layerscape: update kernel patches
[openwrt/openwrt.git] / target / linux / layerscape / patches-4.9 / 701-sdk_dpaa-support-layerscape.patch
1 From 3cd36deb674720ab34eabb9783648ed743e52121 Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Mon, 25 Sep 2017 11:58:03 +0800
4 Subject: [PATCH] sdk_dpaa: support layerscape
5
6 This is a 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: Yangbo Lu <yangbo.lu@nxp.com>
13 ---
14 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 173 +
15 drivers/net/ethernet/freescale/sdk_dpaa/Makefile | 46 +
16 .../net/ethernet/freescale/sdk_dpaa/dpaa_1588.c | 580 ++
17 .../net/ethernet/freescale/sdk_dpaa/dpaa_1588.h | 138 +
18 .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c | 180 +
19 .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h | 43 +
20 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 1213 ++++
21 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 687 ++
22 .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.c | 205 +
23 .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.h | 49 +
24 .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 1992 +++++
25 .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 237 +
26 .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 1820 +++++
27 .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 225 +
28 .../ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c | 381 +
29 .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 1168 +++
30 .../ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c | 278 +
31 .../ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h | 144 +
32 .../net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 544 ++
33 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c | 291 +
34 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c | 907 +++
35 drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 489 ++
36 drivers/net/ethernet/freescale/sdk_dpaa/mac.h | 135 +
37 .../net/ethernet/freescale/sdk_dpaa/offline_port.c | 848 +++
38 .../net/ethernet/freescale/sdk_dpaa/offline_port.h | 59 +
39 drivers/net/ethernet/freescale/sdk_fman/Kconfig | 153 +
40 drivers/net/ethernet/freescale/sdk_fman/Makefile | 11 +
41 .../freescale/sdk_fman/Peripherals/FM/HC/Makefile | 15 +
42 .../freescale/sdk_fman/Peripherals/FM/HC/hc.c | 1232 ++++
43 .../freescale/sdk_fman/Peripherals/FM/MAC/Makefile | 28 +
44 .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c | 1465 ++++
45 .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h | 228 +
46 .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c | 97 +
47 .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h | 42 +
48 .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c | 674 ++
49 .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h | 226 +
50 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.c | 119 +
51 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.h | 43 +
52 .../sdk_fman/Peripherals/FM/MAC/fman_dtsec.c | 845 +++
53 .../Peripherals/FM/MAC/fman_dtsec_mii_acc.c | 163 +
54 .../sdk_fman/Peripherals/FM/MAC/fman_memac.c | 532 ++
55 .../Peripherals/FM/MAC/fman_memac_mii_acc.c | 213 +
56 .../sdk_fman/Peripherals/FM/MAC/fman_tgec.c | 367 +
57 .../freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 1153 +++
58 .../freescale/sdk_fman/Peripherals/FM/MAC/memac.h | 110 +
59 .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c | 78 +
60 .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h | 73 +
61 .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.c | 1017 +++
62 .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.h | 151 +
63 .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c | 139 +
64 .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h | 80 +
65 .../sdk_fman/Peripherals/FM/MACSEC/Makefile | 15 +
66 .../sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c | 237 +
67 .../sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h | 203 +
68 .../Peripherals/FM/MACSEC/fm_macsec_guest.c | 59 +
69 .../Peripherals/FM/MACSEC/fm_macsec_master.c | 1031 +++
70 .../Peripherals/FM/MACSEC/fm_macsec_master.h | 479 ++
71 .../Peripherals/FM/MACSEC/fm_macsec_secy.c | 883 +++
72 .../Peripherals/FM/MACSEC/fm_macsec_secy.h | 144 +
73 .../freescale/sdk_fman/Peripherals/FM/Makefile | 23 +
74 .../freescale/sdk_fman/Peripherals/FM/Pcd/Makefile | 26 +
75 .../freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h | 360 +
76 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c | 7582 ++++++++++++++++++++
77 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h | 399 +
78 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c | 3242 +++++++++
79 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h | 206 +
80 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.c | 5571 ++++++++++++++
81 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.h | 555 ++
82 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c | 2095 ++++++
83 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h | 543 ++
84 .../sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h | 280 +
85 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.c | 1847 +++++
86 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h | 165 +
87 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c | 423 ++
88 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h | 316 +
89 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.c | 984 +++
90 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.h | 101 +
91 .../sdk_fman/Peripherals/FM/Pcd/fman_kg.c | 888 +++
92 .../sdk_fman/Peripherals/FM/Pcd/fman_prs.c | 129 +
93 .../sdk_fman/Peripherals/FM/Port/Makefile | 15 +
94 .../sdk_fman/Peripherals/FM/Port/fm_port.c | 6436 +++++++++++++++++
95 .../sdk_fman/Peripherals/FM/Port/fm_port.h | 999 +++
96 .../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h | 494 ++
97 .../sdk_fman/Peripherals/FM/Port/fm_port_im.c | 753 ++
98 .../sdk_fman/Peripherals/FM/Port/fman_port.c | 1568 ++++
99 .../freescale/sdk_fman/Peripherals/FM/Rtc/Makefile | 15 +
100 .../freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c | 692 ++
101 .../freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h | 96 +
102 .../sdk_fman/Peripherals/FM/Rtc/fman_rtc.c | 334 +
103 .../freescale/sdk_fman/Peripherals/FM/SP/Makefile | 15 +
104 .../freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c | 757 ++
105 .../freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h | 85 +
106 .../freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c | 197 +
107 .../freescale/sdk_fman/Peripherals/FM/fm.c | 5216 ++++++++++++++
108 .../freescale/sdk_fman/Peripherals/FM/fm.h | 648 ++
109 .../freescale/sdk_fman/Peripherals/FM/fm_ipc.h | 465 ++
110 .../freescale/sdk_fman/Peripherals/FM/fm_muram.c | 174 +
111 .../freescale/sdk_fman/Peripherals/FM/fman.c | 1398 ++++
112 .../sdk_fman/Peripherals/FM/inc/fm_common.h | 1214 ++++
113 .../freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h | 93 +
114 .../sdk_fman/Peripherals/FM/inc/fm_sp_common.h | 117 +
115 .../net/ethernet/freescale/sdk_fman/etc/Makefile | 12 +
116 .../net/ethernet/freescale/sdk_fman/etc/error.c | 95 +
117 drivers/net/ethernet/freescale/sdk_fman/etc/list.c | 71 +
118 .../net/ethernet/freescale/sdk_fman/etc/memcpy.c | 620 ++
119 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c | 1155 +++
120 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h | 105 +
121 .../net/ethernet/freescale/sdk_fman/etc/sprint.c | 81 +
122 .../ethernet/freescale/sdk_fman/fmanv3h_dflags.h | 57 +
123 .../ethernet/freescale/sdk_fman/fmanv3l_dflags.h | 56 +
124 .../sdk_fman/inc/Peripherals/crc_mac_addr_ext.h | 364 +
125 .../freescale/sdk_fman/inc/Peripherals/dpaa_ext.h | 210 +
126 .../freescale/sdk_fman/inc/Peripherals/fm_ext.h | 1731 +++++
127 .../sdk_fman/inc/Peripherals/fm_mac_ext.h | 887 +++
128 .../sdk_fman/inc/Peripherals/fm_macsec_ext.h | 1271 ++++
129 .../sdk_fman/inc/Peripherals/fm_muram_ext.h | 170 +
130 .../sdk_fman/inc/Peripherals/fm_pcd_ext.h | 3974 ++++++++++
131 .../sdk_fman/inc/Peripherals/fm_port_ext.h | 2608 +++++++
132 .../sdk_fman/inc/Peripherals/fm_rtc_ext.h | 619 ++
133 .../sdk_fman/inc/Peripherals/fm_vsp_ext.h | 411 ++
134 .../sdk_fman/inc/Peripherals/mii_acc_ext.h | 76 +
135 .../net/ethernet/freescale/sdk_fman/inc/core_ext.h | 90 +
136 .../freescale/sdk_fman/inc/cores/arm_ext.h | 55 +
137 .../freescale/sdk_fman/inc/cores/e500v2_ext.h | 476 ++
138 .../freescale/sdk_fman/inc/cores/ppc_ext.h | 141 +
139 .../ethernet/freescale/sdk_fman/inc/ddr_std_ext.h | 77 +
140 .../ethernet/freescale/sdk_fman/inc/debug_ext.h | 233 +
141 .../ethernet/freescale/sdk_fman/inc/endian_ext.h | 447 ++
142 .../net/ethernet/freescale/sdk_fman/inc/enet_ext.h | 205 +
143 .../ethernet/freescale/sdk_fman/inc/error_ext.h | 529 ++
144 .../ethernet/freescale/sdk_fman/inc/etc/list_ext.h | 358 +
145 .../ethernet/freescale/sdk_fman/inc/etc/mem_ext.h | 318 +
146 .../freescale/sdk_fman/inc/etc/memcpy_ext.h | 208 +
147 .../ethernet/freescale/sdk_fman/inc/etc/mm_ext.h | 310 +
148 .../freescale/sdk_fman/inc/etc/sprint_ext.h | 118 +
149 .../sdk_fman/inc/flib/common/arch/ppc_access.h | 37 +
150 .../freescale/sdk_fman/inc/flib/common/general.h | 52 +
151 .../freescale/sdk_fman/inc/flib/fman_common.h | 78 +
152 .../freescale/sdk_fman/inc/flib/fsl_enet.h | 273 +
153 .../freescale/sdk_fman/inc/flib/fsl_fman.h | 825 +++
154 .../freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h | 1096 +++
155 .../sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h | 107 +
156 .../freescale/sdk_fman/inc/flib/fsl_fman_kg.h | 514 ++
157 .../freescale/sdk_fman/inc/flib/fsl_fman_memac.h | 434 ++
158 .../sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h | 78 +
159 .../freescale/sdk_fman/inc/flib/fsl_fman_port.h | 593 ++
160 .../freescale/sdk_fman/inc/flib/fsl_fman_prs.h | 102 +
161 .../freescale/sdk_fman/inc/flib/fsl_fman_rtc.h | 449 ++
162 .../freescale/sdk_fman/inc/flib/fsl_fman_sp.h | 138 +
163 .../freescale/sdk_fman/inc/flib/fsl_fman_tgec.h | 479 ++
164 .../integrations/FMANV3H/dpaa_integration_ext.h | 291 +
165 .../sdk_fman/inc/integrations/FMANV3H/part_ext.h | 71 +
166 .../integrations/FMANV3H/part_integration_ext.h | 304 +
167 .../integrations/FMANV3L/dpaa_integration_ext.h | 293 +
168 .../sdk_fman/inc/integrations/FMANV3L/part_ext.h | 59 +
169 .../integrations/FMANV3L/part_integration_ext.h | 304 +
170 .../inc/integrations/LS1043/dpaa_integration_ext.h | 291 +
171 .../sdk_fman/inc/integrations/LS1043/part_ext.h | 64 +
172 .../inc/integrations/LS1043/part_integration_ext.h | 185 +
173 .../inc/integrations/P1023/dpaa_integration_ext.h | 213 +
174 .../sdk_fman/inc/integrations/P1023/part_ext.h | 82 +
175 .../inc/integrations/P1023/part_integration_ext.h | 635 ++
176 .../P3040_P4080_P5020/dpaa_integration_ext.h | 276 +
177 .../inc/integrations/P3040_P4080_P5020/part_ext.h | 83 +
178 .../P3040_P4080_P5020/part_integration_ext.h | 336 +
179 .../net/ethernet/freescale/sdk_fman/inc/math_ext.h | 100 +
180 .../net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h | 435 ++
181 .../net/ethernet/freescale/sdk_fman/inc/net_ext.h | 430 ++
182 .../net/ethernet/freescale/sdk_fman/inc/std_ext.h | 48 +
183 .../ethernet/freescale/sdk_fman/inc/stdarg_ext.h | 49 +
184 .../ethernet/freescale/sdk_fman/inc/stdlib_ext.h | 162 +
185 .../ethernet/freescale/sdk_fman/inc/string_ext.h | 56 +
186 .../ethernet/freescale/sdk_fman/inc/types_ext.h | 62 +
187 .../ethernet/freescale/sdk_fman/inc/xx_common.h | 56 +
188 .../net/ethernet/freescale/sdk_fman/inc/xx_ext.h | 791 ++
189 .../ethernet/freescale/sdk_fman/ls1043_dflags.h | 56 +
190 .../net/ethernet/freescale/sdk_fman/ncsw_config.mk | 53 +
191 .../net/ethernet/freescale/sdk_fman/p1023_dflags.h | 65 +
192 .../freescale/sdk_fman/p3040_4080_5020_dflags.h | 62 +
193 .../net/ethernet/freescale/sdk_fman/src/Makefile | 11 +
194 .../freescale/sdk_fman/src/inc/system/sys_ext.h | 118 +
195 .../freescale/sdk_fman/src/inc/system/sys_io_ext.h | 46 +
196 .../freescale/sdk_fman/src/inc/types_linux.h | 208 +
197 .../sdk_fman/src/inc/wrapper/fsl_fman_test.h | 84 +
198 .../sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h | 130 +
199 .../sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h | 163 +
200 .../sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h | 921 +++
201 .../ethernet/freescale/sdk_fman/src/inc/xx/xx.h | 50 +
202 .../freescale/sdk_fman/src/system/Makefile | 10 +
203 .../freescale/sdk_fman/src/system/sys_io.c | 171 +
204 .../freescale/sdk_fman/src/wrapper/Makefile | 19 +
205 .../freescale/sdk_fman/src/wrapper/fman_test.c | 1665 +++++
206 .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 2908 ++++++++
207 .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.h | 294 +
208 .../sdk_fman/src/wrapper/lnxwrp_fm_port.c | 1480 ++++
209 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c | 4854 +++++++++++++
210 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c | 1297 ++++
211 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h | 755 ++
212 .../sdk_fman/src/wrapper/lnxwrp_resources.h | 121 +
213 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.c | 191 +
214 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.h | 144 +
215 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.make | 28 +
216 .../freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c | 60 +
217 .../freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h | 60 +
218 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c | 1855 +++++
219 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h | 136 +
220 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c | 1268 ++++
221 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h | 56 +
222 .../ethernet/freescale/sdk_fman/src/xx/Makefile | 18 +
223 .../freescale/sdk_fman/src/xx/module_strings.c | 46 +
224 .../freescale/sdk_fman/src/xx/xx_arm_linux.c | 905 +++
225 .../ethernet/freescale/sdk_fman/src/xx/xx_linux.c | 918 +++
226 drivers/staging/fsl_qbman/Kconfig | 228 +
227 drivers/staging/fsl_qbman/Makefile | 28 +
228 drivers/staging/fsl_qbman/bman_config.c | 720 ++
229 drivers/staging/fsl_qbman/bman_debugfs.c | 119 +
230 drivers/staging/fsl_qbman/bman_driver.c | 575 ++
231 drivers/staging/fsl_qbman/bman_high.c | 1145 +++
232 drivers/staging/fsl_qbman/bman_low.h | 565 ++
233 drivers/staging/fsl_qbman/bman_private.h | 166 +
234 drivers/staging/fsl_qbman/bman_test.c | 56 +
235 drivers/staging/fsl_qbman/bman_test.h | 44 +
236 drivers/staging/fsl_qbman/bman_test_high.c | 183 +
237 drivers/staging/fsl_qbman/bman_test_thresh.c | 196 +
238 drivers/staging/fsl_qbman/dpa_alloc.c | 706 ++
239 drivers/staging/fsl_qbman/dpa_sys.h | 259 +
240 drivers/staging/fsl_qbman/dpa_sys_arm.h | 95 +
241 drivers/staging/fsl_qbman/dpa_sys_arm64.h | 102 +
242 drivers/staging/fsl_qbman/dpa_sys_ppc32.h | 70 +
243 drivers/staging/fsl_qbman/dpa_sys_ppc64.h | 79 +
244 drivers/staging/fsl_qbman/fsl_usdpaa.c | 1983 +++++
245 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c | 289 +
246 drivers/staging/fsl_qbman/qbman_driver.c | 88 +
247 drivers/staging/fsl_qbman/qman_config.c | 1224 ++++
248 drivers/staging/fsl_qbman/qman_debugfs.c | 1594 ++++
249 drivers/staging/fsl_qbman/qman_driver.c | 977 +++
250 drivers/staging/fsl_qbman/qman_high.c | 5669 +++++++++++++++
251 drivers/staging/fsl_qbman/qman_low.h | 1427 ++++
252 drivers/staging/fsl_qbman/qman_private.h | 398 +
253 drivers/staging/fsl_qbman/qman_test.c | 57 +
254 drivers/staging/fsl_qbman/qman_test.h | 45 +
255 drivers/staging/fsl_qbman/qman_test_high.c | 216 +
256 drivers/staging/fsl_qbman/qman_test_hotpotato.c | 502 ++
257 drivers/staging/fsl_qbman/qman_utility.c | 129 +
258 include/linux/fsl_bman.h | 532 ++
259 include/linux/fsl_qman.h | 3888 ++++++++++
260 include/linux/fsl_usdpaa.h | 372 +
261 include/uapi/linux/fmd/Kbuild | 5 +
262 include/uapi/linux/fmd/Peripherals/Kbuild | 4 +
263 include/uapi/linux/fmd/Peripherals/fm_ioctls.h | 628 ++
264 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h | 3084 ++++++++
265 .../uapi/linux/fmd/Peripherals/fm_port_ioctls.h | 973 +++
266 .../uapi/linux/fmd/Peripherals/fm_test_ioctls.h | 208 +
267 include/uapi/linux/fmd/integrations/Kbuild | 1 +
268 .../linux/fmd/integrations/integration_ioctls.h | 56 +
269 include/uapi/linux/fmd/ioctls.h | 96 +
270 include/uapi/linux/fmd/net_ioctls.h | 430 ++
271 257 files changed, 153159 insertions(+)
272 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
273 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Makefile
274 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
275 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
276 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
277 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
278 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
279 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
280 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
281 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
282 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
283 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
284 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
285 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
286 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
287 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
288 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
289 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
290 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
291 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
292 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
293 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.c
294 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.h
295 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
296 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
297 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Kconfig
298 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Makefile
299 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
300 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
301 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
302 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
303 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
304 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
305 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
306 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
307 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
308 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
309 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
310 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
311 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
312 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
313 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
314 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
315 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
316 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
317 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
318 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
319 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
320 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
321 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
322 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
323 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
324 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
325 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
326 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
327 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
328 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
329 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
330 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
331 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
332 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
333 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
334 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
335 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
336 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
337 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
338 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
339 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
340 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
341 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
342 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
343 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
344 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
345 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
346 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
347 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
348 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
349 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
350 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
351 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
352 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
353 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
354 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
355 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
356 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
357 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
358 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
359 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
360 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
361 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
362 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
363 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
364 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
365 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
366 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
367 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
368 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
369 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
370 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
371 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
372 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
373 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
374 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/error.c
375 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/list.c
376 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
377 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
378 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
379 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
380 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
381 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
382 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
383 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
384 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
385 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
386 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
387 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
388 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
389 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
390 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
391 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
392 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
393 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
394 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
395 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
396 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
397 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
398 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
399 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
400 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
401 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
402 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
403 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
404 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
405 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
406 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
407 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
408 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
409 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
410 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
411 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
412 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
413 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
414 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
415 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
416 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
417 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
418 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
419 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
420 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
421 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
422 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
423 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
424 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
425 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
426 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
427 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
428 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
429 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
430 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
431 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
432 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
433 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
434 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
435 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
436 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
437 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
438 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
439 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
440 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
441 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
442 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
443 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
444 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
445 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
446 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
447 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
448 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
449 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
450 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
451 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/Makefile
452 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
453 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
454 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
455 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
456 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
457 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
458 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
459 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
460 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
461 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
462 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
463 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
464 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
465 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
466 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
467 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
468 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
469 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
470 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
471 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
472 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
473 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
474 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
475 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
476 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
477 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
478 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
479 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
480 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
481 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
482 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
483 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
484 create mode 100644 drivers/staging/fsl_qbman/Kconfig
485 create mode 100644 drivers/staging/fsl_qbman/Makefile
486 create mode 100644 drivers/staging/fsl_qbman/bman_config.c
487 create mode 100644 drivers/staging/fsl_qbman/bman_debugfs.c
488 create mode 100644 drivers/staging/fsl_qbman/bman_driver.c
489 create mode 100644 drivers/staging/fsl_qbman/bman_high.c
490 create mode 100644 drivers/staging/fsl_qbman/bman_low.h
491 create mode 100644 drivers/staging/fsl_qbman/bman_private.h
492 create mode 100644 drivers/staging/fsl_qbman/bman_test.c
493 create mode 100644 drivers/staging/fsl_qbman/bman_test.h
494 create mode 100644 drivers/staging/fsl_qbman/bman_test_high.c
495 create mode 100644 drivers/staging/fsl_qbman/bman_test_thresh.c
496 create mode 100644 drivers/staging/fsl_qbman/dpa_alloc.c
497 create mode 100644 drivers/staging/fsl_qbman/dpa_sys.h
498 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm.h
499 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm64.h
500 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc32.h
501 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc64.h
502 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa.c
503 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
504 create mode 100644 drivers/staging/fsl_qbman/qbman_driver.c
505 create mode 100644 drivers/staging/fsl_qbman/qman_config.c
506 create mode 100644 drivers/staging/fsl_qbman/qman_debugfs.c
507 create mode 100644 drivers/staging/fsl_qbman/qman_driver.c
508 create mode 100644 drivers/staging/fsl_qbman/qman_high.c
509 create mode 100644 drivers/staging/fsl_qbman/qman_low.h
510 create mode 100644 drivers/staging/fsl_qbman/qman_private.h
511 create mode 100644 drivers/staging/fsl_qbman/qman_test.c
512 create mode 100644 drivers/staging/fsl_qbman/qman_test.h
513 create mode 100644 drivers/staging/fsl_qbman/qman_test_high.c
514 create mode 100644 drivers/staging/fsl_qbman/qman_test_hotpotato.c
515 create mode 100644 drivers/staging/fsl_qbman/qman_utility.c
516 create mode 100644 include/linux/fsl_bman.h
517 create mode 100644 include/linux/fsl_qman.h
518 create mode 100644 include/linux/fsl_usdpaa.h
519 create mode 100644 include/uapi/linux/fmd/Kbuild
520 create mode 100644 include/uapi/linux/fmd/Peripherals/Kbuild
521 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_ioctls.h
522 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
523 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
524 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
525 create mode 100644 include/uapi/linux/fmd/integrations/Kbuild
526 create mode 100644 include/uapi/linux/fmd/integrations/integration_ioctls.h
527 create mode 100644 include/uapi/linux/fmd/ioctls.h
528 create mode 100644 include/uapi/linux/fmd/net_ioctls.h
529
530 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
531 new file mode 100644
532 index 00000000..92118b76
533 --- /dev/null
534 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
535 @@ -0,0 +1,173 @@
536 +menuconfig FSL_SDK_DPAA_ETH
537 + tristate "DPAA Ethernet"
538 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && FSL_SDK_FMAN && !FSL_DPAA_ETH
539 + select PHYLIB
540 + help
541 + Data Path Acceleration Architecture Ethernet driver,
542 + supporting the Freescale QorIQ chips.
543 + Depends on Freescale Buffer Manager and Queue Manager
544 + driver and Frame Manager Driver.
545 +
546 +if FSL_SDK_DPAA_ETH
547 +
548 +config FSL_DPAA_HOOKS
549 + bool "DPAA Ethernet driver hooks"
550 +
551 +config FSL_DPAA_CEETM
552 + bool "DPAA CEETM QoS"
553 + depends on NET_SCHED
554 + default n
555 + help
556 + Enable QoS offloading support through the CEETM hardware block.
557 +
558 +config FSL_DPAA_OFFLINE_PORTS
559 + bool "Offline Ports support"
560 + depends on FSL_SDK_DPAA_ETH
561 + default y
562 + help
563 + The Offline Parsing / Host Command ports (short: OH ports, of Offline ports) provide
564 + most of the functionality of the regular, online ports, except they receive their
565 + frames from a core or an accelerator on the SoC, via QMan frame queues,
566 + rather than directly from the network.
567 + Offline ports are configured via PCD (Parse-Classify-Distribute) schemes, just like
568 + any online FMan port. They deliver the processed frames to frame queues, according
569 + to the applied PCD configurations.
570 +
571 + Choosing this feature will not impact the functionality and/or performance of the system,
572 + so it is safe to have it.
573 +
574 +config FSL_DPAA_ADVANCED_DRIVERS
575 + bool "Advanced DPAA Ethernet drivers"
576 + depends on FSL_SDK_DPAA_ETH
577 + default y
578 + help
579 + Besides the standard DPAA Ethernet driver the DPAA Proxy initialization driver
580 + is needed to support advanced scenarios. Select this to also build the advanced
581 + drivers.
582 +
583 +config FSL_DPAA_ETH_JUMBO_FRAME
584 + bool "Optimize for jumbo frames"
585 + default n
586 + help
587 + Optimize the DPAA Ethernet driver throughput for large frames
588 + termination traffic (e.g. 4K and above).
589 + NOTE: This option can only be used if FSL_FM_MAX_FRAME_SIZE
590 + is set to 9600 bytes.
591 + Using this option in combination with small frames increases
592 + significantly the driver's memory footprint and may even deplete
593 + the system memory. Also, the skb truesize is altered and messages
594 + from the stack that warn against this are bypassed.
595 + This option is not available on LS1043.
596 +
597 +config FSL_DPAA_TS
598 + bool "Linux compliant timestamping"
599 + depends on FSL_SDK_DPAA_ETH
600 + default n
601 + help
602 + Enable Linux API compliant timestamping support.
603 +
604 +config FSL_DPAA_1588
605 + bool "IEEE 1588-compliant timestamping"
606 + depends on FSL_SDK_DPAA_ETH
607 + select FSL_DPAA_TS
608 + default n
609 + help
610 + Enable IEEE1588 support code.
611 +
612 +config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
613 + bool "Use driver's Tx queue selection mechanism"
614 + default y
615 + depends on FSL_SDK_DPAA_ETH
616 + help
617 + The DPAA-Ethernet driver defines a ndo_select_queue() callback for optimal selection
618 + of the egress FQ. That will override the XPS support for this netdevice.
619 + If for whatever reason you want to be in control of the egress FQ-to-CPU selection and mapping,
620 + or simply don't want to use the driver's ndo_select_queue() callback, then unselect this
621 + and use the standard XPS support instead.
622 +
623 +config FSL_DPAA_ETH_MAX_BUF_COUNT
624 + int "Maximum nuber of buffers in private bpool"
625 + depends on FSL_SDK_DPAA_ETH
626 + range 64 2048
627 + default "128"
628 + help
629 + The maximum number of buffers to be by default allocated in the DPAA-Ethernet private port's
630 + buffer pool. One needn't normally modify this, as it has probably been tuned for performance
631 + already. This cannot be lower than DPAA_ETH_REFILL_THRESHOLD.
632 +
633 +config FSL_DPAA_ETH_REFILL_THRESHOLD
634 + int "Private bpool refill threshold"
635 + depends on FSL_SDK_DPAA_ETH
636 + range 32 FSL_DPAA_ETH_MAX_BUF_COUNT
637 + default "80"
638 + help
639 + The DPAA-Ethernet driver will start replenishing buffer pools whose count
640 + falls below this threshold. This must be related to DPAA_ETH_MAX_BUF_COUNT. One needn't normally
641 + modify this value unless one has very specific performance reasons.
642 +
643 +config FSL_DPAA_CS_THRESHOLD_1G
644 + hex "Egress congestion threshold on 1G ports"
645 + depends on FSL_SDK_DPAA_ETH
646 + range 0x1000 0x10000000
647 + default "0x06000000"
648 + help
649 + The size in bytes of the egress Congestion State notification threshold on 1G ports.
650 + The 1G dTSECs can quite easily be flooded by cores doing Tx in a tight loop
651 + (e.g. by sending UDP datagrams at "while(1) speed"),
652 + and the larger the frame size, the more acute the problem.
653 + So we have to find a balance between these factors:
654 + - avoiding the device staying congested for a prolonged time (risking
655 + the netdev watchdog to fire - see also the tx_timeout module param);
656 + - affecting performance of protocols such as TCP, which otherwise
657 + behave well under the congestion notification mechanism;
658 + - preventing the Tx cores from tightly-looping (as if the congestion
659 + threshold was too low to be effective);
660 + - running out of memory if the CS threshold is set too high.
661 +
662 +config FSL_DPAA_CS_THRESHOLD_10G
663 + hex "Egress congestion threshold on 10G ports"
664 + depends on FSL_SDK_DPAA_ETH
665 + range 0x1000 0x20000000
666 + default "0x10000000"
667 + help
668 + The size in bytes of the egress Congestion State notification threshold on 10G ports.
669 +
670 +config FSL_DPAA_INGRESS_CS_THRESHOLD
671 + hex "Ingress congestion threshold on FMan ports"
672 + depends on FSL_SDK_DPAA_ETH
673 + default "0x10000000"
674 + help
675 + The size in bytes of the ingress tail-drop threshold on FMan ports.
676 + Traffic piling up above this value will be rejected by QMan and discarded by FMan.
677 +
678 +config FSL_DPAA_ETH_DEBUGFS
679 + bool "DPAA Ethernet debugfs interface"
680 + depends on DEBUG_FS && FSL_SDK_DPAA_ETH
681 + default y
682 + help
683 + This option compiles debugfs code for the DPAA Ethernet driver.
684 +
685 +config FSL_DPAA_ETH_DEBUG
686 + bool "DPAA Ethernet Debug Support"
687 + depends on FSL_SDK_DPAA_ETH
688 + default n
689 + help
690 + This option compiles debug code for the DPAA Ethernet driver.
691 +
692 +config FSL_DPAA_DBG_LOOP
693 + bool "DPAA Ethernet Debug loopback"
694 + depends on FSL_DPAA_ETH_DEBUGFS && FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
695 + default n
696 + help
697 + This option allows to divert all received traffic on a certain interface A towards a
698 + selected interface B. This option is used to benchmark the HW + Ethernet driver in
699 + isolation from the Linux networking stack. The loops are controlled by debugfs entries,
700 + one for each interface. By default all loops are disabled (target value is -1). I.e. to
701 + change the loop setting for interface 4 and divert all received traffic to interface 5
702 + write Tx interface number in the receive interface debugfs file:
703 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
704 + 4->-1
705 + # echo 5 > /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
706 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
707 + 4->5
708 +endif # FSL_SDK_DPAA_ETH
709 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/Makefile b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile
710 new file mode 100644
711 index 00000000..a0f4b190
712 --- /dev/null
713 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile
714 @@ -0,0 +1,46 @@
715 +#
716 +# Makefile for the Freescale Ethernet controllers
717 +#
718 +ccflags-y += -DVERSION=\"\"
719 +#
720 +# Include netcomm SW specific definitions
721 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
722 +
723 +ccflags-y += -I$(NET_DPA)
724 +
725 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_mac.o fsl_dpa.o
726 +obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o
727 +
728 +fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
729 +ifeq ($(CONFIG_FSL_DPAA_DBG_LOOP),y)
730 +fsl_dpa-objs += dpaa_debugfs.o
731 +endif
732 +ifeq ($(CONFIG_FSL_DPAA_1588),y)
733 +fsl_dpa-objs += dpaa_1588.o
734 +endif
735 +ifeq ($(CONFIG_FSL_DPAA_CEETM),y)
736 +ccflags-y += -Idrivers/net/ethernet/freescale/sdk_fman/src/wrapper
737 +fsl_dpa-objs += dpaa_eth_ceetm.o
738 +endif
739 +
740 +fsl_mac-objs += mac.o mac-api.o
741 +
742 +# Advanced drivers
743 +ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y)
744 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_advanced.o
745 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_proxy.o
746 +
747 +fsl_advanced-objs += dpaa_eth_base.o
748 +# suport for multiple drivers per kernel module comes in kernel 3.14
749 +# so we are forced to generate several modules for the advanced drivers
750 +fsl_proxy-objs += dpaa_eth_proxy.o
751 +
752 +ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y)
753 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_oh.o
754 +
755 +fsl_oh-objs += offline_port.o
756 +endif
757 +endif
758 +
759 +# Needed by the tracing framework
760 +CFLAGS_dpaa_eth.o := -I$(src)
761 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
762 new file mode 100644
763 index 00000000..3bf8cbca
764 --- /dev/null
765 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
766 @@ -0,0 +1,580 @@
767 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
768 + * Copyright (C) 2009 IXXAT Automation, GmbH
769 + *
770 + * DPAA Ethernet Driver -- IEEE 1588 interface functionality
771 + *
772 + * This program is free software; you can redistribute it and/or modify
773 + * it under the terms of the GNU General Public License as published by
774 + * the Free Software Foundation; either version 2 of the License, or
775 + * (at your option) any later version.
776 + *
777 + * This program is distributed in the hope that it will be useful,
778 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
779 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
780 + * GNU General Public License for more details.
781 + *
782 + * You should have received a copy of the GNU General Public License along
783 + * with this program; if not, write to the Free Software Foundation, Inc.,
784 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
785 + *
786 + */
787 +#include <linux/io.h>
788 +#include <linux/device.h>
789 +#include <linux/fs.h>
790 +#include <linux/vmalloc.h>
791 +#include <linux/spinlock.h>
792 +#include <linux/ip.h>
793 +#include <linux/ipv6.h>
794 +#include <linux/udp.h>
795 +#include <asm/div64.h>
796 +#include "dpaa_eth.h"
797 +#include "dpaa_eth_common.h"
798 +#include "dpaa_1588.h"
799 +#include "mac.h"
800 +
801 +static int dpa_ptp_init_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
802 +{
803 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
804 +
805 + circ_buf->buf = vmalloc(sizeof(struct dpa_ptp_data) * size);
806 + if (!circ_buf->buf)
807 + return 1;
808 +
809 + circ_buf->head = 0;
810 + circ_buf->tail = 0;
811 + ptp_buf->size = size;
812 + spin_lock_init(&ptp_buf->ptp_lock);
813 +
814 + return 0;
815 +}
816 +
817 +static void dpa_ptp_reset_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
818 +{
819 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
820 +
821 + circ_buf->head = 0;
822 + circ_buf->tail = 0;
823 + ptp_buf->size = size;
824 +}
825 +
826 +static int dpa_ptp_insert(struct dpa_ptp_circ_buf *ptp_buf,
827 + struct dpa_ptp_data *data)
828 +{
829 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
830 + int size = ptp_buf->size;
831 + struct dpa_ptp_data *tmp;
832 + unsigned long flags;
833 + int head, tail;
834 +
835 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
836 +
837 + head = circ_buf->head;
838 + tail = circ_buf->tail;
839 +
840 + if (CIRC_SPACE(head, tail, size) <= 0)
841 + circ_buf->tail = (tail + 1) & (size - 1);
842 +
843 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + head;
844 + memcpy(tmp, data, sizeof(struct dpa_ptp_data));
845 +
846 + circ_buf->head = (head + 1) & (size - 1);
847 +
848 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
849 +
850 + return 0;
851 +}
852 +
853 +static int dpa_ptp_is_ident_match(struct dpa_ptp_ident *dst,
854 + struct dpa_ptp_ident *src)
855 +{
856 + int ret;
857 +
858 + if ((dst->version != src->version) || (dst->msg_type != src->msg_type))
859 + return 0;
860 +
861 + if ((dst->netw_prot == src->netw_prot)
862 + || src->netw_prot == DPA_PTP_PROT_DONTCARE) {
863 + if (dst->seq_id != src->seq_id)
864 + return 0;
865 +
866 + ret = memcmp(dst->snd_port_id, src->snd_port_id,
867 + DPA_PTP_SOURCE_PORT_LENGTH);
868 + if (ret)
869 + return 0;
870 + else
871 + return 1;
872 + }
873 +
874 + return 0;
875 +}
876 +
877 +static int dpa_ptp_find_and_remove(struct dpa_ptp_circ_buf *ptp_buf,
878 + struct dpa_ptp_ident *ident,
879 + struct dpa_ptp_time *ts)
880 +{
881 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
882 + int size = ptp_buf->size;
883 + int head, tail, idx;
884 + unsigned long flags;
885 + struct dpa_ptp_data *tmp, *tmp2;
886 + struct dpa_ptp_ident *tmp_ident;
887 +
888 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
889 +
890 + head = circ_buf->head;
891 + tail = idx = circ_buf->tail;
892 +
893 + if (CIRC_CNT(head, tail, size) == 0) {
894 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
895 + return 1;
896 + }
897 +
898 + while (idx != head) {
899 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
900 + tmp_ident = &tmp->ident;
901 + if (dpa_ptp_is_ident_match(tmp_ident, ident))
902 + break;
903 + idx = (idx + 1) & (size - 1);
904 + }
905 +
906 + if (idx == head) {
907 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
908 + return 1;
909 + }
910 +
911 + ts->sec = tmp->ts.sec;
912 + ts->nsec = tmp->ts.nsec;
913 +
914 + if (idx != tail) {
915 + if (CIRC_CNT(idx, tail, size) > TS_ACCUMULATION_THRESHOLD) {
916 + tail = circ_buf->tail =
917 + (idx - TS_ACCUMULATION_THRESHOLD) & (size - 1);
918 + }
919 +
920 + while (CIRC_CNT(idx, tail, size) > 0) {
921 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
922 + idx = (idx - 1) & (size - 1);
923 + tmp2 = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
924 + *tmp = *tmp2;
925 + }
926 + }
927 + circ_buf->tail = (tail + 1) & (size - 1);
928 +
929 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
930 +
931 + return 0;
932 +}
933 +
934 +/* Parse the PTP packets
935 + *
936 + * The PTP header can be found in an IPv4 packet, IPv6 patcket or in
937 + * an IEEE802.3 ethernet frame. This function returns the position of
938 + * the PTP packet or NULL if no PTP found
939 + */
940 +static u8 *dpa_ptp_parse_packet(struct sk_buff *skb, u16 *eth_type)
941 +{
942 + u8 *pos = skb->data + ETH_ALEN + ETH_ALEN;
943 + u8 *ptp_loc = NULL;
944 + u8 msg_type;
945 + u32 access_len = ETH_ALEN + ETH_ALEN + DPA_ETYPE_LEN;
946 + struct iphdr *iph;
947 + struct udphdr *udph;
948 + struct ipv6hdr *ipv6h;
949 +
950 + /* when we can receive S/G frames we need to check the data we want to
951 + * access is in the linear skb buffer
952 + */
953 + if (!pskb_may_pull(skb, access_len))
954 + return NULL;
955 +
956 + *eth_type = *((u16 *)pos);
957 +
958 + /* Check if inner tag is here */
959 + if (*eth_type == ETH_P_8021Q) {
960 + access_len += DPA_VLAN_TAG_LEN;
961 +
962 + if (!pskb_may_pull(skb, access_len))
963 + return NULL;
964 +
965 + pos += DPA_VLAN_TAG_LEN;
966 + *eth_type = *((u16 *)pos);
967 + }
968 +
969 + pos += DPA_ETYPE_LEN;
970 +
971 + switch (*eth_type) {
972 + /* Transport of PTP over Ethernet */
973 + case ETH_P_1588:
974 + ptp_loc = pos;
975 +
976 + if (!pskb_may_pull(skb, access_len + PTP_OFFS_MSG_TYPE + 1))
977 + return NULL;
978 +
979 + msg_type = *((u8 *)(ptp_loc + PTP_OFFS_MSG_TYPE)) & 0xf;
980 + if ((msg_type == PTP_MSGTYPE_SYNC)
981 + || (msg_type == PTP_MSGTYPE_DELREQ)
982 + || (msg_type == PTP_MSGTYPE_PDELREQ)
983 + || (msg_type == PTP_MSGTYPE_PDELRESP))
984 + return ptp_loc;
985 + break;
986 + /* Transport of PTP over IPv4 */
987 + case ETH_P_IP:
988 + iph = (struct iphdr *)pos;
989 + access_len += sizeof(struct iphdr);
990 +
991 + if (!pskb_may_pull(skb, access_len))
992 + return NULL;
993 +
994 + if (ntohs(iph->protocol) != IPPROTO_UDP)
995 + return NULL;
996 +
997 + access_len += iph->ihl * 4 - sizeof(struct iphdr) +
998 + sizeof(struct udphdr);
999 +
1000 + if (!pskb_may_pull(skb, access_len))
1001 + return NULL;
1002 +
1003 + pos += iph->ihl * 4;
1004 + udph = (struct udphdr *)pos;
1005 + if (ntohs(udph->dest) != 319)
1006 + return NULL;
1007 + ptp_loc = pos + sizeof(struct udphdr);
1008 + break;
1009 + /* Transport of PTP over IPv6 */
1010 + case ETH_P_IPV6:
1011 + ipv6h = (struct ipv6hdr *)pos;
1012 +
1013 + access_len += sizeof(struct ipv6hdr) + sizeof(struct udphdr);
1014 +
1015 + if (ntohs(ipv6h->nexthdr) != IPPROTO_UDP)
1016 + return NULL;
1017 +
1018 + pos += sizeof(struct ipv6hdr);
1019 + udph = (struct udphdr *)pos;
1020 + if (ntohs(udph->dest) != 319)
1021 + return NULL;
1022 + ptp_loc = pos + sizeof(struct udphdr);
1023 + break;
1024 + default:
1025 + break;
1026 + }
1027 +
1028 + return ptp_loc;
1029 +}
1030 +
1031 +static int dpa_ptp_store_stamp(const struct dpa_priv_s *priv,
1032 + struct sk_buff *skb, void *data, enum port_type rx_tx,
1033 + struct dpa_ptp_data *ptp_data)
1034 +{
1035 + u64 nsec;
1036 + u32 mod;
1037 + u8 *ptp_loc;
1038 + u16 eth_type;
1039 +
1040 + ptp_loc = dpa_ptp_parse_packet(skb, &eth_type);
1041 + if (!ptp_loc)
1042 + return -EINVAL;
1043 +
1044 + switch (eth_type) {
1045 + case ETH_P_IP:
1046 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV4;
1047 + break;
1048 + case ETH_P_IPV6:
1049 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV6;
1050 + break;
1051 + case ETH_P_1588:
1052 + ptp_data->ident.netw_prot = DPA_PTP_PROT_802_3;
1053 + break;
1054 + default:
1055 + return -EINVAL;
1056 + }
1057 +
1058 + if (!pskb_may_pull(skb, ptp_loc - skb->data + PTP_OFFS_SEQ_ID + 2))
1059 + return -EINVAL;
1060 +
1061 + ptp_data->ident.version = *(ptp_loc + PTP_OFFS_VER_PTP) & 0xf;
1062 + ptp_data->ident.msg_type = *(ptp_loc + PTP_OFFS_MSG_TYPE) & 0xf;
1063 + ptp_data->ident.seq_id = *((u16 *)(ptp_loc + PTP_OFFS_SEQ_ID));
1064 + memcpy(ptp_data->ident.snd_port_id, ptp_loc + PTP_OFFS_SRCPRTID,
1065 + DPA_PTP_SOURCE_PORT_LENGTH);
1066 +
1067 + nsec = dpa_get_timestamp_ns(priv, rx_tx, data);
1068 + mod = do_div(nsec, NANOSEC_PER_SECOND);
1069 + ptp_data->ts.sec = nsec;
1070 + ptp_data->ts.nsec = mod;
1071 +
1072 + return 0;
1073 +}
1074 +
1075 +void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1076 + struct sk_buff *skb, void *data)
1077 +{
1078 + struct dpa_ptp_tsu *tsu = priv->tsu;
1079 + struct dpa_ptp_data ptp_tx_data;
1080 +
1081 + if (dpa_ptp_store_stamp(priv, skb, data, TX, &ptp_tx_data))
1082 + return;
1083 +
1084 + dpa_ptp_insert(&tsu->tx_timestamps, &ptp_tx_data);
1085 +}
1086 +
1087 +void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1088 + struct sk_buff *skb, void *data)
1089 +{
1090 + struct dpa_ptp_tsu *tsu = priv->tsu;
1091 + struct dpa_ptp_data ptp_rx_data;
1092 +
1093 + if (dpa_ptp_store_stamp(priv, skb, data, RX, &ptp_rx_data))
1094 + return;
1095 +
1096 + dpa_ptp_insert(&tsu->rx_timestamps, &ptp_rx_data);
1097 +}
1098 +
1099 +static uint8_t dpa_get_tx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1100 + struct dpa_ptp_ident *ident,
1101 + struct dpa_ptp_time *ts)
1102 +{
1103 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1104 + struct dpa_ptp_time tmp;
1105 + int flag;
1106 +
1107 + flag = dpa_ptp_find_and_remove(&tsu->tx_timestamps, ident, &tmp);
1108 + if (!flag) {
1109 + ts->sec = tmp.sec;
1110 + ts->nsec = tmp.nsec;
1111 + return 0;
1112 + }
1113 +
1114 + return -1;
1115 +}
1116 +
1117 +static uint8_t dpa_get_rx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1118 + struct dpa_ptp_ident *ident,
1119 + struct dpa_ptp_time *ts)
1120 +{
1121 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1122 + struct dpa_ptp_time tmp;
1123 + int flag;
1124 +
1125 + flag = dpa_ptp_find_and_remove(&tsu->rx_timestamps, ident, &tmp);
1126 + if (!flag) {
1127 + ts->sec = tmp.sec;
1128 + ts->nsec = tmp.nsec;
1129 + return 0;
1130 + }
1131 +
1132 + return -1;
1133 +}
1134 +
1135 +static void dpa_set_fiper_alarm(struct dpa_ptp_tsu *tsu,
1136 + struct dpa_ptp_time *cnt_time)
1137 +{
1138 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1139 + u64 tmp, fiper;
1140 +
1141 + if (mac_dev->fm_rtc_disable)
1142 + mac_dev->fm_rtc_disable(get_fm_handle(tsu->dpa_priv->net_dev));
1143 +
1144 + /* TMR_FIPER1 will pulse every second after ALARM1 expired */
1145 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1146 + fiper = NANOSEC_PER_SECOND - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
1147 + if (mac_dev->fm_rtc_set_alarm)
1148 + mac_dev->fm_rtc_set_alarm(get_fm_handle(tsu->dpa_priv->net_dev),
1149 + 0, tmp);
1150 + if (mac_dev->fm_rtc_set_fiper)
1151 + mac_dev->fm_rtc_set_fiper(get_fm_handle(tsu->dpa_priv->net_dev),
1152 + 0, fiper);
1153 +
1154 + if (mac_dev->fm_rtc_enable)
1155 + mac_dev->fm_rtc_enable(get_fm_handle(tsu->dpa_priv->net_dev));
1156 +}
1157 +
1158 +static void dpa_get_curr_cnt(struct dpa_ptp_tsu *tsu,
1159 + struct dpa_ptp_time *curr_time)
1160 +{
1161 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1162 + u64 tmp;
1163 + u32 mod;
1164 +
1165 + if (mac_dev->fm_rtc_get_cnt)
1166 + mac_dev->fm_rtc_get_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1167 + &tmp);
1168 +
1169 + mod = do_div(tmp, NANOSEC_PER_SECOND);
1170 + curr_time->sec = (u32)tmp;
1171 + curr_time->nsec = mod;
1172 +}
1173 +
1174 +static void dpa_set_1588cnt(struct dpa_ptp_tsu *tsu,
1175 + struct dpa_ptp_time *cnt_time)
1176 +{
1177 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1178 + u64 tmp;
1179 +
1180 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1181 +
1182 + if (mac_dev->fm_rtc_set_cnt)
1183 + mac_dev->fm_rtc_set_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1184 + tmp);
1185 +
1186 + /* Restart fiper two seconds later */
1187 + cnt_time->sec += 2;
1188 + cnt_time->nsec = 0;
1189 + dpa_set_fiper_alarm(tsu, cnt_time);
1190 +}
1191 +
1192 +static void dpa_get_drift(struct dpa_ptp_tsu *tsu, u32 *addend)
1193 +{
1194 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1195 + u32 drift;
1196 +
1197 + if (mac_dev->fm_rtc_get_drift)
1198 + mac_dev->fm_rtc_get_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1199 + &drift);
1200 +
1201 + *addend = drift;
1202 +}
1203 +
1204 +static void dpa_set_drift(struct dpa_ptp_tsu *tsu, u32 addend)
1205 +{
1206 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1207 +
1208 + if (mac_dev->fm_rtc_set_drift)
1209 + mac_dev->fm_rtc_set_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1210 + addend);
1211 +}
1212 +
1213 +static void dpa_flush_timestamp(struct dpa_ptp_tsu *tsu)
1214 +{
1215 + dpa_ptp_reset_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1216 + dpa_ptp_reset_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1217 +}
1218 +
1219 +int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd)
1220 +{
1221 + struct dpa_priv_s *priv = netdev_priv(dev);
1222 + struct dpa_ptp_tsu *tsu = priv->tsu;
1223 + struct mac_device *mac_dev = priv->mac_dev;
1224 + struct dpa_ptp_data ptp_data;
1225 + struct dpa_ptp_data *ptp_data_user;
1226 + struct dpa_ptp_time act_time;
1227 + u32 addend;
1228 + int retval = 0;
1229 +
1230 + if (!tsu || !tsu->valid)
1231 + return -ENODEV;
1232 +
1233 + switch (cmd) {
1234 + case PTP_ENBL_TXTS_IOCTL:
1235 + tsu->hwts_tx_en_ioctl = 1;
1236 + if (mac_dev->fm_rtc_enable)
1237 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
1238 + if (mac_dev->ptp_enable)
1239 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
1240 + break;
1241 + case PTP_DSBL_TXTS_IOCTL:
1242 + tsu->hwts_tx_en_ioctl = 0;
1243 + if (mac_dev->fm_rtc_disable)
1244 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
1245 + if (mac_dev->ptp_disable)
1246 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
1247 + break;
1248 + case PTP_ENBL_RXTS_IOCTL:
1249 + tsu->hwts_rx_en_ioctl = 1;
1250 + break;
1251 + case PTP_DSBL_RXTS_IOCTL:
1252 + tsu->hwts_rx_en_ioctl = 0;
1253 + break;
1254 + case PTP_GET_RX_TIMESTAMP:
1255 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1256 + if (copy_from_user(&ptp_data.ident,
1257 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1258 + return -EINVAL;
1259 +
1260 + if (dpa_get_rx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1261 + return -EAGAIN;
1262 +
1263 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1264 + &ptp_data.ts, sizeof(ptp_data.ts)))
1265 + return -EFAULT;
1266 + break;
1267 + case PTP_GET_TX_TIMESTAMP:
1268 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1269 + if (copy_from_user(&ptp_data.ident,
1270 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1271 + return -EINVAL;
1272 +
1273 + if (dpa_get_tx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1274 + return -EAGAIN;
1275 +
1276 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1277 + &ptp_data.ts, sizeof(ptp_data.ts)))
1278 + return -EFAULT;
1279 + break;
1280 + case PTP_GET_TIME:
1281 + dpa_get_curr_cnt(tsu, &act_time);
1282 + if (copy_to_user(ifr->ifr_data, &act_time, sizeof(act_time)))
1283 + return -EFAULT;
1284 + break;
1285 + case PTP_SET_TIME:
1286 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1287 + return -EINVAL;
1288 + dpa_set_1588cnt(tsu, &act_time);
1289 + break;
1290 + case PTP_GET_ADJ:
1291 + dpa_get_drift(tsu, &addend);
1292 + if (copy_to_user(ifr->ifr_data, &addend, sizeof(addend)))
1293 + return -EFAULT;
1294 + break;
1295 + case PTP_SET_ADJ:
1296 + if (copy_from_user(&addend, ifr->ifr_data, sizeof(addend)))
1297 + return -EINVAL;
1298 + dpa_set_drift(tsu, addend);
1299 + break;
1300 + case PTP_SET_FIPER_ALARM:
1301 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1302 + return -EINVAL;
1303 + dpa_set_fiper_alarm(tsu, &act_time);
1304 + break;
1305 + case PTP_CLEANUP_TS:
1306 + dpa_flush_timestamp(tsu);
1307 + break;
1308 + default:
1309 + return -EINVAL;
1310 + }
1311 +
1312 + return retval;
1313 +}
1314 +
1315 +int dpa_ptp_init(struct dpa_priv_s *priv)
1316 +{
1317 + struct dpa_ptp_tsu *tsu;
1318 +
1319 + /* Allocate memory for PTP structure */
1320 + tsu = kzalloc(sizeof(struct dpa_ptp_tsu), GFP_KERNEL);
1321 + if (!tsu)
1322 + return -ENOMEM;
1323 +
1324 + tsu->valid = TRUE;
1325 + tsu->dpa_priv = priv;
1326 +
1327 + dpa_ptp_init_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1328 + dpa_ptp_init_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1329 +
1330 + priv->tsu = tsu;
1331 +
1332 + return 0;
1333 +}
1334 +EXPORT_SYMBOL(dpa_ptp_init);
1335 +
1336 +void dpa_ptp_cleanup(struct dpa_priv_s *priv)
1337 +{
1338 + struct dpa_ptp_tsu *tsu = priv->tsu;
1339 +
1340 + tsu->valid = FALSE;
1341 + vfree(tsu->rx_timestamps.circ_buf.buf);
1342 + vfree(tsu->tx_timestamps.circ_buf.buf);
1343 +
1344 + kfree(tsu);
1345 +}
1346 +EXPORT_SYMBOL(dpa_ptp_cleanup);
1347 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
1348 new file mode 100644
1349 index 00000000..73390168
1350 --- /dev/null
1351 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
1352 @@ -0,0 +1,138 @@
1353 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
1354 + *
1355 + * This program is free software; you can redistribute it and/or modify
1356 + * it under the terms of the GNU General Public License as published by
1357 + * the Free Software Foundation; either version 2 of the License, or
1358 + * (at your option) any later version.
1359 + *
1360 + * This program is distributed in the hope that it will be useful,
1361 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1362 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1363 + * GNU General Public License for more details.
1364 + *
1365 + * You should have received a copy of the GNU General Public License along
1366 + * with this program; if not, write to the Free Software Foundation, Inc.,
1367 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1368 + *
1369 + */
1370 +#ifndef __DPAA_1588_H__
1371 +#define __DPAA_1588_H__
1372 +
1373 +#include <linux/netdevice.h>
1374 +#include <linux/etherdevice.h>
1375 +#include <linux/circ_buf.h>
1376 +#include <linux/fsl_qman.h>
1377 +
1378 +#define DEFAULT_PTP_RX_BUF_SZ 256
1379 +#define DEFAULT_PTP_TX_BUF_SZ 256
1380 +
1381 +/* 1588 private ioctl calls */
1382 +#define PTP_ENBL_TXTS_IOCTL SIOCDEVPRIVATE
1383 +#define PTP_DSBL_TXTS_IOCTL (SIOCDEVPRIVATE + 1)
1384 +#define PTP_ENBL_RXTS_IOCTL (SIOCDEVPRIVATE + 2)
1385 +#define PTP_DSBL_RXTS_IOCTL (SIOCDEVPRIVATE + 3)
1386 +#define PTP_GET_TX_TIMESTAMP (SIOCDEVPRIVATE + 4)
1387 +#define PTP_GET_RX_TIMESTAMP (SIOCDEVPRIVATE + 5)
1388 +#define PTP_SET_TIME (SIOCDEVPRIVATE + 6)
1389 +#define PTP_GET_TIME (SIOCDEVPRIVATE + 7)
1390 +#define PTP_SET_FIPER_ALARM (SIOCDEVPRIVATE + 8)
1391 +#define PTP_SET_ADJ (SIOCDEVPRIVATE + 9)
1392 +#define PTP_GET_ADJ (SIOCDEVPRIVATE + 10)
1393 +#define PTP_CLEANUP_TS (SIOCDEVPRIVATE + 11)
1394 +
1395 +/* PTP V2 message type */
1396 +enum {
1397 + PTP_MSGTYPE_SYNC = 0x0,
1398 + PTP_MSGTYPE_DELREQ = 0x1,
1399 + PTP_MSGTYPE_PDELREQ = 0x2,
1400 + PTP_MSGTYPE_PDELRESP = 0x3,
1401 + PTP_MSGTYPE_FLWUP = 0x8,
1402 + PTP_MSGTYPE_DELRESP = 0x9,
1403 + PTP_MSGTYPE_PDELRES_FLWUP = 0xA,
1404 + PTP_MSGTYPE_ANNOUNCE = 0xB,
1405 + PTP_MSGTYPE_SGNLNG = 0xC,
1406 + PTP_MSGTYPE_MNGMNT = 0xD,
1407 +};
1408 +
1409 +/* Byte offset of data in the PTP V2 headers */
1410 +#define PTP_OFFS_MSG_TYPE 0
1411 +#define PTP_OFFS_VER_PTP 1
1412 +#define PTP_OFFS_MSG_LEN 2
1413 +#define PTP_OFFS_DOM_NMB 4
1414 +#define PTP_OFFS_FLAGS 6
1415 +#define PTP_OFFS_CORFIELD 8
1416 +#define PTP_OFFS_SRCPRTID 20
1417 +#define PTP_OFFS_SEQ_ID 30
1418 +#define PTP_OFFS_CTRL 32
1419 +#define PTP_OFFS_LOGMEAN 33
1420 +
1421 +#define PTP_IP_OFFS 14
1422 +#define PTP_UDP_OFFS 34
1423 +#define PTP_HEADER_OFFS 42
1424 +#define PTP_MSG_TYPE_OFFS (PTP_HEADER_OFFS + PTP_OFFS_MSG_TYPE)
1425 +#define PTP_SPORT_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SRCPRTID)
1426 +#define PTP_SEQ_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SEQ_ID)
1427 +#define PTP_CTRL_OFFS (PTP_HEADER_OFFS + PTP_OFFS_CTRL)
1428 +
1429 +/* 1588-2008 network protocol enumeration values */
1430 +#define DPA_PTP_PROT_IPV4 1
1431 +#define DPA_PTP_PROT_IPV6 2
1432 +#define DPA_PTP_PROT_802_3 3
1433 +#define DPA_PTP_PROT_DONTCARE 0xFFFF
1434 +
1435 +#define DPA_PTP_SOURCE_PORT_LENGTH 10
1436 +#define DPA_PTP_HEADER_SZE 34
1437 +#define DPA_ETYPE_LEN 2
1438 +#define DPA_VLAN_TAG_LEN 4
1439 +#define NANOSEC_PER_SECOND 1000000000
1440 +
1441 +/* The threshold between the current found one and the oldest one */
1442 +#define TS_ACCUMULATION_THRESHOLD 50
1443 +
1444 +/* Struct needed to identify a timestamp */
1445 +struct dpa_ptp_ident {
1446 + u8 version;
1447 + u8 msg_type;
1448 + u16 netw_prot;
1449 + u16 seq_id;
1450 + u8 snd_port_id[DPA_PTP_SOURCE_PORT_LENGTH];
1451 +};
1452 +
1453 +/* Timestamp format in 1588-2008 */
1454 +struct dpa_ptp_time {
1455 + u64 sec; /* just 48 bit used */
1456 + u32 nsec;
1457 +};
1458 +
1459 +/* needed for timestamp data over ioctl */
1460 +struct dpa_ptp_data {
1461 + struct dpa_ptp_ident ident;
1462 + struct dpa_ptp_time ts;
1463 +};
1464 +
1465 +struct dpa_ptp_circ_buf {
1466 + struct circ_buf circ_buf;
1467 + u32 size;
1468 + spinlock_t ptp_lock;
1469 +};
1470 +
1471 +/* PTP TSU control structure */
1472 +struct dpa_ptp_tsu {
1473 + struct dpa_priv_s *dpa_priv;
1474 + bool valid;
1475 + struct dpa_ptp_circ_buf rx_timestamps;
1476 + struct dpa_ptp_circ_buf tx_timestamps;
1477 +
1478 + /* HW timestamping over ioctl enabled flag */
1479 + int hwts_tx_en_ioctl;
1480 + int hwts_rx_en_ioctl;
1481 +};
1482 +
1483 +extern int dpa_ptp_init(struct dpa_priv_s *priv);
1484 +extern void dpa_ptp_cleanup(struct dpa_priv_s *priv);
1485 +extern void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1486 + struct sk_buff *skb, void *data);
1487 +extern void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1488 + struct sk_buff *skb, void *data);
1489 +extern int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd);
1490 +#endif
1491 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
1492 new file mode 100644
1493 index 00000000..25d9f5f1
1494 --- /dev/null
1495 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
1496 @@ -0,0 +1,180 @@
1497 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1498 + *
1499 + * Redistribution and use in source and binary forms, with or without
1500 + * modification, are permitted provided that the following conditions are met:
1501 + * * Redistributions of source code must retain the above copyright
1502 + * notice, this list of conditions and the following disclaimer.
1503 + * * Redistributions in binary form must reproduce the above copyright
1504 + * notice, this list of conditions and the following disclaimer in the
1505 + * documentation and/or other materials provided with the distribution.
1506 + * * Neither the name of Freescale Semiconductor nor the
1507 + * names of its contributors may be used to endorse or promote products
1508 + * derived from this software without specific prior written permission.
1509 + *
1510 + *
1511 + * ALTERNATIVELY, this software may be distributed under the terms of the
1512 + * GNU General Public License ("GPL") as published by the Free Software
1513 + * Foundation, either version 2 of that License or (at your option) any
1514 + * later version.
1515 + *
1516 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1517 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1518 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1519 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1520 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1521 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1522 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1523 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1524 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1525 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1526 + */
1527 +
1528 +#include <linux/module.h>
1529 +#include <linux/fsl_qman.h> /* struct qm_mcr_querycgr */
1530 +#include <linux/debugfs.h>
1531 +#include "dpaa_debugfs.h"
1532 +#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */
1533 +
1534 +#define DPA_DEBUGFS_DESCRIPTION "FSL DPAA Ethernet debugfs entries"
1535 +#define DPA_ETH_DEBUGFS_ROOT "fsl_dpa"
1536 +
1537 +static struct dentry *dpa_debugfs_root;
1538 +
1539 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file);
1540 +static ssize_t dpa_loop_write(struct file *f,
1541 + const char __user *buf, size_t count, loff_t *off);
1542 +
1543 +static const struct file_operations dpa_debugfs_lp_fops = {
1544 + .open = dpa_debugfs_loop_open,
1545 + .write = dpa_loop_write,
1546 + .read = seq_read,
1547 + .llseek = seq_lseek,
1548 + .release = single_release,
1549 +};
1550 +
1551 +static int dpa_debugfs_loop_show(struct seq_file *file, void *offset)
1552 +{
1553 + struct dpa_priv_s *priv;
1554 +
1555 + BUG_ON(offset == NULL);
1556 +
1557 + priv = netdev_priv((struct net_device *)file->private);
1558 + seq_printf(file, "%d->%d\n", priv->loop_id, priv->loop_to);
1559 +
1560 + return 0;
1561 +}
1562 +
1563 +static int user_input_convert(const char __user *user_buf, size_t count,
1564 + long *val)
1565 +{
1566 + char buf[12];
1567 +
1568 + if (count > sizeof(buf) - 1)
1569 + return -EINVAL;
1570 + if (copy_from_user(buf, user_buf, count))
1571 + return -EFAULT;
1572 + buf[count] = '\0';
1573 + if (kstrtol(buf, 0, val))
1574 + return -EINVAL;
1575 + return 0;
1576 +}
1577 +
1578 +static ssize_t dpa_loop_write(struct file *f,
1579 + const char __user *buf, size_t count, loff_t *off)
1580 +{
1581 + struct dpa_priv_s *priv;
1582 + struct net_device *netdev;
1583 + struct seq_file *sf;
1584 + int ret;
1585 + long val;
1586 +
1587 + ret = user_input_convert(buf, count, &val);
1588 + if (ret)
1589 + return ret;
1590 +
1591 + sf = (struct seq_file *)f->private_data;
1592 + netdev = (struct net_device *)sf->private;
1593 + priv = netdev_priv(netdev);
1594 +
1595 + priv->loop_to = ((val < 0) || (val > 20)) ? -1 : val;
1596 +
1597 + return count;
1598 +}
1599 +
1600 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file)
1601 +{
1602 + int _errno;
1603 + const struct net_device *net_dev;
1604 +
1605 + _errno = single_open(file, dpa_debugfs_loop_show, inode->i_private);
1606 + if (unlikely(_errno < 0)) {
1607 + net_dev = (struct net_device *)inode->i_private;
1608 +
1609 + if (netif_msg_drv((struct dpa_priv_s *)netdev_priv(net_dev)))
1610 + netdev_err(net_dev, "single_open() = %d\n",
1611 + _errno);
1612 + }
1613 +
1614 + return _errno;
1615 +}
1616 +
1617 +
1618 +int dpa_netdev_debugfs_create(struct net_device *net_dev)
1619 +{
1620 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1621 + static int cnt;
1622 + char loop_file_name[100];
1623 +
1624 + if (unlikely(dpa_debugfs_root == NULL)) {
1625 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): \t%s\n",
1626 + KBUILD_BASENAME".c", __LINE__, __func__,
1627 + "root debugfs missing, possible module ordering issue");
1628 + return -ENOMEM;
1629 + }
1630 +
1631 + sprintf(loop_file_name, "eth%d_loop", ++cnt);
1632 + priv->debugfs_loop_file = debugfs_create_file(loop_file_name,
1633 + S_IRUGO,
1634 + dpa_debugfs_root,
1635 + net_dev,
1636 + &dpa_debugfs_lp_fops);
1637 + if (unlikely(priv->debugfs_loop_file == NULL)) {
1638 + netdev_err(net_dev, "debugfs_create_file(%s/%s)",
1639 + dpa_debugfs_root->d_iname,
1640 + loop_file_name);
1641 +
1642 + return -ENOMEM;
1643 + }
1644 + return 0;
1645 +}
1646 +
1647 +void dpa_netdev_debugfs_remove(struct net_device *net_dev)
1648 +{
1649 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1650 +
1651 + debugfs_remove(priv->debugfs_loop_file);
1652 +}
1653 +
1654 +int __init dpa_debugfs_module_init(void)
1655 +{
1656 + int _errno = 0;
1657 +
1658 + pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION "\n");
1659 +
1660 + dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL);
1661 +
1662 + if (unlikely(dpa_debugfs_root == NULL)) {
1663 + _errno = -ENOMEM;
1664 + pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
1665 + KBUILD_BASENAME".c", __LINE__, __func__);
1666 + pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
1667 + DPA_ETH_DEBUGFS_ROOT, _errno);
1668 + }
1669 +
1670 + return _errno;
1671 +}
1672 +
1673 +void __exit dpa_debugfs_module_exit(void)
1674 +{
1675 + debugfs_remove(dpa_debugfs_root);
1676 +}
1677 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
1678 new file mode 100644
1679 index 00000000..63d35427
1680 --- /dev/null
1681 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
1682 @@ -0,0 +1,43 @@
1683 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1684 + *
1685 + * Redistribution and use in source and binary forms, with or without
1686 + * modification, are permitted provided that the following conditions are met:
1687 + * * Redistributions of source code must retain the above copyright
1688 + * notice, this list of conditions and the following disclaimer.
1689 + * * Redistributions in binary form must reproduce the above copyright
1690 + * notice, this list of conditions and the following disclaimer in the
1691 + * documentation and/or other materials provided with the distribution.
1692 + * * Neither the name of Freescale Semiconductor nor the
1693 + * names of its contributors may be used to endorse or promote products
1694 + * derived from this software without specific prior written permission.
1695 + *
1696 + *
1697 + * ALTERNATIVELY, this software may be distributed under the terms of the
1698 + * GNU General Public License ("GPL") as published by the Free Software
1699 + * Foundation, either version 2 of that License or (at your option) any
1700 + * later version.
1701 + *
1702 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1703 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1704 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1705 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1706 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1707 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1708 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1709 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1710 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1711 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1712 + */
1713 +
1714 +#ifndef DPAA_DEBUGFS_H_
1715 +#define DPAA_DEBUGFS_H_
1716 +
1717 +#include <linux/netdevice.h>
1718 +#include <linux/dcache.h> /* struct dentry needed in dpaa_eth.h */
1719 +
1720 +int dpa_netdev_debugfs_create(struct net_device *net_dev);
1721 +void dpa_netdev_debugfs_remove(struct net_device *net_dev);
1722 +int __init dpa_debugfs_module_init(void);
1723 +void __exit dpa_debugfs_module_exit(void);
1724 +
1725 +#endif /* DPAA_DEBUGFS_H_ */
1726 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
1727 new file mode 100644
1728 index 00000000..7026f916
1729 --- /dev/null
1730 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
1731 @@ -0,0 +1,1213 @@
1732 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1733 + *
1734 + * Redistribution and use in source and binary forms, with or without
1735 + * modification, are permitted provided that the following conditions are met:
1736 + * * Redistributions of source code must retain the above copyright
1737 + * notice, this list of conditions and the following disclaimer.
1738 + * * Redistributions in binary form must reproduce the above copyright
1739 + * notice, this list of conditions and the following disclaimer in the
1740 + * documentation and/or other materials provided with the distribution.
1741 + * * Neither the name of Freescale Semiconductor nor the
1742 + * names of its contributors may be used to endorse or promote products
1743 + * derived from this software without specific prior written permission.
1744 + *
1745 + *
1746 + * ALTERNATIVELY, this software may be distributed under the terms of the
1747 + * GNU General Public License ("GPL") as published by the Free Software
1748 + * Foundation, either version 2 of that License or (at your option) any
1749 + * later version.
1750 + *
1751 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1752 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1753 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1754 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1755 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1756 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1757 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1758 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1759 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1760 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1761 + */
1762 +
1763 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
1764 +#define pr_fmt(fmt) \
1765 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
1766 + KBUILD_BASENAME".c", __LINE__, __func__
1767 +#else
1768 +#define pr_fmt(fmt) \
1769 + KBUILD_MODNAME ": " fmt
1770 +#endif
1771 +
1772 +#include <linux/init.h>
1773 +#include <linux/module.h>
1774 +#include <linux/of_mdio.h>
1775 +#include <linux/of_net.h>
1776 +#include <linux/kthread.h>
1777 +#include <linux/io.h>
1778 +#include <linux/if_arp.h> /* arp_hdr_len() */
1779 +#include <linux/if_vlan.h> /* VLAN_HLEN */
1780 +#include <linux/icmp.h> /* struct icmphdr */
1781 +#include <linux/ip.h> /* struct iphdr */
1782 +#include <linux/ipv6.h> /* struct ipv6hdr */
1783 +#include <linux/udp.h> /* struct udphdr */
1784 +#include <linux/tcp.h> /* struct tcphdr */
1785 +#include <linux/net.h> /* net_ratelimit() */
1786 +#include <linux/if_ether.h> /* ETH_P_IP and ETH_P_IPV6 */
1787 +#include <linux/highmem.h>
1788 +#include <linux/percpu.h>
1789 +#include <linux/dma-mapping.h>
1790 +#include <linux/fsl_bman.h>
1791 +#ifdef CONFIG_SOC_BUS
1792 +#include <linux/sys_soc.h> /* soc_device_match */
1793 +#endif
1794 +
1795 +#include "fsl_fman.h"
1796 +#include "fm_ext.h"
1797 +#include "fm_port_ext.h"
1798 +
1799 +#include "mac.h"
1800 +#include "dpaa_eth.h"
1801 +#include "dpaa_eth_common.h"
1802 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1803 +#include "dpaa_debugfs.h"
1804 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
1805 +
1806 +/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files
1807 + * using trace events only need to #include <trace/events/sched.h>
1808 + */
1809 +#define CREATE_TRACE_POINTS
1810 +#include "dpaa_eth_trace.h"
1811 +
1812 +#define DPA_NAPI_WEIGHT 64
1813 +
1814 +/* Valid checksum indication */
1815 +#define DPA_CSUM_VALID 0xFFFF
1816 +
1817 +#define DPA_DESCRIPTION "FSL DPAA Ethernet driver"
1818 +
1819 +MODULE_LICENSE("Dual BSD/GPL");
1820 +
1821 +MODULE_AUTHOR("Andy Fleming <afleming@freescale.com>");
1822 +
1823 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
1824 +
1825 +static uint8_t debug = -1;
1826 +module_param(debug, byte, S_IRUGO);
1827 +MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
1828 +
1829 +/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
1830 +static uint16_t tx_timeout = 1000;
1831 +module_param(tx_timeout, ushort, S_IRUGO);
1832 +MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
1833 +
1834 +static const char rtx[][3] = {
1835 + [RX] = "RX",
1836 + [TX] = "TX"
1837 +};
1838 +
1839 +#ifndef CONFIG_PPC
1840 +bool dpaa_errata_a010022;
1841 +EXPORT_SYMBOL(dpaa_errata_a010022);
1842 +#endif
1843 +
1844 +/* BM */
1845 +
1846 +#define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8)
1847 +
1848 +static uint8_t dpa_priv_common_bpid;
1849 +
1850 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1851 +struct net_device *dpa_loop_netdevs[20];
1852 +#endif
1853 +
1854 +#ifdef CONFIG_PM
1855 +
1856 +static int dpaa_suspend(struct device *dev)
1857 +{
1858 + struct net_device *net_dev;
1859 + struct dpa_priv_s *priv;
1860 + struct mac_device *mac_dev;
1861 + int err = 0;
1862 +
1863 + net_dev = dev_get_drvdata(dev);
1864 +
1865 + if (net_dev->flags & IFF_UP) {
1866 + priv = netdev_priv(net_dev);
1867 + mac_dev = priv->mac_dev;
1868 +
1869 + if (priv->wol & DPAA_WOL_MAGIC) {
1870 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1871 + priv->mac_dev->get_mac_handle(mac_dev), true);
1872 + if (err) {
1873 + netdev_err(net_dev, "set_wol() = %d\n", err);
1874 + goto set_wol_failed;
1875 + }
1876 + }
1877 +
1878 + err = fm_port_suspend(mac_dev->port_dev[RX]);
1879 + if (err) {
1880 + netdev_err(net_dev, "fm_port_suspend(RX) = %d\n", err);
1881 + goto rx_port_suspend_failed;
1882 + }
1883 +
1884 + err = fm_port_suspend(mac_dev->port_dev[TX]);
1885 + if (err) {
1886 + netdev_err(net_dev, "fm_port_suspend(TX) = %d\n", err);
1887 + goto tx_port_suspend_failed;
1888 + }
1889 + }
1890 +
1891 + return 0;
1892 +
1893 +tx_port_suspend_failed:
1894 + fm_port_resume(mac_dev->port_dev[RX]);
1895 +rx_port_suspend_failed:
1896 + if (priv->wol & DPAA_WOL_MAGIC) {
1897 + priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1898 + priv->mac_dev->get_mac_handle(mac_dev), false);
1899 + }
1900 +set_wol_failed:
1901 + return err;
1902 +}
1903 +
1904 +static int dpaa_resume(struct device *dev)
1905 +{
1906 + struct net_device *net_dev;
1907 + struct dpa_priv_s *priv;
1908 + struct mac_device *mac_dev;
1909 + int err = 0;
1910 +
1911 + net_dev = dev_get_drvdata(dev);
1912 +
1913 + if (net_dev->flags & IFF_UP) {
1914 + priv = netdev_priv(net_dev);
1915 + mac_dev = priv->mac_dev;
1916 +
1917 + err = fm_mac_resume(mac_dev->get_mac_handle(mac_dev));
1918 + if (err) {
1919 + netdev_err(net_dev, "fm_mac_resume = %d\n", err);
1920 + goto resume_failed;
1921 + }
1922 +
1923 + err = fm_port_resume(mac_dev->port_dev[TX]);
1924 + if (err) {
1925 + netdev_err(net_dev, "fm_port_resume(TX) = %d\n", err);
1926 + goto resume_failed;
1927 + }
1928 +
1929 + err = fm_port_resume(mac_dev->port_dev[RX]);
1930 + if (err) {
1931 + netdev_err(net_dev, "fm_port_resume(RX) = %d\n", err);
1932 + goto resume_failed;
1933 + }
1934 +
1935 + if (priv->wol & DPAA_WOL_MAGIC) {
1936 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1937 + priv->mac_dev->get_mac_handle(mac_dev), false);
1938 + if (err) {
1939 + netdev_err(net_dev, "set_wol() = %d\n", err);
1940 + goto resume_failed;
1941 + }
1942 + }
1943 + }
1944 +
1945 + return 0;
1946 +
1947 +resume_failed:
1948 + return err;
1949 +}
1950 +
1951 +static const struct dev_pm_ops dpaa_pm_ops = {
1952 + .suspend = dpaa_suspend,
1953 + .resume = dpaa_resume,
1954 +};
1955 +
1956 +#define DPAA_PM_OPS (&dpaa_pm_ops)
1957 +
1958 +#else /* CONFIG_PM */
1959 +
1960 +#define DPAA_PM_OPS NULL
1961 +
1962 +#endif /* CONFIG_PM */
1963 +
1964 +/* Checks whether the checksum field in Parse Results array is valid
1965 + * (equals 0xFFFF) and increments the .cse counter otherwise
1966 + */
1967 +static inline void
1968 +dpa_csum_validation(const struct dpa_priv_s *priv,
1969 + struct dpa_percpu_priv_s *percpu_priv,
1970 + const struct qm_fd *fd)
1971 +{
1972 + dma_addr_t addr = qm_fd_addr(fd);
1973 + struct dpa_bp *dpa_bp = priv->dpa_bp;
1974 + void *frm = phys_to_virt(addr);
1975 + fm_prs_result_t *parse_result;
1976 +
1977 + if (unlikely(!frm))
1978 + return;
1979 +
1980 + dma_sync_single_for_cpu(dpa_bp->dev, addr, DPA_RX_PRIV_DATA_SIZE +
1981 + DPA_PARSE_RESULTS_SIZE, DMA_BIDIRECTIONAL);
1982 +
1983 + parse_result = (fm_prs_result_t *)(frm + DPA_RX_PRIV_DATA_SIZE);
1984 +
1985 + if (parse_result->cksum != DPA_CSUM_VALID)
1986 + percpu_priv->rx_errors.cse++;
1987 +}
1988 +
1989 +static void _dpa_rx_error(struct net_device *net_dev,
1990 + const struct dpa_priv_s *priv,
1991 + struct dpa_percpu_priv_s *percpu_priv,
1992 + const struct qm_fd *fd,
1993 + u32 fqid)
1994 +{
1995 + /* limit common, possibly innocuous Rx FIFO Overflow errors'
1996 + * interference with zero-loss convergence benchmark results.
1997 + */
1998 + if (likely(fd->status & FM_FD_STAT_ERR_PHYSICAL))
1999 + pr_warn_once("fsl-dpa: non-zero error counters in fman statistics (sysfs)\n");
2000 + else
2001 + if (netif_msg_hw(priv) && net_ratelimit())
2002 + netdev_dbg(net_dev, "Err FD status = 0x%08x\n",
2003 + fd->status & FM_FD_STAT_RX_ERRORS);
2004 +#ifdef CONFIG_FSL_DPAA_HOOKS
2005 + if (dpaa_eth_hooks.rx_error &&
2006 + dpaa_eth_hooks.rx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
2007 + /* it's up to the hook to perform resource cleanup */
2008 + return;
2009 +#endif
2010 + percpu_priv->stats.rx_errors++;
2011 +
2012 + if (fd->status & FM_PORT_FRM_ERR_DMA)
2013 + percpu_priv->rx_errors.dme++;
2014 + if (fd->status & FM_PORT_FRM_ERR_PHYSICAL)
2015 + percpu_priv->rx_errors.fpe++;
2016 + if (fd->status & FM_PORT_FRM_ERR_SIZE)
2017 + percpu_priv->rx_errors.fse++;
2018 + if (fd->status & FM_PORT_FRM_ERR_PRS_HDR_ERR)
2019 + percpu_priv->rx_errors.phe++;
2020 + if (fd->status & FM_FD_STAT_L4CV)
2021 + dpa_csum_validation(priv, percpu_priv, fd);
2022 +
2023 + dpa_fd_release(net_dev, fd);
2024 +}
2025 +
2026 +static void _dpa_tx_error(struct net_device *net_dev,
2027 + const struct dpa_priv_s *priv,
2028 + struct dpa_percpu_priv_s *percpu_priv,
2029 + const struct qm_fd *fd,
2030 + u32 fqid)
2031 +{
2032 + struct sk_buff *skb;
2033 +
2034 + if (netif_msg_hw(priv) && net_ratelimit())
2035 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2036 + fd->status & FM_FD_STAT_TX_ERRORS);
2037 +#ifdef CONFIG_FSL_DPAA_HOOKS
2038 + if (dpaa_eth_hooks.tx_error &&
2039 + dpaa_eth_hooks.tx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
2040 + /* now the hook must ensure proper cleanup */
2041 + return;
2042 +#endif
2043 + percpu_priv->stats.tx_errors++;
2044 +
2045 + /* If we intended the buffers from this frame to go into the bpools
2046 + * when the FMan transmit was done, we need to put it in manually.
2047 + */
2048 + if (fd->bpid != 0xff) {
2049 + dpa_fd_release(net_dev, fd);
2050 + return;
2051 + }
2052 +
2053 + skb = _dpa_cleanup_tx_fd(priv, fd);
2054 + dev_kfree_skb(skb);
2055 +}
2056 +
2057 +/* Helper function to factor out frame validation logic on all Rx paths. Its
2058 + * purpose is to extract from the Parse Results structure information about
2059 + * the integrity of the frame, its checksum, the length of the parsed headers
2060 + * and whether the frame is suitable for GRO.
2061 + *
2062 + * Assumes no parser errors, since any error frame is dropped before this
2063 + * function is called.
2064 + *
2065 + * @skb will have its ip_summed field overwritten;
2066 + * @use_gro will only be written with 0, if the frame is definitely not
2067 + * GRO-able; otherwise, it will be left unchanged;
2068 + * @hdr_size will be written with a safe value, at least the size of the
2069 + * headers' length.
2070 + */
2071 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
2072 + const struct qm_fd *fd,
2073 + struct sk_buff *skb, int *use_gro)
2074 +{
2075 + if (fd->status & FM_FD_STAT_L4CV) {
2076 + /* The parser has run and performed L4 checksum validation.
2077 + * We know there were no parser errors (and implicitly no
2078 + * L4 csum error), otherwise we wouldn't be here.
2079 + */
2080 + skb->ip_summed = CHECKSUM_UNNECESSARY;
2081 +
2082 + /* Don't go through GRO for certain types of traffic that
2083 + * we know are not GRO-able, such as dgram-based protocols.
2084 + * In the worst-case scenarios, such as small-pkt terminating
2085 + * UDP, the extra GRO processing would be overkill.
2086 + *
2087 + * The only protocol the Parser supports that is also GRO-able
2088 + * is currently TCP.
2089 + */
2090 + if (!fm_l4_frame_is_tcp(parse_results))
2091 + *use_gro = 0;
2092 +
2093 + return;
2094 + }
2095 +
2096 + /* We're here because either the parser didn't run or the L4 checksum
2097 + * was not verified. This may include the case of a UDP frame with
2098 + * checksum zero or an L4 proto other than TCP/UDP
2099 + */
2100 + skb->ip_summed = CHECKSUM_NONE;
2101 +
2102 + /* Bypass GRO for unknown traffic or if no PCDs are applied */
2103 + *use_gro = 0;
2104 +}
2105 +
2106 +int dpaa_eth_poll(struct napi_struct *napi, int budget)
2107 +{
2108 + struct dpa_napi_portal *np =
2109 + container_of(napi, struct dpa_napi_portal, napi);
2110 +
2111 + int cleaned = qman_p_poll_dqrr(np->p, budget);
2112 +
2113 + if (cleaned < budget) {
2114 + int tmp;
2115 + napi_complete(napi);
2116 + tmp = qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2117 + DPA_BUG_ON(tmp);
2118 + }
2119 +
2120 + return cleaned;
2121 +}
2122 +EXPORT_SYMBOL(dpaa_eth_poll);
2123 +
2124 +static void __hot _dpa_tx_conf(struct net_device *net_dev,
2125 + const struct dpa_priv_s *priv,
2126 + struct dpa_percpu_priv_s *percpu_priv,
2127 + const struct qm_fd *fd,
2128 + u32 fqid)
2129 +{
2130 + struct sk_buff *skb;
2131 +
2132 + /* do we need the timestamp for the error frames? */
2133 +
2134 + if (unlikely(fd->status & FM_FD_STAT_TX_ERRORS) != 0) {
2135 + if (netif_msg_hw(priv) && net_ratelimit())
2136 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2137 + fd->status & FM_FD_STAT_TX_ERRORS);
2138 +
2139 + percpu_priv->stats.tx_errors++;
2140 + }
2141 +
2142 + /* hopefully we need not get the timestamp before the hook */
2143 +#ifdef CONFIG_FSL_DPAA_HOOKS
2144 + if (dpaa_eth_hooks.tx_confirm && dpaa_eth_hooks.tx_confirm(net_dev,
2145 + fd, fqid) == DPAA_ETH_STOLEN)
2146 + /* it's the hook that must now perform cleanup */
2147 + return;
2148 +#endif
2149 + /* This might not perfectly reflect the reality, if the core dequeuing
2150 + * the Tx confirmation is different from the one that did the enqueue,
2151 + * but at least it'll show up in the total count.
2152 + */
2153 + percpu_priv->tx_confirm++;
2154 +
2155 + skb = _dpa_cleanup_tx_fd(priv, fd);
2156 +
2157 + dev_kfree_skb(skb);
2158 +}
2159 +
2160 +enum qman_cb_dqrr_result
2161 +priv_rx_error_dqrr(struct qman_portal *portal,
2162 + struct qman_fq *fq,
2163 + const struct qm_dqrr_entry *dq)
2164 +{
2165 + struct net_device *net_dev;
2166 + struct dpa_priv_s *priv;
2167 + struct dpa_percpu_priv_s *percpu_priv;
2168 + int *count_ptr;
2169 +
2170 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2171 + priv = netdev_priv(net_dev);
2172 +
2173 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2174 + count_ptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
2175 +
2176 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2177 + return qman_cb_dqrr_stop;
2178 +
2179 + if (unlikely(dpaa_eth_refill_bpools(priv->dpa_bp, count_ptr)))
2180 + /* Unable to refill the buffer pool due to insufficient
2181 + * system memory. Just release the frame back into the pool,
2182 + * otherwise we'll soon end up with an empty buffer pool.
2183 + */
2184 + dpa_fd_release(net_dev, &dq->fd);
2185 + else
2186 + _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2187 +
2188 + return qman_cb_dqrr_consume;
2189 +}
2190 +
2191 +
2192 +enum qman_cb_dqrr_result __hot
2193 +priv_rx_default_dqrr(struct qman_portal *portal,
2194 + struct qman_fq *fq,
2195 + const struct qm_dqrr_entry *dq)
2196 +{
2197 + struct net_device *net_dev;
2198 + struct dpa_priv_s *priv;
2199 + struct dpa_percpu_priv_s *percpu_priv;
2200 + int *count_ptr;
2201 + struct dpa_bp *dpa_bp;
2202 +
2203 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2204 + priv = netdev_priv(net_dev);
2205 + dpa_bp = priv->dpa_bp;
2206 +
2207 + /* Trace the Rx fd */
2208 + trace_dpa_rx_fd(net_dev, fq, &dq->fd);
2209 +
2210 + /* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */
2211 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2212 + count_ptr = raw_cpu_ptr(dpa_bp->percpu_count);
2213 +
2214 + if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal)))
2215 + return qman_cb_dqrr_stop;
2216 +
2217 + /* Vale of plenty: make sure we didn't run out of buffers */
2218 +
2219 + if (unlikely(dpaa_eth_refill_bpools(dpa_bp, count_ptr)))
2220 + /* Unable to refill the buffer pool due to insufficient
2221 + * system memory. Just release the frame back into the pool,
2222 + * otherwise we'll soon end up with an empty buffer pool.
2223 + */
2224 + dpa_fd_release(net_dev, &dq->fd);
2225 + else
2226 + _dpa_rx(net_dev, portal, priv, percpu_priv, &dq->fd, fq->fqid,
2227 + count_ptr);
2228 +
2229 + return qman_cb_dqrr_consume;
2230 +}
2231 +
2232 +enum qman_cb_dqrr_result
2233 +priv_tx_conf_error_dqrr(struct qman_portal *portal,
2234 + struct qman_fq *fq,
2235 + const struct qm_dqrr_entry *dq)
2236 +{
2237 + struct net_device *net_dev;
2238 + struct dpa_priv_s *priv;
2239 + struct dpa_percpu_priv_s *percpu_priv;
2240 +
2241 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2242 + priv = netdev_priv(net_dev);
2243 +
2244 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2245 +
2246 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2247 + return qman_cb_dqrr_stop;
2248 +
2249 + _dpa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2250 +
2251 + return qman_cb_dqrr_consume;
2252 +}
2253 +
2254 +enum qman_cb_dqrr_result __hot
2255 +priv_tx_conf_default_dqrr(struct qman_portal *portal,
2256 + struct qman_fq *fq,
2257 + const struct qm_dqrr_entry *dq)
2258 +{
2259 + struct net_device *net_dev;
2260 + struct dpa_priv_s *priv;
2261 + struct dpa_percpu_priv_s *percpu_priv;
2262 +
2263 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2264 + priv = netdev_priv(net_dev);
2265 +
2266 + /* Trace the fd */
2267 + trace_dpa_tx_conf_fd(net_dev, fq, &dq->fd);
2268 +
2269 + /* Non-migratable context, safe to use raw_cpu_ptr */
2270 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2271 +
2272 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2273 + return qman_cb_dqrr_stop;
2274 +
2275 + _dpa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2276 +
2277 + return qman_cb_dqrr_consume;
2278 +}
2279 +
2280 +void priv_ern(struct qman_portal *portal,
2281 + struct qman_fq *fq,
2282 + const struct qm_mr_entry *msg)
2283 +{
2284 + struct net_device *net_dev;
2285 + const struct dpa_priv_s *priv;
2286 + struct sk_buff *skb;
2287 + struct dpa_percpu_priv_s *percpu_priv;
2288 + struct qm_fd fd = msg->ern.fd;
2289 +
2290 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2291 + priv = netdev_priv(net_dev);
2292 + /* Non-migratable context, safe to use raw_cpu_ptr */
2293 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2294 +
2295 + percpu_priv->stats.tx_dropped++;
2296 + percpu_priv->stats.tx_fifo_errors++;
2297 + count_ern(percpu_priv, msg);
2298 +
2299 + /* If we intended this buffer to go into the pool
2300 + * when the FM was done, we need to put it in
2301 + * manually.
2302 + */
2303 + if (msg->ern.fd.bpid != 0xff) {
2304 + dpa_fd_release(net_dev, &fd);
2305 + return;
2306 + }
2307 +
2308 + skb = _dpa_cleanup_tx_fd(priv, &fd);
2309 + dev_kfree_skb_any(skb);
2310 +}
2311 +
2312 +const struct dpa_fq_cbs_t private_fq_cbs = {
2313 + .rx_defq = { .cb = { .dqrr = priv_rx_default_dqrr } },
2314 + .tx_defq = { .cb = { .dqrr = priv_tx_conf_default_dqrr } },
2315 + .rx_errq = { .cb = { .dqrr = priv_rx_error_dqrr } },
2316 + .tx_errq = { .cb = { .dqrr = priv_tx_conf_error_dqrr } },
2317 + .egress_ern = { .cb = { .ern = priv_ern } }
2318 +};
2319 +EXPORT_SYMBOL(private_fq_cbs);
2320 +
2321 +static void dpaa_eth_napi_enable(struct dpa_priv_s *priv)
2322 +{
2323 + struct dpa_percpu_priv_s *percpu_priv;
2324 + int i, j;
2325 +
2326 + for_each_possible_cpu(i) {
2327 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2328 +
2329 + for (j = 0; j < qman_portal_max; j++)
2330 + napi_enable(&percpu_priv->np[j].napi);
2331 + }
2332 +}
2333 +
2334 +static void dpaa_eth_napi_disable(struct dpa_priv_s *priv)
2335 +{
2336 + struct dpa_percpu_priv_s *percpu_priv;
2337 + int i, j;
2338 +
2339 + for_each_possible_cpu(i) {
2340 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2341 +
2342 + for (j = 0; j < qman_portal_max; j++)
2343 + napi_disable(&percpu_priv->np[j].napi);
2344 + }
2345 +}
2346 +
2347 +static int __cold dpa_eth_priv_start(struct net_device *net_dev)
2348 +{
2349 + int err;
2350 + struct dpa_priv_s *priv;
2351 +
2352 + priv = netdev_priv(net_dev);
2353 +
2354 + dpaa_eth_napi_enable(priv);
2355 +
2356 + err = dpa_start(net_dev);
2357 + if (err < 0)
2358 + dpaa_eth_napi_disable(priv);
2359 +
2360 + return err;
2361 +}
2362 +
2363 +
2364 +
2365 +static int __cold dpa_eth_priv_stop(struct net_device *net_dev)
2366 +{
2367 + int _errno;
2368 + struct dpa_priv_s *priv;
2369 +
2370 + _errno = dpa_stop(net_dev);
2371 + /* Allow NAPI to consume any frame still in the Rx/TxConfirm
2372 + * ingress queues. This is to avoid a race between the current
2373 + * context and ksoftirqd which could leave NAPI disabled while
2374 + * in fact there's still Rx traffic to be processed.
2375 + */
2376 + usleep_range(5000, 10000);
2377 +
2378 + priv = netdev_priv(net_dev);
2379 + dpaa_eth_napi_disable(priv);
2380 +
2381 + return _errno;
2382 +}
2383 +
2384 +#ifdef CONFIG_NET_POLL_CONTROLLER
2385 +static void dpaa_eth_poll_controller(struct net_device *net_dev)
2386 +{
2387 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2388 + struct dpa_percpu_priv_s *percpu_priv =
2389 + raw_cpu_ptr(priv->percpu_priv);
2390 + struct qman_portal *p;
2391 + const struct qman_portal_config *pc;
2392 + struct dpa_napi_portal *np;
2393 +
2394 + p = (struct qman_portal *)qman_get_affine_portal(smp_processor_id());
2395 + pc = qman_p_get_portal_config(p);
2396 + np = &percpu_priv->np[pc->index];
2397 +
2398 + qman_p_irqsource_remove(np->p, QM_PIRQ_DQRI);
2399 + qman_p_poll_dqrr(np->p, np->napi.weight);
2400 + qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2401 +}
2402 +#endif
2403 +
2404 +static const struct net_device_ops dpa_private_ops = {
2405 + .ndo_open = dpa_eth_priv_start,
2406 + .ndo_start_xmit = dpa_tx,
2407 + .ndo_stop = dpa_eth_priv_stop,
2408 + .ndo_tx_timeout = dpa_timeout,
2409 + .ndo_get_stats64 = dpa_get_stats64,
2410 + .ndo_set_mac_address = dpa_set_mac_address,
2411 + .ndo_validate_addr = eth_validate_addr,
2412 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
2413 + .ndo_select_queue = dpa_select_queue,
2414 +#endif
2415 + .ndo_change_mtu = dpa_change_mtu,
2416 + .ndo_set_rx_mode = dpa_set_rx_mode,
2417 + .ndo_init = dpa_ndo_init,
2418 + .ndo_set_features = dpa_set_features,
2419 + .ndo_fix_features = dpa_fix_features,
2420 + .ndo_do_ioctl = dpa_ioctl,
2421 +#ifdef CONFIG_NET_POLL_CONTROLLER
2422 + .ndo_poll_controller = dpaa_eth_poll_controller,
2423 +#endif
2424 +};
2425 +
2426 +static int dpa_private_napi_add(struct net_device *net_dev)
2427 +{
2428 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2429 + struct dpa_percpu_priv_s *percpu_priv;
2430 + int i, cpu;
2431 +
2432 + for_each_possible_cpu(cpu) {
2433 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2434 +
2435 + percpu_priv->np = devm_kzalloc(net_dev->dev.parent,
2436 + qman_portal_max * sizeof(struct dpa_napi_portal),
2437 + GFP_KERNEL);
2438 +
2439 + if (unlikely(percpu_priv->np == NULL)) {
2440 + dev_err(net_dev->dev.parent, "devm_kzalloc() failed\n");
2441 + return -ENOMEM;
2442 + }
2443 +
2444 + for (i = 0; i < qman_portal_max; i++)
2445 + netif_napi_add(net_dev, &percpu_priv->np[i].napi,
2446 + dpaa_eth_poll, DPA_NAPI_WEIGHT);
2447 + }
2448 +
2449 + return 0;
2450 +}
2451 +
2452 +void dpa_private_napi_del(struct net_device *net_dev)
2453 +{
2454 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2455 + struct dpa_percpu_priv_s *percpu_priv;
2456 + int i, cpu;
2457 +
2458 + for_each_possible_cpu(cpu) {
2459 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2460 +
2461 + if (percpu_priv->np) {
2462 + for (i = 0; i < qman_portal_max; i++)
2463 + netif_napi_del(&percpu_priv->np[i].napi);
2464 +
2465 + devm_kfree(net_dev->dev.parent, percpu_priv->np);
2466 + }
2467 + }
2468 +}
2469 +EXPORT_SYMBOL(dpa_private_napi_del);
2470 +
2471 +static int dpa_private_netdev_init(struct net_device *net_dev)
2472 +{
2473 + int i;
2474 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2475 + struct dpa_percpu_priv_s *percpu_priv;
2476 + const uint8_t *mac_addr;
2477 +
2478 + /* Although we access another CPU's private data here
2479 + * we do it at initialization so it is safe
2480 + */
2481 + for_each_possible_cpu(i) {
2482 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2483 + percpu_priv->net_dev = net_dev;
2484 + }
2485 +
2486 + net_dev->netdev_ops = &dpa_private_ops;
2487 + mac_addr = priv->mac_dev->addr;
2488 +
2489 + net_dev->mem_start = priv->mac_dev->res->start;
2490 + net_dev->mem_end = priv->mac_dev->res->end;
2491 +
2492 + net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
2493 + NETIF_F_LLTX);
2494 +
2495 + /* Advertise S/G and HIGHDMA support for private interfaces */
2496 + net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
2497 + /* Recent kernels enable GSO automatically, if
2498 + * we declare NETIF_F_SG. For conformity, we'll
2499 + * still declare GSO explicitly.
2500 + */
2501 + net_dev->features |= NETIF_F_GSO;
2502 +
2503 + /* Advertise GRO support */
2504 + net_dev->features |= NETIF_F_GRO;
2505 +
2506 + /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */
2507 + net_dev->features |= NETIF_F_HW_ACCEL_MQ;
2508 +
2509 + return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
2510 +}
2511 +
2512 +static struct dpa_bp * __cold
2513 +dpa_priv_bp_probe(struct device *dev)
2514 +{
2515 + struct dpa_bp *dpa_bp;
2516 +
2517 + dpa_bp = devm_kzalloc(dev, sizeof(*dpa_bp), GFP_KERNEL);
2518 + if (unlikely(dpa_bp == NULL)) {
2519 + dev_err(dev, "devm_kzalloc() failed\n");
2520 + return ERR_PTR(-ENOMEM);
2521 + }
2522 +
2523 + dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count);
2524 + dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
2525 +
2526 + dpa_bp->seed_cb = dpa_bp_priv_seed;
2527 + dpa_bp->free_buf_cb = _dpa_bp_free_pf;
2528 +
2529 + return dpa_bp;
2530 +}
2531 +
2532 +/* Place all ingress FQs (Rx Default, Rx Error, PCD FQs) in a dedicated CGR.
2533 + * We won't be sending congestion notifications to FMan; for now, we just use
2534 + * this CGR to generate enqueue rejections to FMan in order to drop the frames
2535 + * before they reach our ingress queues and eat up memory.
2536 + */
2537 +static int dpaa_eth_priv_ingress_cgr_init(struct dpa_priv_s *priv)
2538 +{
2539 + struct qm_mcc_initcgr initcgr;
2540 + u32 cs_th;
2541 + int err;
2542 +
2543 + err = qman_alloc_cgrid(&priv->ingress_cgr.cgrid);
2544 + if (err < 0) {
2545 + pr_err("Error %d allocating CGR ID\n", err);
2546 + goto out_error;
2547 + }
2548 +
2549 + /* Enable CS TD, but disable Congestion State Change Notifications. */
2550 + initcgr.we_mask = QM_CGR_WE_CS_THRES;
2551 + initcgr.cgr.cscn_en = QM_CGR_EN;
2552 + cs_th = CONFIG_FSL_DPAA_INGRESS_CS_THRESHOLD;
2553 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
2554 +
2555 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
2556 + initcgr.cgr.cstd_en = QM_CGR_EN;
2557 +
2558 + /* This is actually a hack, because this CGR will be associated with
2559 + * our affine SWP. However, we'll place our ingress FQs in it.
2560 + */
2561 + err = qman_create_cgr(&priv->ingress_cgr, QMAN_CGR_FLAG_USE_INIT,
2562 + &initcgr);
2563 + if (err < 0) {
2564 + pr_err("Error %d creating ingress CGR with ID %d\n", err,
2565 + priv->ingress_cgr.cgrid);
2566 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2567 + goto out_error;
2568 + }
2569 + pr_debug("Created ingress CGR %d for netdev with hwaddr %pM\n",
2570 + priv->ingress_cgr.cgrid, priv->mac_dev->addr);
2571 +
2572 + /* struct qman_cgr allows special cgrid values (i.e. outside the 0..255
2573 + * range), but we have no common initialization path between the
2574 + * different variants of the DPAA Eth driver, so we do it here rather
2575 + * than modifying every other variant than "private Eth".
2576 + */
2577 + priv->use_ingress_cgr = true;
2578 +
2579 +out_error:
2580 + return err;
2581 +}
2582 +
2583 +static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
2584 + size_t count)
2585 +{
2586 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2587 + int i;
2588 +
2589 + if (netif_msg_probe(priv))
2590 + dev_dbg(net_dev->dev.parent,
2591 + "Using private BM buffer pools\n");
2592 +
2593 + priv->bp_count = count;
2594 +
2595 + for (i = 0; i < count; i++) {
2596 + int err;
2597 + err = dpa_bp_alloc(&dpa_bp[i]);
2598 + if (err < 0) {
2599 + dpa_bp_free(priv);
2600 + priv->dpa_bp = NULL;
2601 + return err;
2602 + }
2603 +
2604 + priv->dpa_bp = &dpa_bp[i];
2605 + }
2606 +
2607 + dpa_priv_common_bpid = priv->dpa_bp->bpid;
2608 + return 0;
2609 +}
2610 +
2611 +static const struct of_device_id dpa_match[];
2612 +
2613 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2614 +static int dpa_new_loop_id(void)
2615 +{
2616 + static int if_id;
2617 +
2618 + return if_id++;
2619 +}
2620 +#endif
2621 +
2622 +static int
2623 +dpaa_eth_priv_probe(struct platform_device *_of_dev)
2624 +{
2625 + int err = 0, i, channel;
2626 + struct device *dev;
2627 + struct device_node *dpa_node;
2628 + struct dpa_bp *dpa_bp;
2629 + size_t count = 1;
2630 + struct net_device *net_dev = NULL;
2631 + struct dpa_priv_s *priv = NULL;
2632 + struct dpa_percpu_priv_s *percpu_priv;
2633 + struct fm_port_fqs port_fqs;
2634 + struct dpa_buffer_layout_s *buf_layout = NULL;
2635 + struct mac_device *mac_dev;
2636 +
2637 + dev = &_of_dev->dev;
2638 +
2639 + dpa_node = dev->of_node;
2640 +
2641 + if (!of_device_is_available(dpa_node))
2642 + return -ENODEV;
2643 +
2644 + /* Get the buffer pools assigned to this interface;
2645 + * run only once the default pool probing code
2646 + */
2647 + dpa_bp = (dpa_bpid2pool(dpa_priv_common_bpid)) ? :
2648 + dpa_priv_bp_probe(dev);
2649 + if (IS_ERR(dpa_bp))
2650 + return PTR_ERR(dpa_bp);
2651 +
2652 + /* Allocate this early, so we can store relevant information in
2653 + * the private area (needed by 1588 code in dpa_mac_probe)
2654 + */
2655 + net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES);
2656 + if (!net_dev) {
2657 + dev_err(dev, "alloc_etherdev_mq() failed\n");
2658 + goto alloc_etherdev_mq_failed;
2659 + }
2660 +
2661 + /* Do this here, so we can be verbose early */
2662 + SET_NETDEV_DEV(net_dev, dev);
2663 + dev_set_drvdata(dev, net_dev);
2664 +
2665 + priv = netdev_priv(net_dev);
2666 + priv->net_dev = net_dev;
2667 + strcpy(priv->if_type, "private");
2668 +
2669 + priv->msg_enable = netif_msg_init(debug, -1);
2670 +
2671 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2672 + priv->loop_id = dpa_new_loop_id();
2673 + priv->loop_to = -1; /* disabled by default */
2674 + dpa_loop_netdevs[priv->loop_id] = net_dev;
2675 +#endif
2676 +
2677 + mac_dev = dpa_mac_probe(_of_dev);
2678 + if (IS_ERR(mac_dev) || !mac_dev) {
2679 + err = PTR_ERR(mac_dev);
2680 + goto mac_probe_failed;
2681 + }
2682 +
2683 + /* We have physical ports, so we need to establish
2684 + * the buffer layout.
2685 + */
2686 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
2687 + GFP_KERNEL);
2688 + if (!buf_layout) {
2689 + dev_err(dev, "devm_kzalloc() failed\n");
2690 + goto alloc_failed;
2691 + }
2692 + dpa_set_buffers_layout(mac_dev, buf_layout);
2693 +
2694 + /* For private ports, need to compute the size of the default
2695 + * buffer pool, based on FMan port buffer layout;also update
2696 + * the maximum buffer size for private ports if necessary
2697 + */
2698 + dpa_bp->size = dpa_bp_size(&buf_layout[RX]);
2699 +
2700 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
2701 + /* We only want to use jumbo frame optimization if we actually have
2702 + * L2 MAX FRM set for jumbo frames as well.
2703 + */
2704 +#ifndef CONFIG_PPC
2705 + if (likely(!dpaa_errata_a010022))
2706 +#endif
2707 + if(fm_get_max_frm() < 9600)
2708 + dev_warn(dev,
2709 + "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n");
2710 +#endif
2711 +
2712 + INIT_LIST_HEAD(&priv->dpa_fq_list);
2713 +
2714 + memset(&port_fqs, 0, sizeof(port_fqs));
2715 +
2716 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs, true, RX);
2717 + if (!err)
2718 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
2719 + &port_fqs, true, TX);
2720 +
2721 + if (err < 0)
2722 + goto fq_probe_failed;
2723 +
2724 + /* bp init */
2725 +
2726 + err = dpa_priv_bp_create(net_dev, dpa_bp, count);
2727 +
2728 + if (err < 0)
2729 + goto bp_create_failed;
2730 +
2731 + priv->mac_dev = mac_dev;
2732 +
2733 + channel = dpa_get_channel();
2734 +
2735 + if (channel < 0) {
2736 + err = channel;
2737 + goto get_channel_failed;
2738 + }
2739 +
2740 + priv->channel = (uint16_t)channel;
2741 + dpaa_eth_add_channel(priv->channel);
2742 +
2743 + dpa_fq_setup(priv, &private_fq_cbs, priv->mac_dev->port_dev[TX]);
2744 +
2745 + /* Create a congestion group for this netdev, with
2746 + * dynamically-allocated CGR ID.
2747 + * Must be executed after probing the MAC, but before
2748 + * assigning the egress FQs to the CGRs.
2749 + */
2750 + err = dpaa_eth_cgr_init(priv);
2751 + if (err < 0) {
2752 + dev_err(dev, "Error initializing CGR\n");
2753 + goto tx_cgr_init_failed;
2754 + }
2755 + err = dpaa_eth_priv_ingress_cgr_init(priv);
2756 + if (err < 0) {
2757 + dev_err(dev, "Error initializing ingress CGR\n");
2758 + goto rx_cgr_init_failed;
2759 + }
2760 +
2761 + /* Add the FQs to the interface, and make them active */
2762 + err = dpa_fqs_init(dev, &priv->dpa_fq_list, false);
2763 + if (err < 0)
2764 + goto fq_alloc_failed;
2765 +
2766 + priv->buf_layout = buf_layout;
2767 + priv->tx_headroom = dpa_get_headroom(&priv->buf_layout[TX]);
2768 + priv->rx_headroom = dpa_get_headroom(&priv->buf_layout[RX]);
2769 +
2770 + /* All real interfaces need their ports initialized */
2771 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
2772 + buf_layout, dev);
2773 +
2774 +#ifdef CONFIG_FMAN_PFC
2775 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
2776 + err = fm_port_set_pfc_priorities_mapping_to_qman_wq(
2777 + mac_dev->port_dev[TX], i, i);
2778 + if (unlikely(err != 0)) {
2779 + dev_err(dev, "Error maping PFC %u to WQ %u\n", i, i);
2780 + goto pfc_mapping_failed;
2781 + }
2782 + }
2783 +#endif
2784 +
2785 + priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
2786 +
2787 + if (priv->percpu_priv == NULL) {
2788 + dev_err(dev, "devm_alloc_percpu() failed\n");
2789 + err = -ENOMEM;
2790 + goto alloc_percpu_failed;
2791 + }
2792 + for_each_possible_cpu(i) {
2793 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2794 + memset(percpu_priv, 0, sizeof(*percpu_priv));
2795 + }
2796 +
2797 + /* Initialize NAPI */
2798 + err = dpa_private_napi_add(net_dev);
2799 +
2800 + if (err < 0)
2801 + goto napi_add_failed;
2802 +
2803 + err = dpa_private_netdev_init(net_dev);
2804 +
2805 + if (err < 0)
2806 + goto netdev_init_failed;
2807 +
2808 + dpaa_eth_sysfs_init(&net_dev->dev);
2809 +
2810 +#ifdef CONFIG_PM
2811 + device_set_wakeup_capable(dev, true);
2812 +#endif
2813 +
2814 + pr_info("fsl_dpa: Probed interface %s\n", net_dev->name);
2815 +
2816 + return 0;
2817 +
2818 +netdev_init_failed:
2819 +napi_add_failed:
2820 + dpa_private_napi_del(net_dev);
2821 +alloc_percpu_failed:
2822 +#ifdef CONFIG_FMAN_PFC
2823 +pfc_mapping_failed:
2824 +#endif
2825 + dpa_fq_free(dev, &priv->dpa_fq_list);
2826 +fq_alloc_failed:
2827 + qman_delete_cgr_safe(&priv->ingress_cgr);
2828 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2829 +rx_cgr_init_failed:
2830 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
2831 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
2832 +tx_cgr_init_failed:
2833 +get_channel_failed:
2834 + dpa_bp_free(priv);
2835 +bp_create_failed:
2836 +fq_probe_failed:
2837 +alloc_failed:
2838 +mac_probe_failed:
2839 + dev_set_drvdata(dev, NULL);
2840 + free_netdev(net_dev);
2841 +alloc_etherdev_mq_failed:
2842 + if (atomic_read(&dpa_bp->refs) == 0)
2843 + devm_kfree(dev, dpa_bp);
2844 +
2845 + return err;
2846 +}
2847 +
2848 +static const struct of_device_id dpa_match[] = {
2849 + {
2850 + .compatible = "fsl,dpa-ethernet"
2851 + },
2852 + {}
2853 +};
2854 +MODULE_DEVICE_TABLE(of, dpa_match);
2855 +
2856 +static struct platform_driver dpa_driver = {
2857 + .driver = {
2858 + .name = KBUILD_MODNAME,
2859 + .of_match_table = dpa_match,
2860 + .owner = THIS_MODULE,
2861 + .pm = DPAA_PM_OPS,
2862 + },
2863 + .probe = dpaa_eth_priv_probe,
2864 + .remove = dpa_remove
2865 +};
2866 +
2867 +#ifndef CONFIG_PPC
2868 +static bool __init __cold soc_has_errata_a010022(void)
2869 +{
2870 +#ifdef CONFIG_SOC_BUS
2871 + const struct soc_device_attribute soc_msi_matches[] = {
2872 + { .family = "QorIQ LS1043A",
2873 + .data = NULL },
2874 + { },
2875 + };
2876 +
2877 + if (soc_device_match(soc_msi_matches))
2878 + return true;
2879 +
2880 + return false;
2881 +#else
2882 + return true; /* cannot identify SoC */
2883 +#endif
2884 +}
2885 +#endif
2886 +
2887 +static int __init __cold dpa_load(void)
2888 +{
2889 + int _errno;
2890 +
2891 + pr_info(DPA_DESCRIPTION "\n");
2892 +
2893 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2894 + dpa_debugfs_module_init();
2895 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2896 +
2897 + /* initialise dpaa_eth mirror values */
2898 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
2899 + dpa_max_frm = fm_get_max_frm();
2900 + dpa_num_cpus = num_possible_cpus();
2901 +
2902 +#ifndef CONFIG_PPC
2903 + /* Detect if the current SoC requires the 4K alignment workaround */
2904 + dpaa_errata_a010022 = soc_has_errata_a010022();
2905 +#endif
2906 +
2907 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2908 + memset(dpa_loop_netdevs, 0, sizeof(dpa_loop_netdevs));
2909 +#endif
2910 +
2911 + _errno = platform_driver_register(&dpa_driver);
2912 + if (unlikely(_errno < 0)) {
2913 + pr_err(KBUILD_MODNAME
2914 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
2915 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
2916 + }
2917 +
2918 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2919 + KBUILD_BASENAME".c", __func__);
2920 +
2921 + return _errno;
2922 +}
2923 +module_init(dpa_load);
2924 +
2925 +static void __exit __cold dpa_unload(void)
2926 +{
2927 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
2928 + KBUILD_BASENAME".c", __func__);
2929 +
2930 + platform_driver_unregister(&dpa_driver);
2931 +
2932 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2933 + dpa_debugfs_module_exit();
2934 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2935 +
2936 + /* Only one channel is used and needs to be relased after all
2937 + * interfaces are removed
2938 + */
2939 + dpa_release_channel();
2940 +
2941 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2942 + KBUILD_BASENAME".c", __func__);
2943 +}
2944 +module_exit(dpa_unload);
2945 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
2946 new file mode 100644
2947 index 00000000..57c9bef4
2948 --- /dev/null
2949 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
2950 @@ -0,0 +1,687 @@
2951 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
2952 + *
2953 + * Redistribution and use in source and binary forms, with or without
2954 + * modification, are permitted provided that the following conditions are met:
2955 + * * Redistributions of source code must retain the above copyright
2956 + * notice, this list of conditions and the following disclaimer.
2957 + * * Redistributions in binary form must reproduce the above copyright
2958 + * notice, this list of conditions and the following disclaimer in the
2959 + * documentation and/or other materials provided with the distribution.
2960 + * * Neither the name of Freescale Semiconductor nor the
2961 + * names of its contributors may be used to endorse or promote products
2962 + * derived from this software without specific prior written permission.
2963 + *
2964 + *
2965 + * ALTERNATIVELY, this software may be distributed under the terms of the
2966 + * GNU General Public License ("GPL") as published by the Free Software
2967 + * Foundation, either version 2 of that License or (at your option) any
2968 + * later version.
2969 + *
2970 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
2971 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2972 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2973 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
2974 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2975 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2976 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2977 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2978 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2979 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2980 + */
2981 +
2982 +#ifndef __DPA_H
2983 +#define __DPA_H
2984 +
2985 +#include <linux/netdevice.h>
2986 +#include <linux/fsl_qman.h> /* struct qman_fq */
2987 +
2988 +#include "fm_ext.h"
2989 +#include "dpaa_eth_trace.h"
2990 +
2991 +extern int dpa_rx_extra_headroom;
2992 +extern int dpa_max_frm;
2993 +extern int dpa_num_cpus;
2994 +
2995 +#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom
2996 +#define dpa_get_max_frm() dpa_max_frm
2997 +
2998 +#define dpa_get_max_mtu() \
2999 + (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN))
3000 +
3001 +#define __hot
3002 +
3003 +/* Simple enum of FQ types - used for array indexing */
3004 +enum port_type {RX, TX};
3005 +
3006 +/* TODO: This structure should be renamed & moved to the FMD wrapper */
3007 +struct dpa_buffer_layout_s {
3008 + uint16_t priv_data_size;
3009 + bool parse_results;
3010 + bool time_stamp;
3011 + bool hash_results;
3012 + uint8_t manip_extra_space;
3013 + uint16_t data_align;
3014 +};
3015 +
3016 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3017 +#define DPA_BUG_ON(cond) BUG_ON(cond)
3018 +#else
3019 +#define DPA_BUG_ON(cond)
3020 +#endif
3021 +
3022 +#define DPA_TX_PRIV_DATA_SIZE 16
3023 +#define DPA_PARSE_RESULTS_SIZE sizeof(fm_prs_result_t)
3024 +#define DPA_TIME_STAMP_SIZE 8
3025 +#define DPA_HASH_RESULTS_SIZE 8
3026 +#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \
3027 + dpa_get_rx_extra_headroom())
3028 +
3029 +#define FM_FD_STAT_RX_ERRORS \
3030 + (FM_PORT_FRM_ERR_DMA | FM_PORT_FRM_ERR_PHYSICAL | \
3031 + FM_PORT_FRM_ERR_SIZE | FM_PORT_FRM_ERR_CLS_DISCARD | \
3032 + FM_PORT_FRM_ERR_EXTRACTION | FM_PORT_FRM_ERR_NO_SCHEME | \
3033 + FM_PORT_FRM_ERR_ILL_PLCR | FM_PORT_FRM_ERR_PRS_TIMEOUT | \
3034 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | FM_PORT_FRM_ERR_PRS_HDR_ERR)
3035 +
3036 +#define FM_FD_STAT_TX_ERRORS \
3037 + (FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT | \
3038 + FM_PORT_FRM_ERR_LENGTH | FM_PORT_FRM_ERR_DMA)
3039 +
3040 +#ifndef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
3041 +/* The raw buffer size must be cacheline aligned.
3042 + * Normally we use 2K buffers.
3043 + */
3044 +#define DPA_BP_RAW_SIZE 2048
3045 +#else
3046 +/* For jumbo frame optimizations, use buffers large enough to accommodate
3047 + * 9.6K frames, FD maximum offset, skb sh_info overhead and some extra
3048 + * space to account for further alignments.
3049 + */
3050 +#define DPA_MAX_FRM_SIZE 9600
3051 +#ifdef CONFIG_PPC
3052 +#define DPA_BP_RAW_SIZE \
3053 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3054 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))
3055 +#else /* CONFIG_PPC */
3056 +#define DPA_BP_RAW_SIZE ((unlikely(dpaa_errata_a010022)) ? 2048 : \
3057 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3058 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)))
3059 +#endif /* CONFIG_PPC */
3060 +#endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */
3061 +
3062 +/* This is what FMan is ever allowed to use.
3063 + * FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is
3064 + * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that,
3065 + * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us
3066 + * half-page-aligned buffers (can we?), so we reserve some more space
3067 + * for start-of-buffer alignment.
3068 + */
3069 +#define dpa_bp_size(buffer_layout) (SKB_WITH_OVERHEAD(DPA_BP_RAW_SIZE) - \
3070 + SMP_CACHE_BYTES)
3071 +/* We must ensure that skb_shinfo is always cacheline-aligned. */
3072 +#define DPA_SKB_SIZE(size) ((size) & ~(SMP_CACHE_BYTES - 1))
3073 +
3074 +/* Maximum size of a buffer for which recycling is allowed.
3075 + * We need an upper limit such that forwarded skbs that get reallocated on Tx
3076 + * aren't allowed to grow unboundedly. On the other hand, we need to make sure
3077 + * that skbs allocated by us will not fail to be recycled due to their size.
3078 + *
3079 + * For a requested size, the kernel allocator provides the next power of two
3080 + * sized block, which the stack will use as is, regardless of the actual size
3081 + * it required; since we must accommodate at most 9.6K buffers (L2 maximum
3082 + * supported frame size), set the recycling upper limit to 16K.
3083 + */
3084 +#define DPA_RECYCLE_MAX_SIZE 16384
3085 +
3086 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3087 +/*TODO: temporary for fman pcd testing */
3088 +#define FMAN_PCD_TESTS_MAX_NUM_RANGES 20
3089 +#endif
3090 +
3091 +#define DPAA_ETH_FQ_DELTA 0x10000
3092 +
3093 +#define DPAA_ETH_PCD_FQ_BASE(device_addr) \
3094 + (((device_addr) & 0x1fffff) >> 6)
3095 +
3096 +#define DPAA_ETH_PCD_FQ_HI_PRIO_BASE(device_addr) \
3097 + (DPAA_ETH_FQ_DELTA + DPAA_ETH_PCD_FQ_BASE(device_addr))
3098 +
3099 +/* Largest value that the FQD's OAL field can hold.
3100 + * This is DPAA-1.x specific.
3101 + * TODO: This rather belongs in fsl_qman.h
3102 + */
3103 +#define FSL_QMAN_MAX_OAL 127
3104 +
3105 +/* Maximum offset value for a contig or sg FD (represented on 9 bits) */
3106 +#define DPA_MAX_FD_OFFSET ((1 << 9) - 1)
3107 +
3108 +/* Default alignment for start of data in an Rx FD */
3109 +#define DPA_FD_DATA_ALIGNMENT 16
3110 +
3111 +/* Values for the L3R field of the FM Parse Results
3112 + */
3113 +/* L3 Type field: First IP Present IPv4 */
3114 +#define FM_L3_PARSE_RESULT_IPV4 0x8000
3115 +/* L3 Type field: First IP Present IPv6 */
3116 +#define FM_L3_PARSE_RESULT_IPV6 0x4000
3117 +
3118 +/* Values for the L4R field of the FM Parse Results
3119 + * See $8.8.4.7.20 - L4 HXS - L4 Results from DPAA-Rev2 Reference Manual.
3120 + */
3121 +/* L4 Type field: UDP */
3122 +#define FM_L4_PARSE_RESULT_UDP 0x40
3123 +/* L4 Type field: TCP */
3124 +#define FM_L4_PARSE_RESULT_TCP 0x20
3125 +/* FD status field indicating whether the FM Parser has attempted to validate
3126 + * the L4 csum of the frame.
3127 + * Note that having this bit set doesn't necessarily imply that the checksum
3128 + * is valid. One would have to check the parse results to find that out.
3129 + */
3130 +#define FM_FD_STAT_L4CV 0x00000004
3131 +
3132 +
3133 +#define FM_FD_STAT_ERR_PHYSICAL FM_PORT_FRM_ERR_PHYSICAL
3134 +
3135 +/* Check if the parsed frame was found to be a TCP segment.
3136 + *
3137 + * @parse_result_ptr must be of type (fm_prs_result_t *).
3138 + */
3139 +#define fm_l4_frame_is_tcp(parse_result_ptr) \
3140 + ((parse_result_ptr)->l4r & FM_L4_PARSE_RESULT_TCP)
3141 +
3142 +/* number of Tx queues to FMan */
3143 +#ifdef CONFIG_FMAN_PFC
3144 +#define DPAA_ETH_TX_QUEUES (NR_CPUS * CONFIG_FMAN_PFC_COS_COUNT)
3145 +#else
3146 +#define DPAA_ETH_TX_QUEUES NR_CPUS
3147 +#endif
3148 +
3149 +#define DPAA_ETH_RX_QUEUES 128
3150 +
3151 +/* Convenience macros for storing/retrieving the skb back-pointers. They must
3152 + * accommodate both recycling and confirmation paths - i.e. cases when the buf
3153 + * was allocated by ourselves, respectively by the stack. In the former case,
3154 + * we could store the skb at negative offset; in the latter case, we can't,
3155 + * so we'll use 0 as offset.
3156 + *
3157 + * NB: @off is an offset from a (struct sk_buff **) pointer!
3158 + */
3159 +#define DPA_WRITE_SKB_PTR(skb, skbh, addr, off) \
3160 +{ \
3161 + skbh = (struct sk_buff **)addr; \
3162 + *(skbh + (off)) = skb; \
3163 +}
3164 +#define DPA_READ_SKB_PTR(skb, skbh, addr, off) \
3165 +{ \
3166 + skbh = (struct sk_buff **)addr; \
3167 + skb = *(skbh + (off)); \
3168 +}
3169 +
3170 +#ifdef CONFIG_PM
3171 +/* Magic Packet wakeup */
3172 +#define DPAA_WOL_MAGIC 0x00000001
3173 +#endif
3174 +
3175 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3176 +struct pcd_range {
3177 + uint32_t base;
3178 + uint32_t count;
3179 +};
3180 +#endif
3181 +
3182 +/* More detailed FQ types - used for fine-grained WQ assignments */
3183 +enum dpa_fq_type {
3184 + FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */
3185 + FQ_TYPE_RX_ERROR, /* Rx Error FQs */
3186 + FQ_TYPE_RX_PCD, /* User-defined PCDs */
3187 + FQ_TYPE_TX, /* "Real" Tx FQs */
3188 + FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */
3189 + FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */
3190 + FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */
3191 + FQ_TYPE_RX_PCD_HI_PRIO, /* User-defined high-priority PCDs */
3192 +};
3193 +
3194 +struct dpa_fq {
3195 + struct qman_fq fq_base;
3196 + struct list_head list;
3197 + struct net_device *net_dev;
3198 + bool init;
3199 + uint32_t fqid;
3200 + uint32_t flags;
3201 + uint16_t channel;
3202 + uint8_t wq;
3203 + enum dpa_fq_type fq_type;
3204 +};
3205 +
3206 +struct dpa_fq_cbs_t {
3207 + struct qman_fq rx_defq;
3208 + struct qman_fq tx_defq;
3209 + struct qman_fq rx_errq;
3210 + struct qman_fq tx_errq;
3211 + struct qman_fq egress_ern;
3212 +};
3213 +
3214 +struct fqid_cell {
3215 + uint32_t start;
3216 + uint32_t count;
3217 +};
3218 +
3219 +struct dpa_bp {
3220 + struct bman_pool *pool;
3221 + uint8_t bpid;
3222 + struct device *dev;
3223 + union {
3224 + /* The buffer pools used for the private ports are initialized
3225 + * with target_count buffers for each CPU; at runtime the
3226 + * number of buffers per CPU is constantly brought back to this
3227 + * level
3228 + */
3229 + int target_count;
3230 + /* The configured value for the number of buffers in the pool,
3231 + * used for shared port buffer pools
3232 + */
3233 + int config_count;
3234 + };
3235 + size_t size;
3236 + bool seed_pool;
3237 + /* physical address of the contiguous memory used by the pool to store
3238 + * the buffers
3239 + */
3240 + dma_addr_t paddr;
3241 + /* virtual address of the contiguous memory used by the pool to store
3242 + * the buffers
3243 + */
3244 + void __iomem *vaddr;
3245 + /* current number of buffers in the bpool alloted to this CPU */
3246 + int __percpu *percpu_count;
3247 + atomic_t refs;
3248 + /* some bpools need to be seeded before use by this cb */
3249 + int (*seed_cb)(struct dpa_bp *);
3250 + /* some bpools need to be emptied before freeing; this cb is used
3251 + * for freeing of individual buffers taken from the pool
3252 + */
3253 + void (*free_buf_cb)(void *addr);
3254 +};
3255 +
3256 +struct dpa_rx_errors {
3257 + u64 dme; /* DMA Error */
3258 + u64 fpe; /* Frame Physical Error */
3259 + u64 fse; /* Frame Size Error */
3260 + u64 phe; /* Header Error */
3261 + u64 cse; /* Checksum Validation Error */
3262 +};
3263 +
3264 +/* Counters for QMan ERN frames - one counter per rejection code */
3265 +struct dpa_ern_cnt {
3266 + u64 cg_tdrop; /* Congestion group taildrop */
3267 + u64 wred; /* WRED congestion */
3268 + u64 err_cond; /* Error condition */
3269 + u64 early_window; /* Order restoration, frame too early */
3270 + u64 late_window; /* Order restoration, frame too late */
3271 + u64 fq_tdrop; /* FQ taildrop */
3272 + u64 fq_retired; /* FQ is retired */
3273 + u64 orp_zero; /* ORP disabled */
3274 +};
3275 +
3276 +struct dpa_napi_portal {
3277 + struct napi_struct napi;
3278 + struct qman_portal *p;
3279 +};
3280 +
3281 +struct dpa_percpu_priv_s {
3282 + struct net_device *net_dev;
3283 + struct dpa_napi_portal *np;
3284 + u64 in_interrupt;
3285 + u64 tx_returned;
3286 + u64 tx_confirm;
3287 + /* fragmented (non-linear) skbuffs received from the stack */
3288 + u64 tx_frag_skbuffs;
3289 + /* number of S/G frames received */
3290 + u64 rx_sg;
3291 +
3292 + struct rtnl_link_stats64 stats;
3293 + struct dpa_rx_errors rx_errors;
3294 + struct dpa_ern_cnt ern_cnt;
3295 +};
3296 +
3297 +struct dpa_priv_s {
3298 + struct dpa_percpu_priv_s __percpu *percpu_priv;
3299 + struct dpa_bp *dpa_bp;
3300 + /* Store here the needed Tx headroom for convenience and speed
3301 + * (even though it can be computed based on the fields of buf_layout)
3302 + */
3303 + uint16_t tx_headroom;
3304 + struct net_device *net_dev;
3305 + struct mac_device *mac_dev;
3306 + struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES];
3307 + struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES];
3308 +
3309 + size_t bp_count;
3310 +
3311 + uint16_t channel; /* "fsl,qman-channel-id" */
3312 + struct list_head dpa_fq_list;
3313 +
3314 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3315 + struct dentry *debugfs_loop_file;
3316 +#endif
3317 +
3318 + uint32_t msg_enable; /* net_device message level */
3319 +#ifdef CONFIG_FSL_DPAA_1588
3320 + struct dpa_ptp_tsu *tsu;
3321 +#endif
3322 +
3323 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3324 +/* TODO: this is temporary until pcd support is implemented in dpaa */
3325 + int priv_pcd_num_ranges;
3326 + struct pcd_range priv_pcd_ranges[FMAN_PCD_TESTS_MAX_NUM_RANGES];
3327 +#endif
3328 +
3329 + struct {
3330 + /**
3331 + * All egress queues to a given net device belong to one
3332 + * (and the same) congestion group.
3333 + */
3334 + struct qman_cgr cgr;
3335 + /* If congested, when it began. Used for performance stats. */
3336 + u32 congestion_start_jiffies;
3337 + /* Number of jiffies the Tx port was congested. */
3338 + u32 congested_jiffies;
3339 + /**
3340 + * Counter for the number of times the CGR
3341 + * entered congestion state
3342 + */
3343 + u32 cgr_congested_count;
3344 + } cgr_data;
3345 + /* Use a per-port CGR for ingress traffic. */
3346 + bool use_ingress_cgr;
3347 + struct qman_cgr ingress_cgr;
3348 +
3349 +#ifdef CONFIG_FSL_DPAA_TS
3350 + bool ts_tx_en; /* Tx timestamping enabled */
3351 + bool ts_rx_en; /* Rx timestamping enabled */
3352 +#endif /* CONFIG_FSL_DPAA_TS */
3353 +
3354 + struct dpa_buffer_layout_s *buf_layout;
3355 + uint16_t rx_headroom;
3356 + char if_type[30];
3357 +
3358 + void *peer;
3359 +#ifdef CONFIG_PM
3360 + u32 wol;
3361 +#endif
3362 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3363 + int loop_id;
3364 + int loop_to;
3365 +#endif
3366 +#ifdef CONFIG_FSL_DPAA_CEETM
3367 + bool ceetm_en; /* CEETM QoS enabled */
3368 +#endif
3369 +};
3370 +
3371 +struct fm_port_fqs {
3372 + struct dpa_fq *tx_defq;
3373 + struct dpa_fq *tx_errq;
3374 + struct dpa_fq *rx_defq;
3375 + struct dpa_fq *rx_errq;
3376 +};
3377 +
3378 +
3379 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3380 +extern struct net_device *dpa_loop_netdevs[20];
3381 +#endif
3382 +
3383 +/* functions with different implementation for SG and non-SG: */
3384 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp);
3385 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *count_ptr);
3386 +void __hot _dpa_rx(struct net_device *net_dev,
3387 + struct qman_portal *portal,
3388 + const struct dpa_priv_s *priv,
3389 + struct dpa_percpu_priv_s *percpu_priv,
3390 + const struct qm_fd *fd,
3391 + u32 fqid,
3392 + int *count_ptr);
3393 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev);
3394 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
3395 + struct qman_fq *egress_fq, struct qman_fq *conf_fq);
3396 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
3397 + const struct qm_fd *fd);
3398 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
3399 + const struct qm_fd *fd,
3400 + struct sk_buff *skb,
3401 + int *use_gro);
3402 +#ifndef CONFIG_FSL_DPAA_TS
3403 +bool dpa_skb_is_recyclable(struct sk_buff *skb);
3404 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
3405 + uint32_t min_size,
3406 + uint16_t min_offset,
3407 + unsigned char **new_buf_start);
3408 +#endif
3409 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
3410 + struct sk_buff *skb, struct qm_fd *fd,
3411 + int *count_ptr, int *offset);
3412 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
3413 + struct sk_buff *skb, struct qm_fd *fd);
3414 +int __cold __attribute__((nonnull))
3415 + _dpa_fq_free(struct device *dev, struct qman_fq *fq);
3416 +
3417 +/* Turn on HW checksum computation for this outgoing frame.
3418 + * If the current protocol is not something we support in this regard
3419 + * (or if the stack has already computed the SW checksum), we do nothing.
3420 + *
3421 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
3422 + * otherwise.
3423 + *
3424 + * Note that this function may modify the fd->cmd field and the skb data buffer
3425 + * (the Parse Results area).
3426 + */
3427 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
3428 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
3429 +
3430 +static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv,
3431 + struct qman_portal *portal)
3432 +{
3433 + /* In case of threaded ISR for RT enable kernel,
3434 + * in_irq() does not return appropriate value, so use
3435 + * in_serving_softirq to distinguish softirq or irq context.
3436 + */
3437 + if (unlikely(in_irq() || !in_serving_softirq())) {
3438 + /* Disable QMan IRQ and invoke NAPI */
3439 + int ret = qman_p_irqsource_remove(portal, QM_PIRQ_DQRI);
3440 + if (likely(!ret)) {
3441 + const struct qman_portal_config *pc =
3442 + qman_p_get_portal_config(portal);
3443 + struct dpa_napi_portal *np =
3444 + &percpu_priv->np[pc->index];
3445 +
3446 + np->p = portal;
3447 + napi_schedule(&np->napi);
3448 + percpu_priv->in_interrupt++;
3449 + return 1;
3450 + }
3451 + }
3452 + return 0;
3453 +}
3454 +
3455 +static inline ssize_t __const __must_check __attribute__((nonnull))
3456 +dpa_fd_length(const struct qm_fd *fd)
3457 +{
3458 + return fd->length20;
3459 +}
3460 +
3461 +static inline ssize_t __const __must_check __attribute__((nonnull))
3462 +dpa_fd_offset(const struct qm_fd *fd)
3463 +{
3464 + return fd->offset;
3465 +}
3466 +
3467 +static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl)
3468 +{
3469 + uint16_t headroom;
3470 + /* The frame headroom must accommodate:
3471 + * - the driver private data area
3472 + * - parse results, hash results, timestamp if selected
3473 + * - manip extra space
3474 + * If either hash results or time stamp are selected, both will
3475 + * be copied to/from the frame headroom, as TS is located between PR and
3476 + * HR in the IC and IC copy size has a granularity of 16bytes
3477 + * (see description of FMBM_RICP and FMBM_TICP registers in DPAARM)
3478 + *
3479 + * Also make sure the headroom is a multiple of data_align bytes
3480 + */
3481 + headroom = (uint16_t)(bl->priv_data_size +
3482 + (bl->parse_results ? DPA_PARSE_RESULTS_SIZE : 0) +
3483 + (bl->hash_results || bl->time_stamp ?
3484 + DPA_TIME_STAMP_SIZE + DPA_HASH_RESULTS_SIZE : 0) +
3485 + bl->manip_extra_space);
3486 +
3487 + return bl->data_align ? ALIGN(headroom, bl->data_align) : headroom;
3488 +}
3489 +
3490 +int fm_mac_dump_regs(struct mac_device *h_dev, char *buf, int n);
3491 +int fm_mac_dump_rx_stats(struct mac_device *h_dev, char *buf, int n);
3492 +int fm_mac_dump_tx_stats(struct mac_device *h_dev, char *buf, int n);
3493 +
3494 +void dpaa_eth_sysfs_remove(struct device *dev);
3495 +void dpaa_eth_sysfs_init(struct device *dev);
3496 +int dpaa_eth_poll(struct napi_struct *napi, int budget);
3497 +
3498 +void dpa_private_napi_del(struct net_device *net_dev);
3499 +
3500 +/* Equivalent to a memset(0), but works faster */
3501 +static inline void clear_fd(struct qm_fd *fd)
3502 +{
3503 + fd->opaque_addr = 0;
3504 + fd->opaque = 0;
3505 + fd->cmd = 0;
3506 +}
3507 +
3508 +static inline int _dpa_tx_fq_to_id(const struct dpa_priv_s *priv,
3509 + struct qman_fq *tx_fq)
3510 +{
3511 + int i;
3512 +
3513 + for (i = 0; i < DPAA_ETH_TX_QUEUES; i++)
3514 + if (priv->egress_fqs[i] == tx_fq)
3515 + return i;
3516 +
3517 + return -EINVAL;
3518 +}
3519 +
3520 +static inline int __hot dpa_xmit(struct dpa_priv_s *priv,
3521 + struct rtnl_link_stats64 *percpu_stats,
3522 + struct qm_fd *fd, struct qman_fq *egress_fq,
3523 + struct qman_fq *conf_fq)
3524 +{
3525 + int err, i;
3526 +
3527 + if (fd->bpid == 0xff)
3528 + fd->cmd |= qman_fq_fqid(conf_fq);
3529 +
3530 + /* Trace this Tx fd */
3531 + trace_dpa_tx_fd(priv->net_dev, egress_fq, fd);
3532 +
3533 + for (i = 0; i < 100000; i++) {
3534 + err = qman_enqueue(egress_fq, fd, 0);
3535 + if (err != -EBUSY)
3536 + break;
3537 + }
3538 +
3539 + if (unlikely(err < 0)) {
3540 + /* TODO differentiate b/w -EBUSY (EQCR full) and other codes? */
3541 + percpu_stats->tx_errors++;
3542 + percpu_stats->tx_fifo_errors++;
3543 + return err;
3544 + }
3545 +
3546 + percpu_stats->tx_packets++;
3547 + percpu_stats->tx_bytes += dpa_fd_length(fd);
3548 +
3549 + return 0;
3550 +}
3551 +
3552 +/* Use multiple WQs for FQ assignment:
3553 + * - Tx Confirmation queues go to WQ1.
3554 + * - Rx Default, Tx and PCD queues go to WQ3 (no differentiation between
3555 + * Rx and Tx traffic, or between Rx Default and Rx PCD frames).
3556 + * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance
3557 + * to be scheduled, in case there are many more FQs in WQ3).
3558 + * This ensures that Tx-confirmed buffers are timely released. In particular,
3559 + * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they
3560 + * are greatly outnumbered by other FQs in the system (usually PCDs), while
3561 + * dequeue scheduling is round-robin.
3562 + */
3563 +static inline void _dpa_assign_wq(struct dpa_fq *fq)
3564 +{
3565 + switch (fq->fq_type) {
3566 + case FQ_TYPE_TX_CONFIRM:
3567 + case FQ_TYPE_TX_CONF_MQ:
3568 + fq->wq = 1;
3569 + break;
3570 + case FQ_TYPE_RX_DEFAULT:
3571 + case FQ_TYPE_TX:
3572 + fq->wq = 3;
3573 + break;
3574 + case FQ_TYPE_RX_ERROR:
3575 + case FQ_TYPE_TX_ERROR:
3576 + case FQ_TYPE_RX_PCD_HI_PRIO:
3577 + fq->wq = 2;
3578 + break;
3579 + case FQ_TYPE_RX_PCD:
3580 + fq->wq = 5;
3581 + break;
3582 + default:
3583 + WARN(1, "Invalid FQ type %d for FQID %d!\n",
3584 + fq->fq_type, fq->fqid);
3585 + }
3586 +}
3587 +
3588 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
3589 +/* Use in lieu of skb_get_queue_mapping() */
3590 +#ifdef CONFIG_FMAN_PFC
3591 +#define dpa_get_queue_mapping(skb) \
3592 + (((skb)->priority < CONFIG_FMAN_PFC_COS_COUNT) ? \
3593 + ((skb)->priority * dpa_num_cpus + smp_processor_id()) : \
3594 + ((CONFIG_FMAN_PFC_COS_COUNT - 1) * \
3595 + dpa_num_cpus + smp_processor_id()));
3596 +
3597 +#else
3598 +#define dpa_get_queue_mapping(skb) \
3599 + raw_smp_processor_id()
3600 +#endif
3601 +#else
3602 +/* Use the queue selected by XPS */
3603 +#define dpa_get_queue_mapping(skb) \
3604 + skb_get_queue_mapping(skb)
3605 +#endif
3606 +
3607 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
3608 +struct ptp_priv_s {
3609 + struct device_node *node;
3610 + struct platform_device *of_dev;
3611 + struct ptp_clock *clock;
3612 + struct mac_device *mac_dev;
3613 +};
3614 +extern struct ptp_priv_s ptp_priv;
3615 +#endif
3616 +
3617 +static inline void _dpa_bp_free_pf(void *addr)
3618 +{
3619 + put_page(virt_to_head_page(addr));
3620 +}
3621 +
3622 +/* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue
3623 + * manifests itself at high traffic rates when frames cross 4K memory
3624 + * boundaries or when they are not aligned to 16 bytes; For the moment, we
3625 + * use a SW workaround to avoid frames larger than 4K or that exceed 4K
3626 + * alignments and to realign the frames to 16 bytes.
3627 + */
3628 +
3629 +#ifndef CONFIG_PPC
3630 +extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */
3631 +#define NONREC_MARK 0x01
3632 +#define HAS_DMA_ISSUE(start, size) \
3633 + (((uintptr_t)(start) + (size)) > \
3634 + (((uintptr_t)(start) + 0x1000) & ~0xFFF))
3635 +#endif /* !CONFIG_PPC */
3636 +
3637 +#endif /* __DPA_H */
3638 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
3639 new file mode 100644
3640 index 00000000..507e77c3
3641 --- /dev/null
3642 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
3643 @@ -0,0 +1,205 @@
3644 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3645 + *
3646 + * Redistribution and use in source and binary forms, with or without
3647 + * modification, are permitted provided that the following conditions are met:
3648 + * * Redistributions of source code must retain the above copyright
3649 + * notice, this list of conditions and the following disclaimer.
3650 + * * Redistributions in binary form must reproduce the above copyright
3651 + * notice, this list of conditions and the following disclaimer in the
3652 + * documentation and/or other materials provided with the distribution.
3653 + * * Neither the name of Freescale Semiconductor nor the
3654 + * names of its contributors may be used to endorse or promote products
3655 + * derived from this software without specific prior written permission.
3656 + *
3657 + *
3658 + * ALTERNATIVELY, this software may be distributed under the terms of the
3659 + * GNU General Public License ("GPL") as published by the Free Software
3660 + * Foundation, either version 2 of that License or (at your option) any
3661 + * later version.
3662 + *
3663 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3664 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3665 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3666 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3667 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3668 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3669 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3670 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3671 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3672 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3673 + */
3674 +
3675 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3676 +#define pr_fmt(fmt) \
3677 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
3678 + KBUILD_BASENAME".c", __LINE__, __func__
3679 +#else
3680 +#define pr_fmt(fmt) \
3681 + KBUILD_MODNAME ": " fmt
3682 +#endif
3683 +
3684 +#include <linux/init.h>
3685 +#include <linux/module.h>
3686 +#include <linux/io.h>
3687 +#include <linux/of_platform.h>
3688 +#include <linux/of_net.h>
3689 +#include <linux/etherdevice.h>
3690 +#include <linux/kthread.h>
3691 +#include <linux/percpu.h>
3692 +#include <linux/highmem.h>
3693 +#include <linux/sort.h>
3694 +#include <linux/fsl_qman.h>
3695 +#include "dpaa_eth.h"
3696 +#include "dpaa_eth_common.h"
3697 +#include "dpaa_eth_base.h"
3698 +
3699 +#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:"
3700 +
3701 +MODULE_LICENSE("Dual BSD/GPL");
3702 +
3703 +uint8_t advanced_debug = -1;
3704 +module_param(advanced_debug, byte, S_IRUGO);
3705 +MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level");
3706 +EXPORT_SYMBOL(advanced_debug);
3707 +
3708 +static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
3709 +{
3710 + return ((struct dpa_bp *)dpa_bp0)->size -
3711 + ((struct dpa_bp *)dpa_bp1)->size;
3712 +}
3713 +
3714 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3715 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
3716 +{
3717 + int i, lenp, na, ns, err;
3718 + struct device *dev;
3719 + struct device_node *dev_node;
3720 + const __be32 *bpool_cfg;
3721 + struct dpa_bp *dpa_bp;
3722 + u32 bpid;
3723 +
3724 + dev = &_of_dev->dev;
3725 +
3726 + *count = of_count_phandle_with_args(dev->of_node,
3727 + "fsl,bman-buffer-pools", NULL);
3728 + if (*count < 1) {
3729 + dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n");
3730 + return ERR_PTR(-EINVAL);
3731 + }
3732 +
3733 + dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL);
3734 + if (dpa_bp == NULL) {
3735 + dev_err(dev, "devm_kzalloc() failed\n");
3736 + return ERR_PTR(-ENOMEM);
3737 + }
3738 +
3739 + dev_node = of_find_node_by_path("/");
3740 + if (unlikely(dev_node == NULL)) {
3741 + dev_err(dev, "of_find_node_by_path(/) failed\n");
3742 + return ERR_PTR(-EINVAL);
3743 + }
3744 +
3745 + na = of_n_addr_cells(dev_node);
3746 + ns = of_n_size_cells(dev_node);
3747 +
3748 + for (i = 0; i < *count; i++) {
3749 + of_node_put(dev_node);
3750 +
3751 + dev_node = of_parse_phandle(dev->of_node,
3752 + "fsl,bman-buffer-pools", i);
3753 + if (dev_node == NULL) {
3754 + dev_err(dev, "of_find_node_by_phandle() failed\n");
3755 + return ERR_PTR(-EFAULT);
3756 + }
3757 +
3758 + if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) {
3759 + dev_err(dev,
3760 + "!of_device_is_compatible(%s, fsl,bpool)\n",
3761 + dev_node->full_name);
3762 + dpa_bp = ERR_PTR(-EINVAL);
3763 + goto _return_of_node_put;
3764 + }
3765 +
3766 + err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
3767 + if (err) {
3768 + dev_err(dev, "Cannot find buffer pool ID in the device tree\n");
3769 + dpa_bp = ERR_PTR(-EINVAL);
3770 + goto _return_of_node_put;
3771 + }
3772 + dpa_bp[i].bpid = (uint8_t)bpid;
3773 +
3774 + bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
3775 + &lenp);
3776 + if (bpool_cfg && (lenp == (2 * ns + na) * sizeof(*bpool_cfg))) {
3777 + const uint32_t *seed_pool;
3778 +
3779 + dpa_bp[i].config_count =
3780 + (int)of_read_number(bpool_cfg, ns);
3781 + dpa_bp[i].size =
3782 + (size_t)of_read_number(bpool_cfg + ns, ns);
3783 + dpa_bp[i].paddr =
3784 + of_read_number(bpool_cfg + 2 * ns, na);
3785 +
3786 + seed_pool = of_get_property(dev_node,
3787 + "fsl,bpool-ethernet-seeds", &lenp);
3788 + dpa_bp[i].seed_pool = !!seed_pool;
3789 +
3790 + } else {
3791 + dev_err(dev,
3792 + "Missing/invalid fsl,bpool-ethernet-cfg device tree entry for node %s\n",
3793 + dev_node->full_name);
3794 + dpa_bp = ERR_PTR(-EINVAL);
3795 + goto _return_of_node_put;
3796 + }
3797 + }
3798 +
3799 + sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL);
3800 +
3801 + return dpa_bp;
3802 +
3803 +_return_of_node_put:
3804 + if (dev_node)
3805 + of_node_put(dev_node);
3806 +
3807 + return dpa_bp;
3808 +}
3809 +EXPORT_SYMBOL(dpa_bp_probe);
3810 +
3811 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3812 + size_t count)
3813 +{
3814 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3815 + int i;
3816 +
3817 + priv->dpa_bp = dpa_bp;
3818 + priv->bp_count = count;
3819 +
3820 + for (i = 0; i < count; i++) {
3821 + int err;
3822 + err = dpa_bp_alloc(&dpa_bp[i]);
3823 + if (err < 0) {
3824 + dpa_bp_free(priv);
3825 + priv->dpa_bp = NULL;
3826 + return err;
3827 + }
3828 + }
3829 +
3830 + return 0;
3831 +}
3832 +EXPORT_SYMBOL(dpa_bp_create);
3833 +
3834 +static int __init __cold dpa_advanced_load(void)
3835 +{
3836 + pr_info(DPA_DESCRIPTION "\n");
3837 +
3838 + return 0;
3839 +}
3840 +module_init(dpa_advanced_load);
3841 +
3842 +static void __exit __cold dpa_advanced_unload(void)
3843 +{
3844 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
3845 + KBUILD_BASENAME".c", __func__);
3846 +
3847 +}
3848 +module_exit(dpa_advanced_unload);
3849 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
3850 new file mode 100644
3851 index 00000000..6ec68c3c
3852 --- /dev/null
3853 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
3854 @@ -0,0 +1,49 @@
3855 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3856 + *
3857 + * Redistribution and use in source and binary forms, with or without
3858 + * modification, are permitted provided that the following conditions are met:
3859 + * * Redistributions of source code must retain the above copyright
3860 + * notice, this list of conditions and the following disclaimer.
3861 + * * Redistributions in binary form must reproduce the above copyright
3862 + * notice, this list of conditions and the following disclaimer in the
3863 + * documentation and/or other materials provided with the distribution.
3864 + * * Neither the name of Freescale Semiconductor nor the
3865 + * names of its contributors may be used to endorse or promote products
3866 + * derived from this software without specific prior written permission.
3867 + *
3868 + *
3869 + * ALTERNATIVELY, this software may be distributed under the terms of the
3870 + * GNU General Public License ("GPL") as published by the Free Software
3871 + * Foundation, either version 2 of that License or (at your option) any
3872 + * later version.
3873 + *
3874 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3875 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3876 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3877 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3878 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3879 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3880 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3881 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3882 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3883 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3884 + */
3885 +
3886 +#ifndef __DPAA_ETH_BASE_H
3887 +#define __DPAA_ETH_BASE_H
3888 +
3889 +#include <linux/etherdevice.h> /* struct net_device */
3890 +#include <linux/fsl_bman.h> /* struct bm_buffer */
3891 +#include <linux/of_platform.h> /* struct platform_device */
3892 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
3893 +
3894 +extern uint8_t advanced_debug;
3895 +extern const struct dpa_fq_cbs_t shared_fq_cbs;
3896 +extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
3897 +
3898 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3899 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count);
3900 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3901 + size_t count);
3902 +
3903 +#endif /* __DPAA_ETH_BASE_H */
3904 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
3905 new file mode 100644
3906 index 00000000..cac613b7
3907 --- /dev/null
3908 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
3909 @@ -0,0 +1,1992 @@
3910 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
3911 + *
3912 + * Redistribution and use in source and binary forms, with or without
3913 + * modification, are permitted provided that the following conditions are met:
3914 + * * Redistributions of source code must retain the above copyright
3915 + * notice, this list of conditions and the following disclaimer.
3916 + * * Redistributions in binary form must reproduce the above copyright
3917 + * notice, this list of conditions and the following disclaimer in the
3918 + * documentation and/or other materials provided with the distribution.
3919 + * * Neither the name of Freescale Semiconductor nor the
3920 + * names of its contributors may be used to endorse or promote products
3921 + * derived from this software without specific prior written permission.
3922 + *
3923 + *
3924 + * ALTERNATIVELY, this software may be distributed under the terms of the
3925 + * GNU General Public License ("GPL") as published by the Free Software
3926 + * Foundation, either version 2 of that License or (at your option) any
3927 + * later version.
3928 + *
3929 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3930 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3931 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3932 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3933 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3934 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3935 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3936 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3937 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3938 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3939 + */
3940 +
3941 +#include <linux/init.h>
3942 +#include "dpaa_eth_ceetm.h"
3943 +
3944 +#define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc"
3945 +
3946 +const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = {
3947 + [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) },
3948 + [TCA_CEETM_QOPS] = { .len = sizeof(struct tc_ceetm_qopt) },
3949 +};
3950 +
3951 +struct Qdisc_ops ceetm_qdisc_ops;
3952 +
3953 +/* Obtain the DCP and the SP ids from the FMan port */
3954 +static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id,
3955 + unsigned int *sp_id)
3956 +{
3957 + uint32_t channel;
3958 + t_LnxWrpFmPortDev *port_dev;
3959 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
3960 + struct mac_device *mac_dev = dpa_priv->mac_dev;
3961 +
3962 + port_dev = (t_LnxWrpFmPortDev *)mac_dev->port_dev[TX];
3963 + channel = port_dev->txCh;
3964 +
3965 + *sp_id = channel & CHANNEL_SP_MASK;
3966 + pr_debug(KBUILD_BASENAME " : FM sub-portal ID %d\n", *sp_id);
3967 +
3968 + if (channel < DCP0_MAX_CHANNEL) {
3969 + *dcp_id = qm_dc_portal_fman0;
3970 + pr_debug(KBUILD_BASENAME " : DCP ID 0\n");
3971 + } else {
3972 + *dcp_id = qm_dc_portal_fman1;
3973 + pr_debug(KBUILD_BASENAME " : DCP ID 1\n");
3974 + }
3975 +}
3976 +
3977 +/* Enqueue Rejection Notification callback */
3978 +static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq,
3979 + const struct qm_mr_entry *msg)
3980 +{
3981 + struct net_device *net_dev;
3982 + struct ceetm_class *cls;
3983 + struct ceetm_class_stats *cstats = NULL;
3984 + const struct dpa_priv_s *dpa_priv;
3985 + struct dpa_percpu_priv_s *dpa_percpu_priv;
3986 + struct sk_buff *skb;
3987 + struct qm_fd fd = msg->ern.fd;
3988 +
3989 + net_dev = ((struct ceetm_fq *)fq)->net_dev;
3990 + dpa_priv = netdev_priv(net_dev);
3991 + dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv);
3992 +
3993 + /* Increment DPA counters */
3994 + dpa_percpu_priv->stats.tx_dropped++;
3995 + dpa_percpu_priv->stats.tx_fifo_errors++;
3996 +
3997 + /* Increment CEETM counters */
3998 + cls = ((struct ceetm_fq *)fq)->ceetm_cls;
3999 + switch (cls->type) {
4000 + case CEETM_PRIO:
4001 + cstats = this_cpu_ptr(cls->prio.cstats);
4002 + break;
4003 + case CEETM_WBFS:
4004 + cstats = this_cpu_ptr(cls->wbfs.cstats);
4005 + break;
4006 + }
4007 +
4008 + if (cstats)
4009 + cstats->ern_drop_count++;
4010 +
4011 + if (fd.bpid != 0xff) {
4012 + dpa_fd_release(net_dev, &fd);
4013 + return;
4014 + }
4015 +
4016 + skb = _dpa_cleanup_tx_fd(dpa_priv, &fd);
4017 + dev_kfree_skb_any(skb);
4018 +}
4019 +
4020 +/* Congestion State Change Notification callback */
4021 +static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested)
4022 +{
4023 + struct ceetm_fq *ceetm_fq = (struct ceetm_fq *)cb_ctx;
4024 + struct dpa_priv_s *dpa_priv = netdev_priv(ceetm_fq->net_dev);
4025 + struct ceetm_class *cls = ceetm_fq->ceetm_cls;
4026 + struct ceetm_class_stats *cstats = NULL;
4027 +
4028 + switch (cls->type) {
4029 + case CEETM_PRIO:
4030 + cstats = this_cpu_ptr(cls->prio.cstats);
4031 + break;
4032 + case CEETM_WBFS:
4033 + cstats = this_cpu_ptr(cls->wbfs.cstats);
4034 + break;
4035 + }
4036 +
4037 + if (congested) {
4038 + dpa_priv->cgr_data.congestion_start_jiffies = jiffies;
4039 + netif_tx_stop_all_queues(dpa_priv->net_dev);
4040 + dpa_priv->cgr_data.cgr_congested_count++;
4041 + if (cstats)
4042 + cstats->congested_count++;
4043 + } else {
4044 + dpa_priv->cgr_data.congested_jiffies +=
4045 + (jiffies - dpa_priv->cgr_data.congestion_start_jiffies);
4046 + netif_tx_wake_all_queues(dpa_priv->net_dev);
4047 + }
4048 +}
4049 +
4050 +/* Allocate a ceetm fq */
4051 +static int ceetm_alloc_fq(struct ceetm_fq **fq, struct net_device *dev,
4052 + struct ceetm_class *cls)
4053 +{
4054 + *fq = kzalloc(sizeof(**fq), GFP_KERNEL);
4055 + if (!*fq)
4056 + return -ENOMEM;
4057 +
4058 + (*fq)->net_dev = dev;
4059 + (*fq)->ceetm_cls = cls;
4060 + return 0;
4061 +}
4062 +
4063 +/* Configure a ceetm Class Congestion Group */
4064 +static int ceetm_config_ccg(struct qm_ceetm_ccg **ccg,
4065 + struct qm_ceetm_channel *channel, unsigned int id,
4066 + struct ceetm_fq *fq, struct dpa_priv_s *dpa_priv)
4067 +{
4068 + int err;
4069 + u32 cs_th;
4070 + u16 ccg_mask;
4071 + struct qm_ceetm_ccg_params ccg_params;
4072 +
4073 + err = qman_ceetm_ccg_claim(ccg, channel, id, ceetm_cscn, fq);
4074 + if (err)
4075 + return err;
4076 +
4077 + /* Configure the count mode (frames/bytes), enable congestion state
4078 + * notifications, configure the congestion entry and exit thresholds,
4079 + * enable tail-drop, configure the tail-drop mode, and set the
4080 + * overhead accounting limit
4081 + */
4082 + ccg_mask = QM_CCGR_WE_MODE |
4083 + QM_CCGR_WE_CSCN_EN |
4084 + QM_CCGR_WE_CS_THRES_IN | QM_CCGR_WE_CS_THRES_OUT |
4085 + QM_CCGR_WE_TD_EN | QM_CCGR_WE_TD_MODE |
4086 + QM_CCGR_WE_OAL;
4087 +
4088 + ccg_params.mode = 0; /* count bytes */
4089 + ccg_params.cscn_en = 1; /* generate notifications */
4090 + ccg_params.td_en = 1; /* enable tail-drop */
4091 + ccg_params.td_mode = 0; /* tail-drop on congestion state */
4092 + ccg_params.oal = (signed char)(min(sizeof(struct sk_buff) +
4093 + dpa_priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
4094 +
4095 + /* Set the congestion state thresholds according to the link speed */
4096 + if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
4097 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
4098 + else
4099 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
4100 +
4101 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1);
4102 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out,
4103 + cs_th * CEETM_CCGR_RATIO, 1);
4104 +
4105 + err = qman_ceetm_ccg_set(*ccg, ccg_mask, &ccg_params);
4106 + if (err)
4107 + return err;
4108 +
4109 + return 0;
4110 +}
4111 +
4112 +/* Configure a ceetm Logical Frame Queue */
4113 +static int ceetm_config_lfq(struct qm_ceetm_cq *cq, struct ceetm_fq *fq,
4114 + struct qm_ceetm_lfq **lfq)
4115 +{
4116 + int err;
4117 + u64 context_a;
4118 + u32 context_b;
4119 +
4120 + err = qman_ceetm_lfq_claim(lfq, cq);
4121 + if (err)
4122 + return err;
4123 +
4124 + /* Get the former contexts in order to preserve context B */
4125 + err = qman_ceetm_lfq_get_context(*lfq, &context_a, &context_b);
4126 + if (err)
4127 + return err;
4128 +
4129 + context_a = CEETM_CONTEXT_A;
4130 + err = qman_ceetm_lfq_set_context(*lfq, context_a, context_b);
4131 + if (err)
4132 + return err;
4133 +
4134 + (*lfq)->ern = ceetm_ern;
4135 +
4136 + err = qman_ceetm_create_fq(*lfq, &fq->fq);
4137 + if (err)
4138 + return err;
4139 +
4140 + return 0;
4141 +}
4142 +
4143 +/* Configure a prio ceetm class */
4144 +static int ceetm_config_prio_cls(struct ceetm_class *cls,
4145 + struct net_device *dev,
4146 + struct qm_ceetm_channel *channel,
4147 + unsigned int id)
4148 +{
4149 + int err;
4150 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4151 +
4152 + err = ceetm_alloc_fq(&cls->prio.fq, dev, cls);
4153 + if (err)
4154 + return err;
4155 +
4156 + /* Claim and configure the CCG */
4157 + err = ceetm_config_ccg(&cls->prio.ccg, channel, id, cls->prio.fq,
4158 + dpa_priv);
4159 + if (err)
4160 + return err;
4161 +
4162 + /* Claim and configure the CQ */
4163 + err = qman_ceetm_cq_claim(&cls->prio.cq, channel, id, cls->prio.ccg);
4164 + if (err)
4165 + return err;
4166 +
4167 + if (cls->shaped) {
4168 + err = qman_ceetm_channel_set_cq_cr_eligibility(channel, id, 1);
4169 + if (err)
4170 + return err;
4171 +
4172 + err = qman_ceetm_channel_set_cq_er_eligibility(channel, id, 1);
4173 + if (err)
4174 + return err;
4175 + }
4176 +
4177 + /* Claim and configure a LFQ */
4178 + err = ceetm_config_lfq(cls->prio.cq, cls->prio.fq, &cls->prio.lfq);
4179 + if (err)
4180 + return err;
4181 +
4182 + return 0;
4183 +}
4184 +
4185 +/* Configure a wbfs ceetm class */
4186 +static int ceetm_config_wbfs_cls(struct ceetm_class *cls,
4187 + struct net_device *dev,
4188 + struct qm_ceetm_channel *channel,
4189 + unsigned int id, int type)
4190 +{
4191 + int err;
4192 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4193 +
4194 + err = ceetm_alloc_fq(&cls->wbfs.fq, dev, cls);
4195 + if (err)
4196 + return err;
4197 +
4198 + /* Claim and configure the CCG */
4199 + err = ceetm_config_ccg(&cls->wbfs.ccg, channel, id, cls->wbfs.fq,
4200 + dpa_priv);
4201 + if (err)
4202 + return err;
4203 +
4204 + /* Claim and configure the CQ */
4205 + if (type == WBFS_GRP_B)
4206 + err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, channel, id,
4207 + cls->wbfs.ccg);
4208 + else
4209 + err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, channel, id,
4210 + cls->wbfs.ccg);
4211 + if (err)
4212 + return err;
4213 +
4214 + /* Configure the CQ weight: real number multiplied by 100 to get rid
4215 + * of the fraction
4216 + */
4217 + err = qman_ceetm_set_queue_weight_in_ratio(cls->wbfs.cq,
4218 + cls->wbfs.weight * 100);
4219 + if (err)
4220 + return err;
4221 +
4222 + /* Claim and configure a LFQ */
4223 + err = ceetm_config_lfq(cls->wbfs.cq, cls->wbfs.fq, &cls->wbfs.lfq);
4224 + if (err)
4225 + return err;
4226 +
4227 + return 0;
4228 +}
4229 +
4230 +/* Find class in qdisc hash table using given handle */
4231 +static inline struct ceetm_class *ceetm_find(u32 handle, struct Qdisc *sch)
4232 +{
4233 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4234 + struct Qdisc_class_common *clc;
4235 +
4236 + pr_debug(KBUILD_BASENAME " : %s : find class %X in qdisc %X\n",
4237 + __func__, handle, sch->handle);
4238 +
4239 + clc = qdisc_class_find(&priv->clhash, handle);
4240 + return clc ? container_of(clc, struct ceetm_class, common) : NULL;
4241 +}
4242 +
4243 +/* Insert a class in the qdisc's class hash */
4244 +static void ceetm_link_class(struct Qdisc *sch,
4245 + struct Qdisc_class_hash *clhash,
4246 + struct Qdisc_class_common *common)
4247 +{
4248 + sch_tree_lock(sch);
4249 + qdisc_class_hash_insert(clhash, common);
4250 + sch_tree_unlock(sch);
4251 + qdisc_class_hash_grow(sch, clhash);
4252 +}
4253 +
4254 +/* Destroy a ceetm class */
4255 +static void ceetm_cls_destroy(struct Qdisc *sch, struct ceetm_class *cl)
4256 +{
4257 + if (!cl)
4258 + return;
4259 +
4260 + pr_debug(KBUILD_BASENAME " : %s : destroy class %X from under %X\n",
4261 + __func__, cl->common.classid, sch->handle);
4262 +
4263 + switch (cl->type) {
4264 + case CEETM_ROOT:
4265 + if (cl->root.child) {
4266 + qdisc_destroy(cl->root.child);
4267 + cl->root.child = NULL;
4268 + }
4269 +
4270 + if (cl->root.ch && qman_ceetm_channel_release(cl->root.ch))
4271 + pr_err(KBUILD_BASENAME
4272 + " : %s : error releasing the channel %d\n",
4273 + __func__, cl->root.ch->idx);
4274 +
4275 + break;
4276 +
4277 + case CEETM_PRIO:
4278 + if (cl->prio.child) {
4279 + qdisc_destroy(cl->prio.child);
4280 + cl->prio.child = NULL;
4281 + }
4282 +
4283 + if (cl->prio.lfq && qman_ceetm_lfq_release(cl->prio.lfq))
4284 + pr_err(KBUILD_BASENAME
4285 + " : %s : error releasing the LFQ %d\n",
4286 + __func__, cl->prio.lfq->idx);
4287 +
4288 + if (cl->prio.cq && qman_ceetm_cq_release(cl->prio.cq))
4289 + pr_err(KBUILD_BASENAME
4290 + " : %s : error releasing the CQ %d\n",
4291 + __func__, cl->prio.cq->idx);
4292 +
4293 + if (cl->prio.ccg && qman_ceetm_ccg_release(cl->prio.ccg))
4294 + pr_err(KBUILD_BASENAME
4295 + " : %s : error releasing the CCG %d\n",
4296 + __func__, cl->prio.ccg->idx);
4297 +
4298 + kfree(cl->prio.fq);
4299 +
4300 + if (cl->prio.cstats)
4301 + free_percpu(cl->prio.cstats);
4302 +
4303 + break;
4304 +
4305 + case CEETM_WBFS:
4306 + if (cl->wbfs.lfq && qman_ceetm_lfq_release(cl->wbfs.lfq))
4307 + pr_err(KBUILD_BASENAME
4308 + " : %s : error releasing the LFQ %d\n",
4309 + __func__, cl->wbfs.lfq->idx);
4310 +
4311 + if (cl->wbfs.cq && qman_ceetm_cq_release(cl->wbfs.cq))
4312 + pr_err(KBUILD_BASENAME
4313 + " : %s : error releasing the CQ %d\n",
4314 + __func__, cl->wbfs.cq->idx);
4315 +
4316 + if (cl->wbfs.ccg && qman_ceetm_ccg_release(cl->wbfs.ccg))
4317 + pr_err(KBUILD_BASENAME
4318 + " : %s : error releasing the CCG %d\n",
4319 + __func__, cl->wbfs.ccg->idx);
4320 +
4321 + kfree(cl->wbfs.fq);
4322 +
4323 + if (cl->wbfs.cstats)
4324 + free_percpu(cl->wbfs.cstats);
4325 + }
4326 +
4327 + tcf_destroy_chain(&cl->filter_list);
4328 + kfree(cl);
4329 +}
4330 +
4331 +/* Destroy a ceetm qdisc */
4332 +static void ceetm_destroy(struct Qdisc *sch)
4333 +{
4334 + unsigned int ntx, i;
4335 + struct hlist_node *next;
4336 + struct ceetm_class *cl;
4337 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4338 + struct net_device *dev = qdisc_dev(sch);
4339 +
4340 + pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n",
4341 + __func__, sch->handle);
4342 +
4343 + /* All filters need to be removed before destroying the classes */
4344 + tcf_destroy_chain(&priv->filter_list);
4345 +
4346 + for (i = 0; i < priv->clhash.hashsize; i++) {
4347 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode)
4348 + tcf_destroy_chain(&cl->filter_list);
4349 + }
4350 +
4351 + for (i = 0; i < priv->clhash.hashsize; i++) {
4352 + hlist_for_each_entry_safe(cl, next, &priv->clhash.hash[i],
4353 + common.hnode)
4354 + ceetm_cls_destroy(sch, cl);
4355 + }
4356 +
4357 + qdisc_class_hash_destroy(&priv->clhash);
4358 +
4359 + switch (priv->type) {
4360 + case CEETM_ROOT:
4361 + dpa_disable_ceetm(dev);
4362 +
4363 + if (priv->root.lni && qman_ceetm_lni_release(priv->root.lni))
4364 + pr_err(KBUILD_BASENAME
4365 + " : %s : error releasing the LNI %d\n",
4366 + __func__, priv->root.lni->idx);
4367 +
4368 + if (priv->root.sp && qman_ceetm_sp_release(priv->root.sp))
4369 + pr_err(KBUILD_BASENAME
4370 + " : %s : error releasing the SP %d\n",
4371 + __func__, priv->root.sp->idx);
4372 +
4373 + if (priv->root.qstats)
4374 + free_percpu(priv->root.qstats);
4375 +
4376 + if (!priv->root.qdiscs)
4377 + break;
4378 +
4379 + /* Remove the pfifo qdiscs */
4380 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++)
4381 + if (priv->root.qdiscs[ntx])
4382 + qdisc_destroy(priv->root.qdiscs[ntx]);
4383 +
4384 + kfree(priv->root.qdiscs);
4385 + break;
4386 +
4387 + case CEETM_PRIO:
4388 + if (priv->prio.parent)
4389 + priv->prio.parent->root.child = NULL;
4390 + break;
4391 +
4392 + case CEETM_WBFS:
4393 + if (priv->wbfs.parent)
4394 + priv->wbfs.parent->prio.child = NULL;
4395 + break;
4396 + }
4397 +}
4398 +
4399 +static int ceetm_dump(struct Qdisc *sch, struct sk_buff *skb)
4400 +{
4401 + struct Qdisc *qdisc;
4402 + unsigned int ntx, i;
4403 + struct nlattr *nest;
4404 + struct tc_ceetm_qopt qopt;
4405 + struct ceetm_qdisc_stats *qstats;
4406 + struct net_device *dev = qdisc_dev(sch);
4407 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4408 +
4409 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4410 +
4411 + sch_tree_lock(sch);
4412 + memset(&qopt, 0, sizeof(qopt));
4413 + qopt.type = priv->type;
4414 + qopt.shaped = priv->shaped;
4415 +
4416 + switch (priv->type) {
4417 + case CEETM_ROOT:
4418 + /* Gather statistics from the underlying pfifo qdiscs */
4419 + sch->q.qlen = 0;
4420 + memset(&sch->bstats, 0, sizeof(sch->bstats));
4421 + memset(&sch->qstats, 0, sizeof(sch->qstats));
4422 +
4423 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
4424 + qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping;
4425 + sch->q.qlen += qdisc->q.qlen;
4426 + sch->bstats.bytes += qdisc->bstats.bytes;
4427 + sch->bstats.packets += qdisc->bstats.packets;
4428 + sch->qstats.qlen += qdisc->qstats.qlen;
4429 + sch->qstats.backlog += qdisc->qstats.backlog;
4430 + sch->qstats.drops += qdisc->qstats.drops;
4431 + sch->qstats.requeues += qdisc->qstats.requeues;
4432 + sch->qstats.overlimits += qdisc->qstats.overlimits;
4433 + }
4434 +
4435 + for_each_online_cpu(i) {
4436 + qstats = per_cpu_ptr(priv->root.qstats, i);
4437 + sch->qstats.drops += qstats->drops;
4438 + }
4439 +
4440 + qopt.rate = priv->root.rate;
4441 + qopt.ceil = priv->root.ceil;
4442 + qopt.overhead = priv->root.overhead;
4443 + break;
4444 +
4445 + case CEETM_PRIO:
4446 + qopt.qcount = priv->prio.qcount;
4447 + break;
4448 +
4449 + case CEETM_WBFS:
4450 + qopt.qcount = priv->wbfs.qcount;
4451 + qopt.cr = priv->wbfs.cr;
4452 + qopt.er = priv->wbfs.er;
4453 + break;
4454 +
4455 + default:
4456 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
4457 + sch_tree_unlock(sch);
4458 + return -EINVAL;
4459 + }
4460 +
4461 + nest = nla_nest_start(skb, TCA_OPTIONS);
4462 + if (!nest)
4463 + goto nla_put_failure;
4464 + if (nla_put(skb, TCA_CEETM_QOPS, sizeof(qopt), &qopt))
4465 + goto nla_put_failure;
4466 + nla_nest_end(skb, nest);
4467 +
4468 + sch_tree_unlock(sch);
4469 + return skb->len;
4470 +
4471 +nla_put_failure:
4472 + sch_tree_unlock(sch);
4473 + nla_nest_cancel(skb, nest);
4474 + return -EMSGSIZE;
4475 +}
4476 +
4477 +/* Configure a root ceetm qdisc */
4478 +static int ceetm_init_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
4479 + struct tc_ceetm_qopt *qopt)
4480 +{
4481 + struct netdev_queue *dev_queue;
4482 + struct Qdisc *qdisc;
4483 + enum qm_dc_portal dcp_id;
4484 + unsigned int i, sp_id, parent_id;
4485 + int err;
4486 + u64 bps;
4487 + struct qm_ceetm_sp *sp;
4488 + struct qm_ceetm_lni *lni;
4489 + struct net_device *dev = qdisc_dev(sch);
4490 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4491 + struct mac_device *mac_dev = dpa_priv->mac_dev;
4492 +
4493 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4494 +
4495 + /* Validate inputs */
4496 + if (sch->parent != TC_H_ROOT) {
4497 + pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n");
4498 + tcf_destroy_chain(&priv->filter_list);
4499 + qdisc_class_hash_destroy(&priv->clhash);
4500 + return -EINVAL;
4501 + }
4502 +
4503 + if (!mac_dev) {
4504 + pr_err("CEETM: the interface is lacking a mac\n");
4505 + err = -EINVAL;
4506 + goto err_init_root;
4507 + }
4508 +
4509 + /* pre-allocate underlying pfifo qdiscs */
4510 + priv->root.qdiscs = kcalloc(dev->num_tx_queues,
4511 + sizeof(priv->root.qdiscs[0]),
4512 + GFP_KERNEL);
4513 + if (!priv->root.qdiscs) {
4514 + err = -ENOMEM;
4515 + goto err_init_root;
4516 + }
4517 +
4518 + for (i = 0; i < dev->num_tx_queues; i++) {
4519 + dev_queue = netdev_get_tx_queue(dev, i);
4520 + parent_id = TC_H_MAKE(TC_H_MAJ(sch->handle),
4521 + TC_H_MIN(i + PFIFO_MIN_OFFSET));
4522 +
4523 + qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
4524 + parent_id);
4525 + if (!qdisc) {
4526 + err = -ENOMEM;
4527 + goto err_init_root;
4528 + }
4529 +
4530 + priv->root.qdiscs[i] = qdisc;
4531 + qdisc->flags |= TCQ_F_ONETXQUEUE;
4532 + }
4533 +
4534 + sch->flags |= TCQ_F_MQROOT;
4535 +
4536 + priv->root.qstats = alloc_percpu(struct ceetm_qdisc_stats);
4537 + if (!priv->root.qstats) {
4538 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4539 + __func__);
4540 + err = -ENOMEM;
4541 + goto err_init_root;
4542 + }
4543 +
4544 + priv->shaped = qopt->shaped;
4545 + priv->root.rate = qopt->rate;
4546 + priv->root.ceil = qopt->ceil;
4547 + priv->root.overhead = qopt->overhead;
4548 +
4549 + /* Claim the SP */
4550 + get_dcp_and_sp(dev, &dcp_id, &sp_id);
4551 + err = qman_ceetm_sp_claim(&sp, dcp_id, sp_id);
4552 + if (err) {
4553 + pr_err(KBUILD_BASENAME " : %s : failed to claim the SP\n",
4554 + __func__);
4555 + goto err_init_root;
4556 + }
4557 +
4558 + priv->root.sp = sp;
4559 +
4560 + /* Claim the LNI - will use the same id as the SP id since SPs 0-7
4561 + * are connected to the TX FMan ports
4562 + */
4563 + err = qman_ceetm_lni_claim(&lni, dcp_id, sp_id);
4564 + if (err) {
4565 + pr_err(KBUILD_BASENAME " : %s : failed to claim the LNI\n",
4566 + __func__);
4567 + goto err_init_root;
4568 + }
4569 +
4570 + priv->root.lni = lni;
4571 +
4572 + err = qman_ceetm_sp_set_lni(sp, lni);
4573 + if (err) {
4574 + pr_err(KBUILD_BASENAME " : %s : failed to link the SP and LNI\n",
4575 + __func__);
4576 + goto err_init_root;
4577 + }
4578 +
4579 + lni->sp = sp;
4580 +
4581 + /* Configure the LNI shaper */
4582 + if (priv->shaped) {
4583 + err = qman_ceetm_lni_enable_shaper(lni, 1, priv->root.overhead);
4584 + if (err) {
4585 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4586 + __func__);
4587 + goto err_init_root;
4588 + }
4589 +
4590 + bps = priv->root.rate << 3; /* Bps -> bps */
4591 + err = qman_ceetm_lni_set_commit_rate_bps(lni, bps, dev->mtu);
4592 + if (err) {
4593 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4594 + __func__);
4595 + goto err_init_root;
4596 + }
4597 +
4598 + bps = priv->root.ceil << 3; /* Bps -> bps */
4599 + err = qman_ceetm_lni_set_excess_rate_bps(lni, bps, dev->mtu);
4600 + if (err) {
4601 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4602 + __func__);
4603 + goto err_init_root;
4604 + }
4605 + }
4606 +
4607 + /* TODO default configuration */
4608 +
4609 + dpa_enable_ceetm(dev);
4610 + return 0;
4611 +
4612 +err_init_root:
4613 + ceetm_destroy(sch);
4614 + return err;
4615 +}
4616 +
4617 +/* Configure a prio ceetm qdisc */
4618 +static int ceetm_init_prio(struct Qdisc *sch, struct ceetm_qdisc *priv,
4619 + struct tc_ceetm_qopt *qopt)
4620 +{
4621 + int err;
4622 + unsigned int i;
4623 + struct ceetm_class *parent_cl, *child_cl;
4624 + struct Qdisc *parent_qdisc;
4625 + struct net_device *dev = qdisc_dev(sch);
4626 +
4627 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4628 +
4629 + if (sch->parent == TC_H_ROOT) {
4630 + pr_err("CEETM: a prio ceetm qdisc can not be root\n");
4631 + err = -EINVAL;
4632 + goto err_init_prio;
4633 + }
4634 +
4635 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4636 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4637 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4638 + err = -EINVAL;
4639 + goto err_init_prio;
4640 + }
4641 +
4642 + /* Obtain the parent root ceetm_class */
4643 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4644 +
4645 + if (!parent_cl || parent_cl->type != CEETM_ROOT) {
4646 + pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n");
4647 + err = -EINVAL;
4648 + goto err_init_prio;
4649 + }
4650 +
4651 + priv->prio.parent = parent_cl;
4652 + parent_cl->root.child = sch;
4653 +
4654 + priv->shaped = parent_cl->shaped;
4655 + priv->prio.qcount = qopt->qcount;
4656 +
4657 + /* Create and configure qcount child classes */
4658 + for (i = 0; i < priv->prio.qcount; i++) {
4659 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4660 + if (!child_cl) {
4661 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4662 + __func__);
4663 + err = -ENOMEM;
4664 + goto err_init_prio;
4665 + }
4666 +
4667 + child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats);
4668 + if (!child_cl->prio.cstats) {
4669 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4670 + __func__);
4671 + err = -ENOMEM;
4672 + goto err_init_prio_cls;
4673 + }
4674 +
4675 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4676 + child_cl->refcnt = 1;
4677 + child_cl->parent = sch;
4678 + child_cl->type = CEETM_PRIO;
4679 + child_cl->shaped = priv->shaped;
4680 + child_cl->prio.child = NULL;
4681 +
4682 + /* All shaped CQs have CR and ER enabled by default */
4683 + child_cl->prio.cr = child_cl->shaped;
4684 + child_cl->prio.er = child_cl->shaped;
4685 + child_cl->prio.fq = NULL;
4686 + child_cl->prio.cq = NULL;
4687 +
4688 + /* Configure the corresponding hardware CQ */
4689 + err = ceetm_config_prio_cls(child_cl, dev,
4690 + parent_cl->root.ch, i);
4691 + if (err) {
4692 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
4693 + __func__, child_cl->common.classid);
4694 + goto err_init_prio_cls;
4695 + }
4696 +
4697 + /* Add class handle in Qdisc */
4698 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4699 + pr_debug(KBUILD_BASENAME " : %s : added ceetm prio class %X associated with CQ %d and CCG %d\n",
4700 + __func__, child_cl->common.classid,
4701 + child_cl->prio.cq->idx, child_cl->prio.ccg->idx);
4702 + }
4703 +
4704 + return 0;
4705 +
4706 +err_init_prio_cls:
4707 + ceetm_cls_destroy(sch, child_cl);
4708 +err_init_prio:
4709 + ceetm_destroy(sch);
4710 + return err;
4711 +}
4712 +
4713 +/* Configure a wbfs ceetm qdisc */
4714 +static int ceetm_init_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
4715 + struct tc_ceetm_qopt *qopt)
4716 +{
4717 + int err, group_b, small_group;
4718 + unsigned int i, id, prio_a, prio_b;
4719 + struct ceetm_class *parent_cl, *child_cl, *root_cl;
4720 + struct Qdisc *parent_qdisc;
4721 + struct ceetm_qdisc *parent_priv;
4722 + struct qm_ceetm_channel *channel;
4723 + struct net_device *dev = qdisc_dev(sch);
4724 +
4725 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4726 +
4727 + /* Validate inputs */
4728 + if (sch->parent == TC_H_ROOT) {
4729 + pr_err("CEETM: a wbfs ceetm qdiscs can not be root\n");
4730 + err = -EINVAL;
4731 + goto err_init_wbfs;
4732 + }
4733 +
4734 + /* Obtain the parent prio ceetm qdisc */
4735 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4736 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4737 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4738 + err = -EINVAL;
4739 + goto err_init_wbfs;
4740 + }
4741 +
4742 + /* Obtain the parent prio ceetm class */
4743 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4744 + parent_priv = qdisc_priv(parent_qdisc);
4745 +
4746 + if (!parent_cl || parent_cl->type != CEETM_PRIO) {
4747 + pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n");
4748 + err = -EINVAL;
4749 + goto err_init_wbfs;
4750 + }
4751 +
4752 + if (!qopt->qcount || !qopt->qweight[0]) {
4753 + pr_err("CEETM: qcount and qweight are mandatory for a wbfs ceetm qdisc\n");
4754 + err = -EINVAL;
4755 + goto err_init_wbfs;
4756 + }
4757 +
4758 + priv->shaped = parent_cl->shaped;
4759 +
4760 + if (!priv->shaped && (qopt->cr || qopt->er)) {
4761 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
4762 + err = -EINVAL;
4763 + goto err_init_wbfs;
4764 + }
4765 +
4766 + if (priv->shaped && !(qopt->cr || qopt->er)) {
4767 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
4768 + err = -EINVAL;
4769 + goto err_init_wbfs;
4770 + }
4771 +
4772 + /* Obtain the parent root ceetm class */
4773 + root_cl = parent_priv->prio.parent;
4774 + if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) ||
4775 + root_cl->root.wbfs_grp_large) {
4776 + pr_err("CEETM: no more wbfs classes are available\n");
4777 + err = -EINVAL;
4778 + goto err_init_wbfs;
4779 + }
4780 +
4781 + if ((root_cl->root.wbfs_grp_a || root_cl->root.wbfs_grp_b) &&
4782 + qopt->qcount == CEETM_MAX_WBFS_QCOUNT) {
4783 + pr_err("CEETM: only %d wbfs classes are available\n",
4784 + CEETM_MIN_WBFS_QCOUNT);
4785 + err = -EINVAL;
4786 + goto err_init_wbfs;
4787 + }
4788 +
4789 + priv->wbfs.parent = parent_cl;
4790 + parent_cl->prio.child = sch;
4791 +
4792 + priv->wbfs.qcount = qopt->qcount;
4793 + priv->wbfs.cr = qopt->cr;
4794 + priv->wbfs.er = qopt->er;
4795 +
4796 + channel = root_cl->root.ch;
4797 +
4798 + /* Configure the hardware wbfs channel groups */
4799 + if (priv->wbfs.qcount == CEETM_MAX_WBFS_QCOUNT) {
4800 + /* Configure the large group A */
4801 + priv->wbfs.group_type = WBFS_GRP_LARGE;
4802 + small_group = false;
4803 + group_b = false;
4804 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4805 + prio_b = prio_a;
4806 +
4807 + } else if (root_cl->root.wbfs_grp_a) {
4808 + /* Configure the group B */
4809 + priv->wbfs.group_type = WBFS_GRP_B;
4810 +
4811 + err = qman_ceetm_channel_get_group(channel, &small_group,
4812 + &prio_a, &prio_b);
4813 + if (err) {
4814 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4815 + __func__);
4816 + goto err_init_wbfs;
4817 + }
4818 +
4819 + small_group = true;
4820 + group_b = true;
4821 + prio_b = TC_H_MIN(parent_cl->common.classid) - 1;
4822 + /* If group A isn't configured, configure it as group B */
4823 + prio_a = prio_a ? : prio_b;
4824 +
4825 + } else {
4826 + /* Configure the small group A */
4827 + priv->wbfs.group_type = WBFS_GRP_A;
4828 +
4829 + err = qman_ceetm_channel_get_group(channel, &small_group,
4830 + &prio_a, &prio_b);
4831 + if (err) {
4832 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4833 + __func__);
4834 + goto err_init_wbfs;
4835 + }
4836 +
4837 + small_group = true;
4838 + group_b = false;
4839 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4840 + /* If group B isn't configured, configure it as group A */
4841 + prio_b = prio_b ? : prio_a;
4842 + }
4843 +
4844 + err = qman_ceetm_channel_set_group(channel, small_group, prio_a,
4845 + prio_b);
4846 + if (err)
4847 + goto err_init_wbfs;
4848 +
4849 + if (priv->shaped) {
4850 + err = qman_ceetm_channel_set_group_cr_eligibility(channel,
4851 + group_b,
4852 + priv->wbfs.cr);
4853 + if (err) {
4854 + pr_err(KBUILD_BASENAME " : %s : failed to set group CR eligibility\n",
4855 + __func__);
4856 + goto err_init_wbfs;
4857 + }
4858 +
4859 + err = qman_ceetm_channel_set_group_er_eligibility(channel,
4860 + group_b,
4861 + priv->wbfs.er);
4862 + if (err) {
4863 + pr_err(KBUILD_BASENAME " : %s : failed to set group ER eligibility\n",
4864 + __func__);
4865 + goto err_init_wbfs;
4866 + }
4867 + }
4868 +
4869 + /* Create qcount child classes */
4870 + for (i = 0; i < priv->wbfs.qcount; i++) {
4871 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4872 + if (!child_cl) {
4873 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4874 + __func__);
4875 + err = -ENOMEM;
4876 + goto err_init_wbfs;
4877 + }
4878 +
4879 + child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats);
4880 + if (!child_cl->wbfs.cstats) {
4881 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4882 + __func__);
4883 + err = -ENOMEM;
4884 + goto err_init_wbfs_cls;
4885 + }
4886 +
4887 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4888 + child_cl->refcnt = 1;
4889 + child_cl->parent = sch;
4890 + child_cl->type = CEETM_WBFS;
4891 + child_cl->shaped = priv->shaped;
4892 + child_cl->wbfs.fq = NULL;
4893 + child_cl->wbfs.cq = NULL;
4894 + child_cl->wbfs.weight = qopt->qweight[i];
4895 +
4896 + if (priv->wbfs.group_type == WBFS_GRP_B)
4897 + id = WBFS_GRP_B_OFFSET + i;
4898 + else
4899 + id = WBFS_GRP_A_OFFSET + i;
4900 +
4901 + err = ceetm_config_wbfs_cls(child_cl, dev, channel, id,
4902 + priv->wbfs.group_type);
4903 + if (err) {
4904 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
4905 + __func__, child_cl->common.classid);
4906 + goto err_init_wbfs_cls;
4907 + }
4908 +
4909 + /* Add class handle in Qdisc */
4910 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4911 + pr_debug(KBUILD_BASENAME " : %s : added ceetm wbfs class %X associated with CQ %d and CCG %d\n",
4912 + __func__, child_cl->common.classid,
4913 + child_cl->wbfs.cq->idx, child_cl->wbfs.ccg->idx);
4914 + }
4915 +
4916 + /* Signal the root class that a group has been configured */
4917 + switch (priv->wbfs.group_type) {
4918 + case WBFS_GRP_LARGE:
4919 + root_cl->root.wbfs_grp_large = true;
4920 + break;
4921 + case WBFS_GRP_A:
4922 + root_cl->root.wbfs_grp_a = true;
4923 + break;
4924 + case WBFS_GRP_B:
4925 + root_cl->root.wbfs_grp_b = true;
4926 + break;
4927 + }
4928 +
4929 + return 0;
4930 +
4931 +err_init_wbfs_cls:
4932 + ceetm_cls_destroy(sch, child_cl);
4933 +err_init_wbfs:
4934 + ceetm_destroy(sch);
4935 + return err;
4936 +}
4937 +
4938 +/* Configure a generic ceetm qdisc */
4939 +static int ceetm_init(struct Qdisc *sch, struct nlattr *opt)
4940 +{
4941 + struct tc_ceetm_qopt *qopt;
4942 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
4943 + int ret;
4944 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4945 + struct net_device *dev = qdisc_dev(sch);
4946 +
4947 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4948 +
4949 + if (!netif_is_multiqueue(dev))
4950 + return -EOPNOTSUPP;
4951 +
4952 + if (!opt) {
4953 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4954 + return -EINVAL;
4955 + }
4956 +
4957 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
4958 + if (ret < 0) {
4959 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4960 + return ret;
4961 + }
4962 +
4963 + if (!tb[TCA_CEETM_QOPS]) {
4964 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4965 + return -EINVAL;
4966 + }
4967 +
4968 + if (TC_H_MIN(sch->handle)) {
4969 + pr_err("CEETM: a qdisc should not have a minor\n");
4970 + return -EINVAL;
4971 + }
4972 +
4973 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
4974 +
4975 + /* Initialize the class hash list. Each qdisc has its own class hash */
4976 + ret = qdisc_class_hash_init(&priv->clhash);
4977 + if (ret < 0) {
4978 + pr_err(KBUILD_BASENAME " : %s : qdisc_class_hash_init failed\n",
4979 + __func__);
4980 + return ret;
4981 + }
4982 +
4983 + priv->type = qopt->type;
4984 +
4985 + switch (priv->type) {
4986 + case CEETM_ROOT:
4987 + ret = ceetm_init_root(sch, priv, qopt);
4988 + break;
4989 + case CEETM_PRIO:
4990 + ret = ceetm_init_prio(sch, priv, qopt);
4991 + break;
4992 + case CEETM_WBFS:
4993 + ret = ceetm_init_wbfs(sch, priv, qopt);
4994 + break;
4995 + default:
4996 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
4997 + ceetm_destroy(sch);
4998 + ret = -EINVAL;
4999 + }
5000 +
5001 + return ret;
5002 +}
5003 +
5004 +/* Edit a root ceetm qdisc */
5005 +static int ceetm_change_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
5006 + struct net_device *dev,
5007 + struct tc_ceetm_qopt *qopt)
5008 +{
5009 + int err = 0;
5010 + u64 bps;
5011 +
5012 + if (priv->shaped != (bool)qopt->shaped) {
5013 + pr_err("CEETM: qdisc %X is %s\n", sch->handle,
5014 + priv->shaped ? "shaped" : "unshaped");
5015 + return -EINVAL;
5016 + }
5017 +
5018 + /* Nothing to modify for unshaped qdiscs */
5019 + if (!priv->shaped)
5020 + return 0;
5021 +
5022 + /* Configure the LNI shaper */
5023 + if (priv->root.overhead != qopt->overhead) {
5024 + err = qman_ceetm_lni_enable_shaper(priv->root.lni, 1,
5025 + qopt->overhead);
5026 + if (err)
5027 + goto change_err;
5028 + priv->root.overhead = qopt->overhead;
5029 + }
5030 +
5031 + if (priv->root.rate != qopt->rate) {
5032 + bps = qopt->rate << 3; /* Bps -> bps */
5033 + err = qman_ceetm_lni_set_commit_rate_bps(priv->root.lni, bps,
5034 + dev->mtu);
5035 + if (err)
5036 + goto change_err;
5037 + priv->root.rate = qopt->rate;
5038 + }
5039 +
5040 + if (priv->root.ceil != qopt->ceil) {
5041 + bps = qopt->ceil << 3; /* Bps -> bps */
5042 + err = qman_ceetm_lni_set_excess_rate_bps(priv->root.lni, bps,
5043 + dev->mtu);
5044 + if (err)
5045 + goto change_err;
5046 + priv->root.ceil = qopt->ceil;
5047 + }
5048 +
5049 + return 0;
5050 +
5051 +change_err:
5052 + pr_err(KBUILD_BASENAME " : %s : failed to configure the root ceetm qdisc %X\n",
5053 + __func__, sch->handle);
5054 + return err;
5055 +}
5056 +
5057 +/* Edit a wbfs ceetm qdisc */
5058 +static int ceetm_change_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
5059 + struct tc_ceetm_qopt *qopt)
5060 +{
5061 + int err;
5062 + bool group_b;
5063 + struct qm_ceetm_channel *channel;
5064 + struct ceetm_class *prio_class, *root_class;
5065 + struct ceetm_qdisc *prio_qdisc;
5066 +
5067 + if (qopt->qcount) {
5068 + pr_err("CEETM: the qcount can not be modified\n");
5069 + return -EINVAL;
5070 + }
5071 +
5072 + if (qopt->qweight[0]) {
5073 + pr_err("CEETM: the qweight can be modified through the wbfs classes\n");
5074 + return -EINVAL;
5075 + }
5076 +
5077 + if (!priv->shaped && (qopt->cr || qopt->er)) {
5078 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
5079 + return -EINVAL;
5080 + }
5081 +
5082 + if (priv->shaped && !(qopt->cr || qopt->er)) {
5083 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
5084 + return -EINVAL;
5085 + }
5086 +
5087 + /* Nothing to modify for unshaped qdiscs */
5088 + if (!priv->shaped)
5089 + return 0;
5090 +
5091 + prio_class = priv->wbfs.parent;
5092 + prio_qdisc = qdisc_priv(prio_class->parent);
5093 + root_class = prio_qdisc->prio.parent;
5094 + channel = root_class->root.ch;
5095 + group_b = priv->wbfs.group_type == WBFS_GRP_B;
5096 +
5097 + if (qopt->cr != priv->wbfs.cr) {
5098 + err = qman_ceetm_channel_set_group_cr_eligibility(channel,
5099 + group_b,
5100 + qopt->cr);
5101 + if (err)
5102 + goto change_err;
5103 + priv->wbfs.cr = qopt->cr;
5104 + }
5105 +
5106 + if (qopt->er != priv->wbfs.er) {
5107 + err = qman_ceetm_channel_set_group_er_eligibility(channel,
5108 + group_b,
5109 + qopt->er);
5110 + if (err)
5111 + goto change_err;
5112 + priv->wbfs.er = qopt->er;
5113 + }
5114 +
5115 + return 0;
5116 +
5117 +change_err:
5118 + pr_err(KBUILD_BASENAME " : %s : failed to configure the wbfs ceetm qdisc %X\n",
5119 + __func__, sch->handle);
5120 + return err;
5121 +}
5122 +
5123 +/* Edit a ceetm qdisc */
5124 +static int ceetm_change(struct Qdisc *sch, struct nlattr *opt)
5125 +{
5126 + struct tc_ceetm_qopt *qopt;
5127 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
5128 + int ret;
5129 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5130 + struct net_device *dev = qdisc_dev(sch);
5131 +
5132 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5133 +
5134 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
5135 + if (ret < 0) {
5136 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5137 + return ret;
5138 + }
5139 +
5140 + if (!tb[TCA_CEETM_QOPS]) {
5141 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5142 + return -EINVAL;
5143 + }
5144 +
5145 + if (TC_H_MIN(sch->handle)) {
5146 + pr_err("CEETM: a qdisc should not have a minor\n");
5147 + return -EINVAL;
5148 + }
5149 +
5150 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
5151 +
5152 + if (priv->type != qopt->type) {
5153 + pr_err("CEETM: qdisc %X is not of the provided type\n",
5154 + sch->handle);
5155 + return -EINVAL;
5156 + }
5157 +
5158 + switch (priv->type) {
5159 + case CEETM_ROOT:
5160 + ret = ceetm_change_root(sch, priv, dev, qopt);
5161 + break;
5162 + case CEETM_PRIO:
5163 + pr_err("CEETM: prio qdiscs can not be modified\n");
5164 + ret = -EINVAL;
5165 + break;
5166 + case CEETM_WBFS:
5167 + ret = ceetm_change_wbfs(sch, priv, qopt);
5168 + break;
5169 + default:
5170 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
5171 + ret = -EINVAL;
5172 + }
5173 +
5174 + return ret;
5175 +}
5176 +
5177 +/* Attach the underlying pfifo qdiscs */
5178 +static void ceetm_attach(struct Qdisc *sch)
5179 +{
5180 + struct net_device *dev = qdisc_dev(sch);
5181 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5182 + struct Qdisc *qdisc, *old_qdisc;
5183 + unsigned int i;
5184 +
5185 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5186 +
5187 + for (i = 0; i < dev->num_tx_queues; i++) {
5188 + qdisc = priv->root.qdiscs[i];
5189 + old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc);
5190 + if (old_qdisc)
5191 + qdisc_destroy(old_qdisc);
5192 + }
5193 +}
5194 +
5195 +static unsigned long ceetm_cls_get(struct Qdisc *sch, u32 classid)
5196 +{
5197 + struct ceetm_class *cl;
5198 +
5199 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5200 + __func__, classid, sch->handle);
5201 + cl = ceetm_find(classid, sch);
5202 +
5203 + if (cl)
5204 + cl->refcnt++; /* Will decrement in put() */
5205 + return (unsigned long)cl;
5206 +}
5207 +
5208 +static void ceetm_cls_put(struct Qdisc *sch, unsigned long arg)
5209 +{
5210 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5211 +
5212 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5213 + __func__, cl->common.classid, sch->handle);
5214 + cl->refcnt--;
5215 +
5216 + if (cl->refcnt == 0)
5217 + ceetm_cls_destroy(sch, cl);
5218 +}
5219 +
5220 +static int ceetm_cls_change_root(struct ceetm_class *cl,
5221 + struct tc_ceetm_copt *copt,
5222 + struct net_device *dev)
5223 +{
5224 + int err;
5225 + u64 bps;
5226 +
5227 + if ((bool)copt->shaped != cl->shaped) {
5228 + pr_err("CEETM: class %X is %s\n", cl->common.classid,
5229 + cl->shaped ? "shaped" : "unshaped");
5230 + return -EINVAL;
5231 + }
5232 +
5233 + if (cl->shaped && cl->root.rate != copt->rate) {
5234 + bps = copt->rate << 3; /* Bps -> bps */
5235 + err = qman_ceetm_channel_set_commit_rate_bps(cl->root.ch, bps,
5236 + dev->mtu);
5237 + if (err)
5238 + goto change_cls_err;
5239 + cl->root.rate = copt->rate;
5240 + }
5241 +
5242 + if (cl->shaped && cl->root.ceil != copt->ceil) {
5243 + bps = copt->ceil << 3; /* Bps -> bps */
5244 + err = qman_ceetm_channel_set_excess_rate_bps(cl->root.ch, bps,
5245 + dev->mtu);
5246 + if (err)
5247 + goto change_cls_err;
5248 + cl->root.ceil = copt->ceil;
5249 + }
5250 +
5251 + if (!cl->shaped && cl->root.tbl != copt->tbl) {
5252 + err = qman_ceetm_channel_set_weight(cl->root.ch, copt->tbl);
5253 + if (err)
5254 + goto change_cls_err;
5255 + cl->root.tbl = copt->tbl;
5256 + }
5257 +
5258 + return 0;
5259 +
5260 +change_cls_err:
5261 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm root class %X\n",
5262 + __func__, cl->common.classid);
5263 + return err;
5264 +}
5265 +
5266 +static int ceetm_cls_change_prio(struct ceetm_class *cl,
5267 + struct tc_ceetm_copt *copt)
5268 +{
5269 + int err;
5270 +
5271 + if (!cl->shaped && (copt->cr || copt->er)) {
5272 + pr_err("CEETM: only shaped classes can have CR and ER enabled\n");
5273 + return -EINVAL;
5274 + }
5275 +
5276 + if (cl->prio.cr != (bool)copt->cr) {
5277 + err = qman_ceetm_channel_set_cq_cr_eligibility(
5278 + cl->prio.cq->parent,
5279 + cl->prio.cq->idx,
5280 + copt->cr);
5281 + if (err)
5282 + goto change_cls_err;
5283 + cl->prio.cr = copt->cr;
5284 + }
5285 +
5286 + if (cl->prio.er != (bool)copt->er) {
5287 + err = qman_ceetm_channel_set_cq_er_eligibility(
5288 + cl->prio.cq->parent,
5289 + cl->prio.cq->idx,
5290 + copt->er);
5291 + if (err)
5292 + goto change_cls_err;
5293 + cl->prio.er = copt->er;
5294 + }
5295 +
5296 + return 0;
5297 +
5298 +change_cls_err:
5299 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
5300 + __func__, cl->common.classid);
5301 + return err;
5302 +}
5303 +
5304 +static int ceetm_cls_change_wbfs(struct ceetm_class *cl,
5305 + struct tc_ceetm_copt *copt)
5306 +{
5307 + int err;
5308 +
5309 + if (copt->weight != cl->wbfs.weight) {
5310 + /* Configure the CQ weight: real number multiplied by 100 to
5311 + * get rid of the fraction
5312 + */
5313 + err = qman_ceetm_set_queue_weight_in_ratio(cl->wbfs.cq,
5314 + copt->weight * 100);
5315 +
5316 + if (err) {
5317 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
5318 + __func__, cl->common.classid);
5319 + return err;
5320 + }
5321 +
5322 + cl->wbfs.weight = copt->weight;
5323 + }
5324 +
5325 + return 0;
5326 +}
5327 +
5328 +/* Add a ceetm root class or configure a ceetm root/prio/wbfs class */
5329 +static int ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid,
5330 + struct nlattr **tca, unsigned long *arg)
5331 +{
5332 + int err;
5333 + u64 bps;
5334 + struct ceetm_qdisc *priv;
5335 + struct ceetm_class *cl = (struct ceetm_class *)*arg;
5336 + struct nlattr *opt = tca[TCA_OPTIONS];
5337 + struct nlattr *tb[__TCA_CEETM_MAX];
5338 + struct tc_ceetm_copt *copt;
5339 + struct qm_ceetm_channel *channel;
5340 + struct net_device *dev = qdisc_dev(sch);
5341 +
5342 + pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n",
5343 + __func__, classid, sch->handle);
5344 +
5345 + if (strcmp(sch->ops->id, ceetm_qdisc_ops.id)) {
5346 + pr_err("CEETM: a ceetm class can not be attached to other qdisc/class types\n");
5347 + return -EINVAL;
5348 + }
5349 +
5350 + priv = qdisc_priv(sch);
5351 +
5352 + if (!opt) {
5353 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5354 + return -EINVAL;
5355 + }
5356 +
5357 + if (!cl && sch->handle != parentid) {
5358 + pr_err("CEETM: classes can be attached to the root ceetm qdisc only\n");
5359 + return -EINVAL;
5360 + }
5361 +
5362 + if (!cl && priv->type != CEETM_ROOT) {
5363 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5364 + return -EINVAL;
5365 + }
5366 +
5367 + err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy);
5368 + if (err < 0) {
5369 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5370 + return -EINVAL;
5371 + }
5372 +
5373 + if (!tb[TCA_CEETM_COPT]) {
5374 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5375 + return -EINVAL;
5376 + }
5377 +
5378 + if (TC_H_MIN(classid) >= PFIFO_MIN_OFFSET) {
5379 + pr_err("CEETM: only minors 0x01 to 0x20 can be used for ceetm root classes\n");
5380 + return -EINVAL;
5381 + }
5382 +
5383 + copt = nla_data(tb[TCA_CEETM_COPT]);
5384 +
5385 + /* Configure an existing ceetm class */
5386 + if (cl) {
5387 + if (copt->type != cl->type) {
5388 + pr_err("CEETM: class %X is not of the provided type\n",
5389 + cl->common.classid);
5390 + return -EINVAL;
5391 + }
5392 +
5393 + switch (copt->type) {
5394 + case CEETM_ROOT:
5395 + return ceetm_cls_change_root(cl, copt, dev);
5396 +
5397 + case CEETM_PRIO:
5398 + return ceetm_cls_change_prio(cl, copt);
5399 +
5400 + case CEETM_WBFS:
5401 + return ceetm_cls_change_wbfs(cl, copt);
5402 +
5403 + default:
5404 + pr_err(KBUILD_BASENAME " : %s : invalid class\n",
5405 + __func__);
5406 + return -EINVAL;
5407 + }
5408 + }
5409 +
5410 + /* Add a new root ceetm class */
5411 + if (copt->type != CEETM_ROOT) {
5412 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5413 + return -EINVAL;
5414 + }
5415 +
5416 + if (copt->shaped && !priv->shaped) {
5417 + pr_err("CEETM: can not add a shaped ceetm root class under an unshaped ceetm root qdisc\n");
5418 + return -EINVAL;
5419 + }
5420 +
5421 + cl = kzalloc(sizeof(*cl), GFP_KERNEL);
5422 + if (!cl)
5423 + return -ENOMEM;
5424 +
5425 + cl->type = copt->type;
5426 + cl->shaped = copt->shaped;
5427 + cl->root.rate = copt->rate;
5428 + cl->root.ceil = copt->ceil;
5429 + cl->root.tbl = copt->tbl;
5430 +
5431 + cl->common.classid = classid;
5432 + cl->refcnt = 1;
5433 + cl->parent = sch;
5434 + cl->root.child = NULL;
5435 + cl->root.wbfs_grp_a = false;
5436 + cl->root.wbfs_grp_b = false;
5437 + cl->root.wbfs_grp_large = false;
5438 +
5439 + /* Claim a CEETM channel */
5440 + err = qman_ceetm_channel_claim(&channel, priv->root.lni);
5441 + if (err) {
5442 + pr_err(KBUILD_BASENAME " : %s : failed to claim a channel\n",
5443 + __func__);
5444 + goto claim_err;
5445 + }
5446 +
5447 + cl->root.ch = channel;
5448 +
5449 + if (cl->shaped) {
5450 + /* Configure the channel shaper */
5451 + err = qman_ceetm_channel_enable_shaper(channel, 1);
5452 + if (err)
5453 + goto channel_err;
5454 +
5455 + bps = cl->root.rate << 3; /* Bps -> bps */
5456 + err = qman_ceetm_channel_set_commit_rate_bps(channel, bps,
5457 + dev->mtu);
5458 + if (err)
5459 + goto channel_err;
5460 +
5461 + bps = cl->root.ceil << 3; /* Bps -> bps */
5462 + err = qman_ceetm_channel_set_excess_rate_bps(channel, bps,
5463 + dev->mtu);
5464 + if (err)
5465 + goto channel_err;
5466 +
5467 + } else {
5468 + /* Configure the uFQ algorithm */
5469 + err = qman_ceetm_channel_set_weight(channel, cl->root.tbl);
5470 + if (err)
5471 + goto channel_err;
5472 + }
5473 +
5474 + /* Add class handle in Qdisc */
5475 + ceetm_link_class(sch, &priv->clhash, &cl->common);
5476 +
5477 + pr_debug(KBUILD_BASENAME " : %s : configured class %X associated with channel %d\n",
5478 + __func__, classid, channel->idx);
5479 + *arg = (unsigned long)cl;
5480 + return 0;
5481 +
5482 +channel_err:
5483 + pr_err(KBUILD_BASENAME " : %s : failed to configure the channel %d\n",
5484 + __func__, channel->idx);
5485 + if (qman_ceetm_channel_release(channel))
5486 + pr_err(KBUILD_BASENAME " : %s : failed to release the channel %d\n",
5487 + __func__, channel->idx);
5488 +claim_err:
5489 + kfree(cl);
5490 + return err;
5491 +}
5492 +
5493 +static void ceetm_cls_walk(struct Qdisc *sch, struct qdisc_walker *arg)
5494 +{
5495 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5496 + struct ceetm_class *cl;
5497 + unsigned int i;
5498 +
5499 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5500 +
5501 + if (arg->stop)
5502 + return;
5503 +
5504 + for (i = 0; i < priv->clhash.hashsize; i++) {
5505 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) {
5506 + if (arg->count < arg->skip) {
5507 + arg->count++;
5508 + continue;
5509 + }
5510 + if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
5511 + arg->stop = 1;
5512 + return;
5513 + }
5514 + arg->count++;
5515 + }
5516 + }
5517 +}
5518 +
5519 +static int ceetm_cls_dump(struct Qdisc *sch, unsigned long arg,
5520 + struct sk_buff *skb, struct tcmsg *tcm)
5521 +{
5522 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5523 + struct nlattr *nest;
5524 + struct tc_ceetm_copt copt;
5525 +
5526 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5527 + __func__, cl->common.classid, sch->handle);
5528 +
5529 + sch_tree_lock(sch);
5530 +
5531 + tcm->tcm_parent = ((struct Qdisc *)cl->parent)->handle;
5532 + tcm->tcm_handle = cl->common.classid;
5533 +
5534 + memset(&copt, 0, sizeof(copt));
5535 +
5536 + copt.shaped = cl->shaped;
5537 + copt.type = cl->type;
5538 +
5539 + switch (cl->type) {
5540 + case CEETM_ROOT:
5541 + if (cl->root.child)
5542 + tcm->tcm_info = cl->root.child->handle;
5543 +
5544 + copt.rate = cl->root.rate;
5545 + copt.ceil = cl->root.ceil;
5546 + copt.tbl = cl->root.tbl;
5547 + break;
5548 +
5549 + case CEETM_PRIO:
5550 + if (cl->prio.child)
5551 + tcm->tcm_info = cl->prio.child->handle;
5552 +
5553 + copt.cr = cl->prio.cr;
5554 + copt.er = cl->prio.er;
5555 + break;
5556 +
5557 + case CEETM_WBFS:
5558 + copt.weight = cl->wbfs.weight;
5559 + break;
5560 + }
5561 +
5562 + nest = nla_nest_start(skb, TCA_OPTIONS);
5563 + if (!nest)
5564 + goto nla_put_failure;
5565 + if (nla_put(skb, TCA_CEETM_COPT, sizeof(copt), &copt))
5566 + goto nla_put_failure;
5567 + nla_nest_end(skb, nest);
5568 + sch_tree_unlock(sch);
5569 + return skb->len;
5570 +
5571 +nla_put_failure:
5572 + sch_tree_unlock(sch);
5573 + nla_nest_cancel(skb, nest);
5574 + return -EMSGSIZE;
5575 +}
5576 +
5577 +static int ceetm_cls_delete(struct Qdisc *sch, unsigned long arg)
5578 +{
5579 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5580 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5581 +
5582 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5583 + __func__, cl->common.classid, sch->handle);
5584 +
5585 + sch_tree_lock(sch);
5586 + qdisc_class_hash_remove(&priv->clhash, &cl->common);
5587 + cl->refcnt--;
5588 +
5589 + /* The refcnt should be at least 1 since we have incremented it in
5590 + * get(). Will decrement again in put() where we will call destroy()
5591 + * to actually free the memory if it reaches 0.
5592 + */
5593 + WARN_ON(cl->refcnt == 0);
5594 +
5595 + sch_tree_unlock(sch);
5596 + return 0;
5597 +}
5598 +
5599 +/* Get the class' child qdisc, if any */
5600 +static struct Qdisc *ceetm_cls_leaf(struct Qdisc *sch, unsigned long arg)
5601 +{
5602 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5603 +
5604 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5605 + __func__, cl->common.classid, sch->handle);
5606 +
5607 + switch (cl->type) {
5608 + case CEETM_ROOT:
5609 + return cl->root.child;
5610 +
5611 + case CEETM_PRIO:
5612 + return cl->prio.child;
5613 + }
5614 +
5615 + return NULL;
5616 +}
5617 +
5618 +static int ceetm_cls_graft(struct Qdisc *sch, unsigned long arg,
5619 + struct Qdisc *new, struct Qdisc **old)
5620 +{
5621 + if (new && strcmp(new->ops->id, ceetm_qdisc_ops.id)) {
5622 + pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n");
5623 + return -EOPNOTSUPP;
5624 + }
5625 +
5626 + return 0;
5627 +}
5628 +
5629 +static int ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg,
5630 + struct gnet_dump *d)
5631 +{
5632 + unsigned int i;
5633 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5634 + struct gnet_stats_basic_packed tmp_bstats;
5635 + struct ceetm_class_stats *cstats = NULL;
5636 + struct qm_ceetm_cq *cq = NULL;
5637 + struct tc_ceetm_xstats xstats;
5638 +
5639 + memset(&xstats, 0, sizeof(xstats));
5640 + memset(&tmp_bstats, 0, sizeof(tmp_bstats));
5641 +
5642 + switch (cl->type) {
5643 + case CEETM_ROOT:
5644 + return 0;
5645 + case CEETM_PRIO:
5646 + cq = cl->prio.cq;
5647 + break;
5648 + case CEETM_WBFS:
5649 + cq = cl->wbfs.cq;
5650 + break;
5651 + }
5652 +
5653 + for_each_online_cpu(i) {
5654 + switch (cl->type) {
5655 + case CEETM_PRIO:
5656 + cstats = per_cpu_ptr(cl->prio.cstats, i);
5657 + break;
5658 + case CEETM_WBFS:
5659 + cstats = per_cpu_ptr(cl->wbfs.cstats, i);
5660 + break;
5661 + }
5662 +
5663 + if (cstats) {
5664 + xstats.ern_drop_count += cstats->ern_drop_count;
5665 + xstats.congested_count += cstats->congested_count;
5666 + tmp_bstats.bytes += cstats->bstats.bytes;
5667 + tmp_bstats.packets += cstats->bstats.packets;
5668 + }
5669 + }
5670 +
5671 + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
5672 + d, NULL, &tmp_bstats) < 0)
5673 + return -1;
5674 +
5675 + if (cq && qman_ceetm_cq_get_dequeue_statistics(cq, 0,
5676 + &xstats.frame_count,
5677 + &xstats.byte_count))
5678 + return -1;
5679 +
5680 + return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
5681 +}
5682 +
5683 +static struct tcf_proto **ceetm_tcf_chain(struct Qdisc *sch, unsigned long arg)
5684 +{
5685 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5686 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5687 + struct tcf_proto **fl = cl ? &cl->filter_list : &priv->filter_list;
5688 +
5689 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5690 + cl ? cl->common.classid : 0, sch->handle);
5691 + return fl;
5692 +}
5693 +
5694 +static unsigned long ceetm_tcf_bind(struct Qdisc *sch, unsigned long parent,
5695 + u32 classid)
5696 +{
5697 + struct ceetm_class *cl = ceetm_find(classid, sch);
5698 +
5699 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5700 + cl ? cl->common.classid : 0, sch->handle);
5701 + return (unsigned long)cl;
5702 +}
5703 +
5704 +static void ceetm_tcf_unbind(struct Qdisc *sch, unsigned long arg)
5705 +{
5706 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5707 +
5708 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5709 + cl ? cl->common.classid : 0, sch->handle);
5710 +}
5711 +
5712 +const struct Qdisc_class_ops ceetm_cls_ops = {
5713 + .graft = ceetm_cls_graft,
5714 + .leaf = ceetm_cls_leaf,
5715 + .get = ceetm_cls_get,
5716 + .put = ceetm_cls_put,
5717 + .change = ceetm_cls_change,
5718 + .delete = ceetm_cls_delete,
5719 + .walk = ceetm_cls_walk,
5720 + .tcf_chain = ceetm_tcf_chain,
5721 + .bind_tcf = ceetm_tcf_bind,
5722 + .unbind_tcf = ceetm_tcf_unbind,
5723 + .dump = ceetm_cls_dump,
5724 + .dump_stats = ceetm_cls_dump_stats,
5725 +};
5726 +
5727 +struct Qdisc_ops ceetm_qdisc_ops __read_mostly = {
5728 + .id = "ceetm",
5729 + .priv_size = sizeof(struct ceetm_qdisc),
5730 + .cl_ops = &ceetm_cls_ops,
5731 + .init = ceetm_init,
5732 + .destroy = ceetm_destroy,
5733 + .change = ceetm_change,
5734 + .dump = ceetm_dump,
5735 + .attach = ceetm_attach,
5736 + .owner = THIS_MODULE,
5737 +};
5738 +
5739 +/* Run the filters and classifiers attached to the qdisc on the provided skb */
5740 +static struct ceetm_class *ceetm_classify(struct sk_buff *skb,
5741 + struct Qdisc *sch, int *qerr,
5742 + bool *act_drop)
5743 +{
5744 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5745 + struct ceetm_class *cl = NULL, *wbfs_cl;
5746 + struct tcf_result res;
5747 + struct tcf_proto *tcf;
5748 + int result;
5749 +
5750 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
5751 + tcf = priv->filter_list;
5752 + while (tcf && (result = tc_classify(skb, tcf, &res, false)) >= 0) {
5753 +#ifdef CONFIG_NET_CLS_ACT
5754 + switch (result) {
5755 + case TC_ACT_QUEUED:
5756 + case TC_ACT_STOLEN:
5757 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
5758 + case TC_ACT_SHOT:
5759 + /* No valid class found due to action */
5760 + *act_drop = true;
5761 + return NULL;
5762 + }
5763 +#endif
5764 + cl = (void *)res.class;
5765 + if (!cl) {
5766 + if (res.classid == sch->handle) {
5767 + /* The filter leads to the qdisc */
5768 + /* TODO default qdisc */
5769 + return NULL;
5770 + }
5771 +
5772 + cl = ceetm_find(res.classid, sch);
5773 + if (!cl)
5774 + /* The filter leads to an invalid class */
5775 + break;
5776 + }
5777 +
5778 + /* The class might have its own filters attached */
5779 + tcf = cl->filter_list;
5780 + }
5781 +
5782 + if (!cl) {
5783 + /* No valid class found */
5784 + /* TODO default qdisc */
5785 + return NULL;
5786 + }
5787 +
5788 + switch (cl->type) {
5789 + case CEETM_ROOT:
5790 + if (cl->root.child) {
5791 + /* Run the prio qdisc classifiers */
5792 + return ceetm_classify(skb, cl->root.child, qerr,
5793 + act_drop);
5794 + } else {
5795 + /* The root class does not have a child prio qdisc */
5796 + /* TODO default qdisc */
5797 + return NULL;
5798 + }
5799 + case CEETM_PRIO:
5800 + if (cl->prio.child) {
5801 + /* If filters lead to a wbfs class, return it.
5802 + * Otherwise, return the prio class
5803 + */
5804 + wbfs_cl = ceetm_classify(skb, cl->prio.child, qerr,
5805 + act_drop);
5806 + /* A NULL result might indicate either an erroneous
5807 + * filter, or no filters at all. We will assume the
5808 + * latter
5809 + */
5810 + return wbfs_cl ? : cl;
5811 + }
5812 + }
5813 +
5814 + /* For wbfs and childless prio classes, return the class directly */
5815 + return cl;
5816 +}
5817 +
5818 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
5819 +{
5820 + int ret;
5821 + bool act_drop = false;
5822 + struct Qdisc *sch = net_dev->qdisc;
5823 + struct ceetm_class *cl;
5824 + struct dpa_priv_s *priv_dpa;
5825 + struct qman_fq *egress_fq, *conf_fq;
5826 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5827 + struct ceetm_qdisc_stats *qstats = this_cpu_ptr(priv->root.qstats);
5828 + struct ceetm_class_stats *cstats;
5829 + const int queue_mapping = dpa_get_queue_mapping(skb);
5830 + spinlock_t *root_lock = qdisc_lock(sch);
5831 +
5832 + spin_lock(root_lock);
5833 + cl = ceetm_classify(skb, sch, &ret, &act_drop);
5834 + spin_unlock(root_lock);
5835 +
5836 +#ifdef CONFIG_NET_CLS_ACT
5837 + if (act_drop) {
5838 + if (ret & __NET_XMIT_BYPASS)
5839 + qstats->drops++;
5840 + goto drop;
5841 + }
5842 +#endif
5843 + /* TODO default class */
5844 + if (unlikely(!cl)) {
5845 + qstats->drops++;
5846 + goto drop;
5847 + }
5848 +
5849 + priv_dpa = netdev_priv(net_dev);
5850 + conf_fq = priv_dpa->conf_fqs[queue_mapping];
5851 +
5852 + /* Choose the proper tx fq and update the basic stats (bytes and
5853 + * packets sent by the class)
5854 + */
5855 + switch (cl->type) {
5856 + case CEETM_PRIO:
5857 + egress_fq = &cl->prio.fq->fq;
5858 + cstats = this_cpu_ptr(cl->prio.cstats);
5859 + break;
5860 + case CEETM_WBFS:
5861 + egress_fq = &cl->wbfs.fq->fq;
5862 + cstats = this_cpu_ptr(cl->wbfs.cstats);
5863 + break;
5864 + default:
5865 + qstats->drops++;
5866 + goto drop;
5867 + }
5868 +
5869 + bstats_update(&cstats->bstats, skb);
5870 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
5871 +
5872 +drop:
5873 + dev_kfree_skb_any(skb);
5874 + return NET_XMIT_SUCCESS;
5875 +}
5876 +
5877 +static int __init ceetm_register(void)
5878 +{
5879 + int _errno = 0;
5880 +
5881 + pr_info(KBUILD_MODNAME ": " DPA_CEETM_DESCRIPTION "\n");
5882 +
5883 + _errno = register_qdisc(&ceetm_qdisc_ops);
5884 + if (unlikely(_errno))
5885 + pr_err(KBUILD_MODNAME
5886 + ": %s:%hu:%s(): register_qdisc() = %d\n",
5887 + KBUILD_BASENAME ".c", __LINE__, __func__, _errno);
5888 +
5889 + return _errno;
5890 +}
5891 +
5892 +static void __exit ceetm_unregister(void)
5893 +{
5894 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
5895 + KBUILD_BASENAME ".c", __func__);
5896 +
5897 + unregister_qdisc(&ceetm_qdisc_ops);
5898 +}
5899 +
5900 +module_init(ceetm_register);
5901 +module_exit(ceetm_unregister);
5902 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
5903 new file mode 100644
5904 index 00000000..63cc3475
5905 --- /dev/null
5906 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
5907 @@ -0,0 +1,237 @@
5908 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
5909 + *
5910 + * Redistribution and use in source and binary forms, with or without
5911 + * modification, are permitted provided that the following conditions are met:
5912 + * * Redistributions of source code must retain the above copyright
5913 + * notice, this list of conditions and the following disclaimer.
5914 + * * Redistributions in binary form must reproduce the above copyright
5915 + * notice, this list of conditions and the following disclaimer in the
5916 + * documentation and/or other materials provided with the distribution.
5917 + * * Neither the name of Freescale Semiconductor nor the
5918 + * names of its contributors may be used to endorse or promote products
5919 + * derived from this software without specific prior written permission.
5920 + *
5921 + *
5922 + * ALTERNATIVELY, this software may be distributed under the terms of the
5923 + * GNU General Public License ("GPL") as published by the Free Software
5924 + * Foundation, either version 2 of that License or (at your option) any
5925 + * later version.
5926 + *
5927 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5928 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5929 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5930 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5931 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5932 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5933 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5934 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5935 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5936 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5937 + */
5938 +
5939 +#ifndef __DPAA_ETH_CEETM_H
5940 +#define __DPAA_ETH_CEETM_H
5941 +
5942 +#include <net/pkt_sched.h>
5943 +#include <net/pkt_cls.h>
5944 +#include <net/netlink.h>
5945 +#include <lnxwrp_fm.h>
5946 +
5947 +#include "mac.h"
5948 +#include "dpaa_eth_common.h"
5949 +
5950 +/* Mask to determine the sub-portal id from a channel number */
5951 +#define CHANNEL_SP_MASK 0x1f
5952 +/* The number of the last channel that services DCP0, connected to FMan 0.
5953 + * Value validated for B4 and T series platforms.
5954 + */
5955 +#define DCP0_MAX_CHANNEL 0x80f
5956 +/* A2V=1 - field A2 is valid
5957 + * A0V=1 - field A0 is valid - enables frame confirmation
5958 + * OVOM=1 - override operation mode bits with values from A2
5959 + * EBD=1 - external buffers are deallocated at the end of the FMan flow
5960 + * NL=0 - the BMI releases all the internal buffers
5961 + */
5962 +#define CEETM_CONTEXT_A 0x1a00000080000000
5963 +/* The ratio between the superior and inferior congestion state thresholds. The
5964 + * lower threshold is set to 7/8 of the superior one (as the default for WQ
5965 + * scheduling).
5966 + */
5967 +#define CEETM_CCGR_RATIO 0.875
5968 +/* For functional purposes, there are num_tx_queues pfifo qdiscs through which
5969 + * frames reach the driver. Their handles start from 1:21. Handles 1:1 to 1:20
5970 + * are reserved for the maximum 32 CEETM channels (majors and minors are in
5971 + * hex).
5972 + */
5973 +#define PFIFO_MIN_OFFSET 0x21
5974 +
5975 +/* A maximum of 8 CQs can be linked to a CQ channel or to a WBFS scheduler. */
5976 +#define CEETM_MAX_PRIO_QCOUNT 8
5977 +#define CEETM_MAX_WBFS_QCOUNT 8
5978 +#define CEETM_MIN_WBFS_QCOUNT 4
5979 +
5980 +/* The id offsets of the CQs belonging to WBFS groups (ids 8-11/15 for group A
5981 + * and/or 12-15 for group B).
5982 + */
5983 +#define WBFS_GRP_A_OFFSET 8
5984 +#define WBFS_GRP_B_OFFSET 12
5985 +
5986 +#define WBFS_GRP_A 1
5987 +#define WBFS_GRP_B 2
5988 +#define WBFS_GRP_LARGE 3
5989 +
5990 +enum {
5991 + TCA_CEETM_UNSPEC,
5992 + TCA_CEETM_COPT,
5993 + TCA_CEETM_QOPS,
5994 + __TCA_CEETM_MAX,
5995 +};
5996 +
5997 +/* CEETM configuration types */
5998 +enum {
5999 + CEETM_ROOT = 1,
6000 + CEETM_PRIO,
6001 + CEETM_WBFS
6002 +};
6003 +
6004 +#define TCA_CEETM_MAX (__TCA_CEETM_MAX - 1)
6005 +extern const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1];
6006 +
6007 +struct ceetm_class;
6008 +struct ceetm_qdisc_stats;
6009 +struct ceetm_class_stats;
6010 +
6011 +struct ceetm_fq {
6012 + struct qman_fq fq;
6013 + struct net_device *net_dev;
6014 + struct ceetm_class *ceetm_cls;
6015 +};
6016 +
6017 +struct root_q {
6018 + struct Qdisc **qdiscs;
6019 + __u16 overhead;
6020 + __u32 rate;
6021 + __u32 ceil;
6022 + struct qm_ceetm_sp *sp;
6023 + struct qm_ceetm_lni *lni;
6024 + struct ceetm_qdisc_stats __percpu *qstats;
6025 +};
6026 +
6027 +struct prio_q {
6028 + __u16 qcount;
6029 + struct ceetm_class *parent;
6030 +};
6031 +
6032 +struct wbfs_q {
6033 + __u16 qcount;
6034 + int group_type;
6035 + struct ceetm_class *parent;
6036 + __u16 cr;
6037 + __u16 er;
6038 +};
6039 +
6040 +struct ceetm_qdisc {
6041 + int type; /* LNI/CHNL/WBFS */
6042 + bool shaped;
6043 + union {
6044 + struct root_q root;
6045 + struct prio_q prio;
6046 + struct wbfs_q wbfs;
6047 + };
6048 + struct Qdisc_class_hash clhash;
6049 + struct tcf_proto *filter_list; /* qdisc attached filters */
6050 +};
6051 +
6052 +/* CEETM Qdisc configuration parameters */
6053 +struct tc_ceetm_qopt {
6054 + __u32 type;
6055 + __u16 shaped;
6056 + __u16 qcount;
6057 + __u16 overhead;
6058 + __u32 rate;
6059 + __u32 ceil;
6060 + __u16 cr;
6061 + __u16 er;
6062 + __u8 qweight[CEETM_MAX_WBFS_QCOUNT];
6063 +};
6064 +
6065 +struct root_c {
6066 + unsigned int rate;
6067 + unsigned int ceil;
6068 + unsigned int tbl;
6069 + bool wbfs_grp_a;
6070 + bool wbfs_grp_b;
6071 + bool wbfs_grp_large;
6072 + struct Qdisc *child;
6073 + struct qm_ceetm_channel *ch;
6074 +};
6075 +
6076 +struct prio_c {
6077 + bool cr;
6078 + bool er;
6079 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6080 + struct qm_ceetm_lfq *lfq;
6081 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6082 + struct qm_ceetm_ccg *ccg;
6083 + /* only one wbfs can be linked to one priority CQ */
6084 + struct Qdisc *child;
6085 + struct ceetm_class_stats __percpu *cstats;
6086 +};
6087 +
6088 +struct wbfs_c {
6089 + __u8 weight; /* The weight of the class between 1 and 248 */
6090 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6091 + struct qm_ceetm_lfq *lfq;
6092 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6093 + struct qm_ceetm_ccg *ccg;
6094 + struct ceetm_class_stats __percpu *cstats;
6095 +};
6096 +
6097 +struct ceetm_class {
6098 + struct Qdisc_class_common common;
6099 + int refcnt; /* usage count of this class */
6100 + struct tcf_proto *filter_list; /* class attached filters */
6101 + struct Qdisc *parent;
6102 + bool shaped;
6103 + int type; /* ROOT/PRIO/WBFS */
6104 + union {
6105 + struct root_c root;
6106 + struct prio_c prio;
6107 + struct wbfs_c wbfs;
6108 + };
6109 +};
6110 +
6111 +/* CEETM Class configuration parameters */
6112 +struct tc_ceetm_copt {
6113 + __u32 type;
6114 + __u16 shaped;
6115 + __u32 rate;
6116 + __u32 ceil;
6117 + __u16 tbl;
6118 + __u16 cr;
6119 + __u16 er;
6120 + __u8 weight;
6121 +};
6122 +
6123 +/* CEETM stats */
6124 +struct ceetm_qdisc_stats {
6125 + __u32 drops;
6126 +};
6127 +
6128 +struct ceetm_class_stats {
6129 + /* Software counters */
6130 + struct gnet_stats_basic_packed bstats;
6131 + __u32 ern_drop_count;
6132 + __u32 congested_count;
6133 +};
6134 +
6135 +struct tc_ceetm_xstats {
6136 + __u32 ern_drop_count;
6137 + __u32 congested_count;
6138 + /* Hardware counters */
6139 + __u64 frame_count;
6140 + __u64 byte_count;
6141 +};
6142 +
6143 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev);
6144 +#endif
6145 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
6146 new file mode 100644
6147 index 00000000..19a8a3c3
6148 --- /dev/null
6149 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
6150 @@ -0,0 +1,1820 @@
6151 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
6152 + *
6153 + * Redistribution and use in source and binary forms, with or without
6154 + * modification, are permitted provided that the following conditions are met:
6155 + * * Redistributions of source code must retain the above copyright
6156 + * notice, this list of conditions and the following disclaimer.
6157 + * * Redistributions in binary form must reproduce the above copyright
6158 + * notice, this list of conditions and the following disclaimer in the
6159 + * documentation and/or other materials provided with the distribution.
6160 + * * Neither the name of Freescale Semiconductor nor the
6161 + * names of its contributors may be used to endorse or promote products
6162 + * derived from this software without specific prior written permission.
6163 + *
6164 + *
6165 + * ALTERNATIVELY, this software may be distributed under the terms of the
6166 + * GNU General Public License ("GPL") as published by the Free Software
6167 + * Foundation, either version 2 of that License or (at your option) any
6168 + * later version.
6169 + *
6170 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
6171 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6172 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6173 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
6174 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6175 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6176 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6177 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6178 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6179 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6180 + */
6181 +
6182 +#include <linux/init.h>
6183 +#include <linux/module.h>
6184 +#include <linux/of_platform.h>
6185 +#include <linux/of_net.h>
6186 +#include <linux/etherdevice.h>
6187 +#include <linux/kthread.h>
6188 +#include <linux/percpu.h>
6189 +#include <linux/highmem.h>
6190 +#include <linux/sort.h>
6191 +#include <linux/fsl_qman.h>
6192 +#include <linux/ip.h>
6193 +#include <linux/ipv6.h>
6194 +#include <linux/if_vlan.h> /* vlan_eth_hdr */
6195 +#include "dpaa_eth.h"
6196 +#include "dpaa_eth_common.h"
6197 +#ifdef CONFIG_FSL_DPAA_1588
6198 +#include "dpaa_1588.h"
6199 +#endif
6200 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6201 +#include "dpaa_debugfs.h"
6202 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6203 +#include "mac.h"
6204 +
6205 +/* Size in bytes of the FQ taildrop threshold */
6206 +#define DPA_FQ_TD 0x200000
6207 +
6208 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6209 +struct ptp_priv_s ptp_priv;
6210 +#endif
6211 +
6212 +static struct dpa_bp *dpa_bp_array[64];
6213 +
6214 +int dpa_max_frm;
6215 +EXPORT_SYMBOL(dpa_max_frm);
6216 +
6217 +int dpa_rx_extra_headroom;
6218 +EXPORT_SYMBOL(dpa_rx_extra_headroom);
6219 +
6220 +int dpa_num_cpus = NR_CPUS;
6221 +
6222 +static const struct fqid_cell tx_confirm_fqids[] = {
6223 + {0, DPAA_ETH_TX_QUEUES}
6224 +};
6225 +
6226 +static struct fqid_cell default_fqids[][3] = {
6227 + [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} },
6228 + [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} }
6229 +};
6230 +
6231 +static const char fsl_qman_frame_queues[][25] = {
6232 + [RX] = "fsl,qman-frame-queues-rx",
6233 + [TX] = "fsl,qman-frame-queues-tx"
6234 +};
6235 +#ifdef CONFIG_FSL_DPAA_HOOKS
6236 +/* A set of callbacks for hooking into the fastpath at different points. */
6237 +struct dpaa_eth_hooks_s dpaa_eth_hooks;
6238 +EXPORT_SYMBOL(dpaa_eth_hooks);
6239 +/* This function should only be called on the probe paths, since it makes no
6240 + * effort to guarantee consistency of the destination hooks structure.
6241 + */
6242 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks)
6243 +{
6244 + if (hooks)
6245 + dpaa_eth_hooks = *hooks;
6246 + else
6247 + pr_err("NULL pointer to hooks!\n");
6248 +}
6249 +EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks);
6250 +#endif
6251 +
6252 +int dpa_netdev_init(struct net_device *net_dev,
6253 + const uint8_t *mac_addr,
6254 + uint16_t tx_timeout)
6255 +{
6256 + int err;
6257 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6258 + struct device *dev = net_dev->dev.parent;
6259 +
6260 + net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
6261 +
6262 + net_dev->features |= net_dev->hw_features;
6263 + net_dev->vlan_features = net_dev->features;
6264 +
6265 + memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
6266 + memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len);
6267 +
6268 + net_dev->ethtool_ops = &dpa_ethtool_ops;
6269 +
6270 + net_dev->needed_headroom = priv->tx_headroom;
6271 + net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
6272 +
6273 + err = register_netdev(net_dev);
6274 + if (err < 0) {
6275 + dev_err(dev, "register_netdev() = %d\n", err);
6276 + return err;
6277 + }
6278 +
6279 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6280 + /* create debugfs entry for this net_device */
6281 + err = dpa_netdev_debugfs_create(net_dev);
6282 + if (err) {
6283 + unregister_netdev(net_dev);
6284 + return err;
6285 + }
6286 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6287 +
6288 + return 0;
6289 +}
6290 +EXPORT_SYMBOL(dpa_netdev_init);
6291 +
6292 +int __cold dpa_start(struct net_device *net_dev)
6293 +{
6294 + int err, i;
6295 + struct dpa_priv_s *priv;
6296 + struct mac_device *mac_dev;
6297 +
6298 + priv = netdev_priv(net_dev);
6299 + mac_dev = priv->mac_dev;
6300 +
6301 + err = mac_dev->init_phy(net_dev, priv->mac_dev);
6302 + if (err < 0) {
6303 + if (netif_msg_ifup(priv))
6304 + netdev_err(net_dev, "init_phy() = %d\n", err);
6305 + return err;
6306 + }
6307 +
6308 + for_each_port_device(i, mac_dev->port_dev) {
6309 + err = fm_port_enable(mac_dev->port_dev[i]);
6310 + if (err)
6311 + goto mac_start_failed;
6312 + }
6313 +
6314 + err = priv->mac_dev->start(mac_dev);
6315 + if (err < 0) {
6316 + if (netif_msg_ifup(priv))
6317 + netdev_err(net_dev, "mac_dev->start() = %d\n", err);
6318 + goto mac_start_failed;
6319 + }
6320 +
6321 + netif_tx_start_all_queues(net_dev);
6322 +
6323 + return 0;
6324 +
6325 +mac_start_failed:
6326 + for_each_port_device(i, mac_dev->port_dev)
6327 + fm_port_disable(mac_dev->port_dev[i]);
6328 +
6329 + return err;
6330 +}
6331 +EXPORT_SYMBOL(dpa_start);
6332 +
6333 +int __cold dpa_stop(struct net_device *net_dev)
6334 +{
6335 + int _errno, i, err;
6336 + struct dpa_priv_s *priv;
6337 + struct mac_device *mac_dev;
6338 +
6339 + priv = netdev_priv(net_dev);
6340 + mac_dev = priv->mac_dev;
6341 +
6342 + netif_tx_stop_all_queues(net_dev);
6343 + /* Allow the Fman (Tx) port to process in-flight frames before we
6344 + * try switching it off.
6345 + */
6346 + usleep_range(5000, 10000);
6347 +
6348 + _errno = mac_dev->stop(mac_dev);
6349 + if (unlikely(_errno < 0))
6350 + if (netif_msg_ifdown(priv))
6351 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
6352 + _errno);
6353 +
6354 + for_each_port_device(i, mac_dev->port_dev) {
6355 + err = fm_port_disable(mac_dev->port_dev[i]);
6356 + _errno = err ? err : _errno;
6357 + }
6358 +
6359 + if (mac_dev->phy_dev)
6360 + phy_disconnect(mac_dev->phy_dev);
6361 + mac_dev->phy_dev = NULL;
6362 +
6363 + return _errno;
6364 +}
6365 +EXPORT_SYMBOL(dpa_stop);
6366 +
6367 +void __cold dpa_timeout(struct net_device *net_dev)
6368 +{
6369 + const struct dpa_priv_s *priv;
6370 + struct dpa_percpu_priv_s *percpu_priv;
6371 +
6372 + priv = netdev_priv(net_dev);
6373 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
6374 +
6375 + if (netif_msg_timer(priv))
6376 + netdev_crit(net_dev, "Transmit timeout!\n");
6377 +
6378 + percpu_priv->stats.tx_errors++;
6379 +}
6380 +EXPORT_SYMBOL(dpa_timeout);
6381 +
6382 +/* net_device */
6383 +
6384 +/**
6385 + * @param net_dev the device for which statistics are calculated
6386 + * @param stats the function fills this structure with the device's statistics
6387 + * @return the address of the structure containing the statistics
6388 + *
6389 + * Calculates the statistics for the given device by adding the statistics
6390 + * collected by each CPU.
6391 + */
6392 +void __cold
6393 +dpa_get_stats64(struct net_device *net_dev,
6394 + struct rtnl_link_stats64 *stats)
6395 +{
6396 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6397 + u64 *cpustats;
6398 + u64 *netstats = (u64 *)stats;
6399 + int i, j;
6400 + struct dpa_percpu_priv_s *percpu_priv;
6401 + int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64);
6402 +
6403 + for_each_possible_cpu(i) {
6404 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
6405 +
6406 + cpustats = (u64 *)&percpu_priv->stats;
6407 +
6408 + for (j = 0; j < numstats; j++)
6409 + netstats[j] += cpustats[j];
6410 + }
6411 +}
6412 +EXPORT_SYMBOL(dpa_get_stats64);
6413 +
6414 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu)
6415 +{
6416 + int max_mtu = dpa_get_max_mtu();
6417 +
6418 +#ifndef CONFIG_PPC
6419 + /* Due to the A010022 FMan errata, we can not use contig frames larger
6420 + * than 4K, nor S/G frames. We need to prevent the user from setting a
6421 + * large MTU.
6422 + */
6423 + if (unlikely(dpaa_errata_a010022))
6424 + max_mtu = DPA_BP_RAW_SIZE;
6425 +#endif
6426 +
6427 + /* Make sure we don't exceed the Ethernet controller's MAXFRM */
6428 + if (new_mtu < 68 || new_mtu > max_mtu) {
6429 + netdev_err(net_dev, "Invalid L3 mtu %d (must be between %d and %d).\n",
6430 + new_mtu, 68, max_mtu);
6431 + return -EINVAL;
6432 + }
6433 + net_dev->mtu = new_mtu;
6434 +
6435 + return 0;
6436 +}
6437 +EXPORT_SYMBOL(dpa_change_mtu);
6438 +
6439 +/* .ndo_init callback */
6440 +int dpa_ndo_init(struct net_device *net_dev)
6441 +{
6442 + /* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
6443 + * we choose conservatively and let the user explicitly set a higher
6444 + * MTU via ifconfig. Otherwise, the user may end up with different MTUs
6445 + * in the same LAN.
6446 + * If on the other hand fsl_fm_max_frm has been chosen below 1500,
6447 + * start with the maximum allowed.
6448 + */
6449 + int init_mtu = min(dpa_get_max_mtu(), ETH_DATA_LEN);
6450 +
6451 + pr_debug("Setting initial MTU on net device: %d\n", init_mtu);
6452 + net_dev->mtu = init_mtu;
6453 +
6454 + return 0;
6455 +}
6456 +EXPORT_SYMBOL(dpa_ndo_init);
6457 +
6458 +int dpa_set_features(struct net_device *dev, netdev_features_t features)
6459 +{
6460 + /* Not much to do here for now */
6461 + dev->features = features;
6462 + return 0;
6463 +}
6464 +EXPORT_SYMBOL(dpa_set_features);
6465 +
6466 +netdev_features_t dpa_fix_features(struct net_device *dev,
6467 + netdev_features_t features)
6468 +{
6469 + netdev_features_t unsupported_features = 0;
6470 +
6471 + /* In theory we should never be requested to enable features that
6472 + * we didn't set in netdev->features and netdev->hw_features at probe
6473 + * time, but double check just to be on the safe side.
6474 + * We don't support enabling Rx csum through ethtool yet
6475 + */
6476 + unsupported_features |= NETIF_F_RXCSUM;
6477 +
6478 + features &= ~unsupported_features;
6479 +
6480 + return features;
6481 +}
6482 +EXPORT_SYMBOL(dpa_fix_features);
6483 +
6484 +#ifdef CONFIG_FSL_DPAA_TS
6485 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx,
6486 + const void *data)
6487 +{
6488 + u64 *ts, ns;
6489 +
6490 + ts = fm_port_get_buffer_time_stamp(priv->mac_dev->port_dev[rx_tx],
6491 + data);
6492 +
6493 + if (!ts || *ts == 0)
6494 + return 0;
6495 +
6496 + be64_to_cpus(ts);
6497 +
6498 + /* multiple DPA_PTP_NOMINAL_FREQ_PERIOD_NS for case of non power of 2 */
6499 + ns = *ts << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT;
6500 +
6501 + return ns;
6502 +}
6503 +
6504 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
6505 + struct skb_shared_hwtstamps *shhwtstamps, const void *data)
6506 +{
6507 + u64 ns;
6508 +
6509 + ns = dpa_get_timestamp_ns(priv, rx_tx, data);
6510 +
6511 + if (ns == 0)
6512 + return -EINVAL;
6513 +
6514 + memset(shhwtstamps, 0, sizeof(*shhwtstamps));
6515 + shhwtstamps->hwtstamp = ns_to_ktime(ns);
6516 +
6517 + return 0;
6518 +}
6519 +
6520 +static void dpa_ts_tx_enable(struct net_device *dev)
6521 +{
6522 + struct dpa_priv_s *priv = netdev_priv(dev);
6523 + struct mac_device *mac_dev = priv->mac_dev;
6524 +
6525 + if (mac_dev->fm_rtc_enable)
6526 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6527 + if (mac_dev->ptp_enable)
6528 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6529 +
6530 + priv->ts_tx_en = true;
6531 +}
6532 +
6533 +static void dpa_ts_tx_disable(struct net_device *dev)
6534 +{
6535 + struct dpa_priv_s *priv = netdev_priv(dev);
6536 +
6537 +#if 0
6538 +/* the RTC might be needed by the Rx Ts, cannot disable here
6539 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6540 + */
6541 + struct mac_device *mac_dev = priv->mac_dev;
6542 +
6543 + if (mac_dev->fm_rtc_disable)
6544 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6545 +
6546 + if (mac_dev->ptp_disable)
6547 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6548 +#endif
6549 +
6550 + priv->ts_tx_en = false;
6551 +}
6552 +
6553 +static void dpa_ts_rx_enable(struct net_device *dev)
6554 +{
6555 + struct dpa_priv_s *priv = netdev_priv(dev);
6556 + struct mac_device *mac_dev = priv->mac_dev;
6557 +
6558 + if (mac_dev->fm_rtc_enable)
6559 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6560 + if (mac_dev->ptp_enable)
6561 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6562 +
6563 + priv->ts_rx_en = true;
6564 +}
6565 +
6566 +static void dpa_ts_rx_disable(struct net_device *dev)
6567 +{
6568 + struct dpa_priv_s *priv = netdev_priv(dev);
6569 +
6570 +#if 0
6571 +/* the RTC might be needed by the Tx Ts, cannot disable here
6572 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6573 + */
6574 + struct mac_device *mac_dev = priv->mac_dev;
6575 +
6576 + if (mac_dev->fm_rtc_disable)
6577 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6578 +
6579 + if (mac_dev->ptp_disable)
6580 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6581 +#endif
6582 +
6583 + priv->ts_rx_en = false;
6584 +}
6585 +
6586 +static int dpa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6587 +{
6588 + struct hwtstamp_config config;
6589 +
6590 + if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
6591 + return -EFAULT;
6592 +
6593 + switch (config.tx_type) {
6594 + case HWTSTAMP_TX_OFF:
6595 + dpa_ts_tx_disable(dev);
6596 + break;
6597 + case HWTSTAMP_TX_ON:
6598 + dpa_ts_tx_enable(dev);
6599 + break;
6600 + default:
6601 + return -ERANGE;
6602 + }
6603 +
6604 + if (config.rx_filter == HWTSTAMP_FILTER_NONE)
6605 + dpa_ts_rx_disable(dev);
6606 + else {
6607 + dpa_ts_rx_enable(dev);
6608 + /* TS is set for all frame types, not only those requested */
6609 + config.rx_filter = HWTSTAMP_FILTER_ALL;
6610 + }
6611 +
6612 + return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
6613 + -EFAULT : 0;
6614 +}
6615 +#endif /* CONFIG_FSL_DPAA_TS */
6616 +
6617 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6618 +{
6619 +#ifdef CONFIG_FSL_DPAA_1588
6620 + struct dpa_priv_s *priv = netdev_priv(dev);
6621 +#endif
6622 + int ret = 0;
6623 +
6624 + /* at least one timestamping feature must be enabled */
6625 +#ifdef CONFIG_FSL_DPAA_TS
6626 + if (!netif_running(dev))
6627 +#endif
6628 + return -EINVAL;
6629 +
6630 +#ifdef CONFIG_FSL_DPAA_TS
6631 + if (cmd == SIOCSHWTSTAMP)
6632 + return dpa_ts_ioctl(dev, rq, cmd);
6633 +#endif /* CONFIG_FSL_DPAA_TS */
6634 +
6635 +#ifdef CONFIG_FSL_DPAA_1588
6636 + if ((cmd >= PTP_ENBL_TXTS_IOCTL) && (cmd <= PTP_CLEANUP_TS)) {
6637 + if (priv->tsu && priv->tsu->valid)
6638 + ret = dpa_ioctl_1588(dev, rq, cmd);
6639 + else
6640 + ret = -ENODEV;
6641 + }
6642 +#endif
6643 +
6644 + return ret;
6645 +}
6646 +EXPORT_SYMBOL(dpa_ioctl);
6647 +
6648 +int __cold dpa_remove(struct platform_device *of_dev)
6649 +{
6650 + int err;
6651 + struct device *dev;
6652 + struct net_device *net_dev;
6653 + struct dpa_priv_s *priv;
6654 +
6655 + dev = &of_dev->dev;
6656 + net_dev = dev_get_drvdata(dev);
6657 +
6658 + priv = netdev_priv(net_dev);
6659 +
6660 + dpaa_eth_sysfs_remove(dev);
6661 +
6662 + dev_set_drvdata(dev, NULL);
6663 + unregister_netdev(net_dev);
6664 +
6665 + err = dpa_fq_free(dev, &priv->dpa_fq_list);
6666 +
6667 + qman_delete_cgr_safe(&priv->ingress_cgr);
6668 + qman_release_cgrid(priv->ingress_cgr.cgrid);
6669 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
6670 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
6671 +
6672 + dpa_private_napi_del(net_dev);
6673 +
6674 + dpa_bp_free(priv);
6675 +
6676 + if (priv->buf_layout)
6677 + devm_kfree(dev, priv->buf_layout);
6678 +
6679 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6680 + /* remove debugfs entry for this net_device */
6681 + dpa_netdev_debugfs_remove(net_dev);
6682 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6683 +
6684 +#ifdef CONFIG_FSL_DPAA_1588
6685 + if (priv->tsu && priv->tsu->valid)
6686 + dpa_ptp_cleanup(priv);
6687 +#endif
6688 +
6689 + free_netdev(net_dev);
6690 +
6691 + return err;
6692 +}
6693 +EXPORT_SYMBOL(dpa_remove);
6694 +
6695 +struct mac_device * __cold __must_check
6696 +__attribute__((nonnull))
6697 +dpa_mac_probe(struct platform_device *_of_dev)
6698 +{
6699 + struct device *dpa_dev, *dev;
6700 + struct device_node *mac_node;
6701 + struct platform_device *of_dev;
6702 + struct mac_device *mac_dev;
6703 +#ifdef CONFIG_FSL_DPAA_1588
6704 + int lenp;
6705 + const phandle *phandle_prop;
6706 + struct net_device *net_dev = NULL;
6707 + struct dpa_priv_s *priv = NULL;
6708 + struct device_node *timer_node;
6709 +#endif
6710 + dpa_dev = &_of_dev->dev;
6711 +
6712 + mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0);
6713 + if (unlikely(mac_node == NULL)) {
6714 + dev_err(dpa_dev, "Cannot find MAC device device tree node\n");
6715 + return ERR_PTR(-EFAULT);
6716 + }
6717 +
6718 + of_dev = of_find_device_by_node(mac_node);
6719 + if (unlikely(of_dev == NULL)) {
6720 + dev_err(dpa_dev, "of_find_device_by_node(%s) failed\n",
6721 + mac_node->full_name);
6722 + of_node_put(mac_node);
6723 + return ERR_PTR(-EINVAL);
6724 + }
6725 + of_node_put(mac_node);
6726 +
6727 + dev = &of_dev->dev;
6728 +
6729 + mac_dev = dev_get_drvdata(dev);
6730 + if (unlikely(mac_dev == NULL)) {
6731 + dev_err(dpa_dev, "dev_get_drvdata(%s) failed\n",
6732 + dev_name(dev));
6733 + return ERR_PTR(-EINVAL);
6734 + }
6735 +
6736 +#ifdef CONFIG_FSL_DPAA_1588
6737 + phandle_prop = of_get_property(mac_node, "ptp-timer", &lenp);
6738 + if (phandle_prop && ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6739 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6740 + (mac_dev->speed == SPEED_1000)))) {
6741 + timer_node = of_find_node_by_phandle(*phandle_prop);
6742 + if (timer_node)
6743 + net_dev = dev_get_drvdata(dpa_dev);
6744 + if (timer_node && net_dev) {
6745 + priv = netdev_priv(net_dev);
6746 + if (!dpa_ptp_init(priv))
6747 + dev_info(dev, "%s: ptp 1588 is initialized.\n",
6748 + mac_node->full_name);
6749 + }
6750 + }
6751 +#endif
6752 +
6753 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6754 + if ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6755 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6756 + (mac_dev->speed == SPEED_1000))) {
6757 + ptp_priv.node = of_parse_phandle(mac_node, "ptp-timer", 0);
6758 + if (ptp_priv.node) {
6759 + ptp_priv.of_dev = of_find_device_by_node(ptp_priv.node);
6760 + if (unlikely(ptp_priv.of_dev == NULL)) {
6761 + dev_err(dpa_dev,
6762 + "Cannot find device represented by timer_node\n");
6763 + of_node_put(ptp_priv.node);
6764 + return ERR_PTR(-EINVAL);
6765 + }
6766 + ptp_priv.mac_dev = mac_dev;
6767 + }
6768 + }
6769 +#endif
6770 + return mac_dev;
6771 +}
6772 +EXPORT_SYMBOL(dpa_mac_probe);
6773 +
6774 +int dpa_set_mac_address(struct net_device *net_dev, void *addr)
6775 +{
6776 + const struct dpa_priv_s *priv;
6777 + int _errno;
6778 + struct mac_device *mac_dev;
6779 +
6780 + priv = netdev_priv(net_dev);
6781 +
6782 + _errno = eth_mac_addr(net_dev, addr);
6783 + if (_errno < 0) {
6784 + if (netif_msg_drv(priv))
6785 + netdev_err(net_dev,
6786 + "eth_mac_addr() = %d\n",
6787 + _errno);
6788 + return _errno;
6789 + }
6790 +
6791 + mac_dev = priv->mac_dev;
6792 +
6793 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
6794 + net_dev->dev_addr);
6795 + if (_errno < 0) {
6796 + if (netif_msg_drv(priv))
6797 + netdev_err(net_dev,
6798 + "mac_dev->change_addr() = %d\n",
6799 + _errno);
6800 + return _errno;
6801 + }
6802 +
6803 + return 0;
6804 +}
6805 +EXPORT_SYMBOL(dpa_set_mac_address);
6806 +
6807 +void dpa_set_rx_mode(struct net_device *net_dev)
6808 +{
6809 + int _errno;
6810 + const struct dpa_priv_s *priv;
6811 +
6812 + priv = netdev_priv(net_dev);
6813 +
6814 + if (!!(net_dev->flags & IFF_PROMISC) != priv->mac_dev->promisc) {
6815 + priv->mac_dev->promisc = !priv->mac_dev->promisc;
6816 + _errno = priv->mac_dev->set_promisc(
6817 + priv->mac_dev->get_mac_handle(priv->mac_dev),
6818 + priv->mac_dev->promisc);
6819 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6820 + netdev_err(net_dev,
6821 + "mac_dev->set_promisc() = %d\n",
6822 + _errno);
6823 + }
6824 +
6825 + _errno = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
6826 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6827 + netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno);
6828 +}
6829 +EXPORT_SYMBOL(dpa_set_rx_mode);
6830 +
6831 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
6832 + struct dpa_buffer_layout_s *layout)
6833 +{
6834 + struct fm_port_params params;
6835 +
6836 + /* Rx */
6837 + layout[RX].priv_data_size = (uint16_t)DPA_RX_PRIV_DATA_SIZE;
6838 + layout[RX].parse_results = true;
6839 + layout[RX].hash_results = true;
6840 +#ifdef CONFIG_FSL_DPAA_TS
6841 + layout[RX].time_stamp = true;
6842 +#endif
6843 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[RX], &params);
6844 + layout[RX].manip_extra_space = params.manip_extra_space;
6845 + /* a value of zero for data alignment means "don't care", so align to
6846 + * a non-zero value to prevent FMD from using its own default
6847 + */
6848 + layout[RX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6849 +
6850 + /* Tx */
6851 + layout[TX].priv_data_size = DPA_TX_PRIV_DATA_SIZE;
6852 + layout[TX].parse_results = true;
6853 + layout[TX].hash_results = true;
6854 +#ifdef CONFIG_FSL_DPAA_TS
6855 + layout[TX].time_stamp = true;
6856 +#endif
6857 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[TX], &params);
6858 + layout[TX].manip_extra_space = params.manip_extra_space;
6859 + layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6860 +}
6861 +EXPORT_SYMBOL(dpa_set_buffers_layout);
6862 +
6863 +int __attribute__((nonnull))
6864 +dpa_bp_alloc(struct dpa_bp *dpa_bp)
6865 +{
6866 + int err;
6867 + struct bman_pool_params bp_params;
6868 + struct platform_device *pdev;
6869 +
6870 + if (dpa_bp->size == 0 || dpa_bp->config_count == 0) {
6871 + pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers");
6872 + return -EINVAL;
6873 + }
6874 +
6875 + memset(&bp_params, 0, sizeof(struct bman_pool_params));
6876 +#ifdef CONFIG_FMAN_PFC
6877 + bp_params.flags = BMAN_POOL_FLAG_THRESH;
6878 + bp_params.thresholds[0] = bp_params.thresholds[2] =
6879 + CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD;
6880 + bp_params.thresholds[1] = bp_params.thresholds[3] =
6881 + CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
6882 +#endif
6883 +
6884 + /* If the pool is already specified, we only create one per bpid */
6885 + if (dpa_bpid2pool_use(dpa_bp->bpid))
6886 + return 0;
6887 +
6888 + if (dpa_bp->bpid == 0)
6889 + bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID;
6890 + else
6891 + bp_params.bpid = dpa_bp->bpid;
6892 +
6893 + dpa_bp->pool = bman_new_pool(&bp_params);
6894 + if (unlikely(dpa_bp->pool == NULL)) {
6895 + pr_err("bman_new_pool() failed\n");
6896 + return -ENODEV;
6897 + }
6898 +
6899 + dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid;
6900 +
6901 + pdev = platform_device_register_simple("dpaa_eth_bpool",
6902 + dpa_bp->bpid, NULL, 0);
6903 + if (IS_ERR(pdev)) {
6904 + pr_err("platform_device_register_simple() failed\n");
6905 + err = PTR_ERR(pdev);
6906 + goto pdev_register_failed;
6907 + }
6908 + {
6909 + struct dma_map_ops *ops = get_dma_ops(&pdev->dev);
6910 + ops->dma_supported = NULL;
6911 + }
6912 + err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40));
6913 + if (err) {
6914 + pr_err("dma_coerce_mask_and_coherent() failed\n");
6915 + goto pdev_mask_failed;
6916 + }
6917 +#ifdef CONFIG_FMAN_ARM
6918 + /* force coherency */
6919 + pdev->dev.archdata.dma_coherent = true;
6920 + arch_setup_dma_ops(&pdev->dev, 0, 0, NULL, true);
6921 +#endif
6922 +
6923 + dpa_bp->dev = &pdev->dev;
6924 +
6925 + if (dpa_bp->seed_cb) {
6926 + err = dpa_bp->seed_cb(dpa_bp);
6927 + if (err)
6928 + goto pool_seed_failed;
6929 + }
6930 +
6931 + dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp);
6932 +
6933 + return 0;
6934 +
6935 +pool_seed_failed:
6936 +pdev_mask_failed:
6937 + platform_device_unregister(pdev);
6938 +pdev_register_failed:
6939 + bman_free_pool(dpa_bp->pool);
6940 +
6941 + return err;
6942 +}
6943 +EXPORT_SYMBOL(dpa_bp_alloc);
6944 +
6945 +void dpa_bp_drain(struct dpa_bp *bp)
6946 +{
6947 + int ret, num = 8;
6948 +
6949 + do {
6950 + struct bm_buffer bmb[8];
6951 + int i;
6952 +
6953 + ret = bman_acquire(bp->pool, bmb, num, 0);
6954 + if (ret < 0) {
6955 + if (num == 8) {
6956 + /* we have less than 8 buffers left;
6957 + * drain them one by one
6958 + */
6959 + num = 1;
6960 + ret = 1;
6961 + continue;
6962 + } else {
6963 + /* Pool is fully drained */
6964 + break;
6965 + }
6966 + }
6967 +
6968 + for (i = 0; i < num; i++) {
6969 + dma_addr_t addr = bm_buf_addr(&bmb[i]);
6970 +
6971 + dma_unmap_single(bp->dev, addr, bp->size,
6972 + DMA_BIDIRECTIONAL);
6973 +
6974 + bp->free_buf_cb(phys_to_virt(addr));
6975 + }
6976 + } while (ret > 0);
6977 +}
6978 +EXPORT_SYMBOL(dpa_bp_drain);
6979 +
6980 +static void __cold __attribute__((nonnull))
6981 +_dpa_bp_free(struct dpa_bp *dpa_bp)
6982 +{
6983 + struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid);
6984 +
6985 + /* the mapping between bpid and dpa_bp is done very late in the
6986 + * allocation procedure; if something failed before the mapping, the bp
6987 + * was not configured, therefore we don't need the below instructions
6988 + */
6989 + if (!bp)
6990 + return;
6991 +
6992 + if (!atomic_dec_and_test(&bp->refs))
6993 + return;
6994 +
6995 + if (bp->free_buf_cb)
6996 + dpa_bp_drain(bp);
6997 +
6998 + dpa_bp_array[bp->bpid] = NULL;
6999 + bman_free_pool(bp->pool);
7000 +
7001 + if (bp->dev)
7002 + platform_device_unregister(to_platform_device(bp->dev));
7003 +}
7004 +
7005 +void __cold __attribute__((nonnull))
7006 +dpa_bp_free(struct dpa_priv_s *priv)
7007 +{
7008 + int i;
7009 +
7010 + if (priv->dpa_bp)
7011 + for (i = 0; i < priv->bp_count; i++)
7012 + _dpa_bp_free(&priv->dpa_bp[i]);
7013 +}
7014 +EXPORT_SYMBOL(dpa_bp_free);
7015 +
7016 +struct dpa_bp *dpa_bpid2pool(int bpid)
7017 +{
7018 + return dpa_bp_array[bpid];
7019 +}
7020 +EXPORT_SYMBOL(dpa_bpid2pool);
7021 +
7022 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp)
7023 +{
7024 + dpa_bp_array[bpid] = dpa_bp;
7025 + atomic_set(&dpa_bp->refs, 1);
7026 +}
7027 +
7028 +bool dpa_bpid2pool_use(int bpid)
7029 +{
7030 + if (dpa_bpid2pool(bpid)) {
7031 + atomic_inc(&dpa_bp_array[bpid]->refs);
7032 + return true;
7033 + }
7034 +
7035 + return false;
7036 +}
7037 +
7038 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
7039 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
7040 + void *accel_priv, select_queue_fallback_t fallback)
7041 +{
7042 + return dpa_get_queue_mapping(skb);
7043 +}
7044 +EXPORT_SYMBOL(dpa_select_queue);
7045 +#endif
7046 +
7047 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
7048 + u32 fq_start,
7049 + u32 fq_count,
7050 + struct list_head *list,
7051 + enum dpa_fq_type fq_type)
7052 +{
7053 + int i;
7054 + struct dpa_fq *dpa_fq;
7055 +
7056 + dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fq_count, GFP_KERNEL);
7057 + if (dpa_fq == NULL)
7058 + return NULL;
7059 +
7060 + for (i = 0; i < fq_count; i++) {
7061 + dpa_fq[i].fq_type = fq_type;
7062 + if (fq_type == FQ_TYPE_RX_PCD_HI_PRIO)
7063 + dpa_fq[i].fqid = fq_start ?
7064 + DPAA_ETH_FQ_DELTA + fq_start + i : 0;
7065 + else
7066 + dpa_fq[i].fqid = fq_start ? fq_start + i : 0;
7067 +
7068 + list_add_tail(&dpa_fq[i].list, list);
7069 + }
7070 +
7071 +#ifdef CONFIG_FMAN_PFC
7072 + if (fq_type == FQ_TYPE_TX)
7073 + for (i = 0; i < fq_count; i++)
7074 + dpa_fq[i].wq = i / dpa_num_cpus;
7075 + else
7076 +#endif
7077 + for (i = 0; i < fq_count; i++)
7078 + _dpa_assign_wq(dpa_fq + i);
7079 +
7080 + return dpa_fq;
7081 +}
7082 +EXPORT_SYMBOL(dpa_fq_alloc);
7083 +
7084 +/* Probing of FQs for MACful ports */
7085 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
7086 + struct fm_port_fqs *port_fqs,
7087 + bool alloc_tx_conf_fqs,
7088 + enum port_type ptype)
7089 +{
7090 + struct fqid_cell *fqids = NULL;
7091 + const void *fqids_off = NULL;
7092 + struct dpa_fq *dpa_fq = NULL;
7093 + struct device_node *np = dev->of_node;
7094 + int num_ranges;
7095 + int i, lenp;
7096 +
7097 + if (ptype == TX && alloc_tx_conf_fqs) {
7098 + if (!dpa_fq_alloc(dev, tx_confirm_fqids->start,
7099 + tx_confirm_fqids->count, list,
7100 + FQ_TYPE_TX_CONF_MQ))
7101 + goto fq_alloc_failed;
7102 + }
7103 +
7104 + fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
7105 + if (fqids_off == NULL) {
7106 + /* No dts definition, so use the defaults. */
7107 + fqids = default_fqids[ptype];
7108 + num_ranges = 3;
7109 + } else {
7110 + num_ranges = lenp / sizeof(*fqids);
7111 +
7112 + fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges,
7113 + GFP_KERNEL);
7114 + if (fqids == NULL)
7115 + goto fqids_alloc_failed;
7116 +
7117 + /* convert to CPU endianess */
7118 + for (i = 0; i < num_ranges; i++) {
7119 + fqids[i].start = be32_to_cpup(fqids_off +
7120 + i * sizeof(*fqids));
7121 + fqids[i].count = be32_to_cpup(fqids_off +
7122 + i * sizeof(*fqids) + sizeof(__be32));
7123 + }
7124 + }
7125 +
7126 + for (i = 0; i < num_ranges; i++) {
7127 + switch (i) {
7128 + case 0:
7129 + /* The first queue is the error queue */
7130 + if (fqids[i].count != 1)
7131 + goto invalid_error_queue;
7132 +
7133 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7134 + fqids[i].count, list,
7135 + ptype == RX ?
7136 + FQ_TYPE_RX_ERROR :
7137 + FQ_TYPE_TX_ERROR);
7138 + if (dpa_fq == NULL)
7139 + goto fq_alloc_failed;
7140 +
7141 + if (ptype == RX)
7142 + port_fqs->rx_errq = &dpa_fq[0];
7143 + else
7144 + port_fqs->tx_errq = &dpa_fq[0];
7145 + break;
7146 + case 1:
7147 + /* the second queue is the default queue */
7148 + if (fqids[i].count != 1)
7149 + goto invalid_default_queue;
7150 +
7151 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7152 + fqids[i].count, list,
7153 + ptype == RX ?
7154 + FQ_TYPE_RX_DEFAULT :
7155 + FQ_TYPE_TX_CONFIRM);
7156 + if (dpa_fq == NULL)
7157 + goto fq_alloc_failed;
7158 +
7159 + if (ptype == RX)
7160 + port_fqs->rx_defq = &dpa_fq[0];
7161 + else
7162 + port_fqs->tx_defq = &dpa_fq[0];
7163 + break;
7164 + default:
7165 + /* all subsequent queues are either RX* PCD or Tx */
7166 + if (ptype == RX) {
7167 + if (!dpa_fq_alloc(dev, fqids[i].start,
7168 + fqids[i].count, list,
7169 + FQ_TYPE_RX_PCD) ||
7170 + !dpa_fq_alloc(dev, fqids[i].start,
7171 + fqids[i].count, list,
7172 + FQ_TYPE_RX_PCD_HI_PRIO))
7173 + goto fq_alloc_failed;
7174 + } else {
7175 + if (!dpa_fq_alloc(dev, fqids[i].start,
7176 + fqids[i].count, list,
7177 + FQ_TYPE_TX))
7178 + goto fq_alloc_failed;
7179 + }
7180 + break;
7181 + }
7182 + }
7183 +
7184 + return 0;
7185 +
7186 +fq_alloc_failed:
7187 +fqids_alloc_failed:
7188 + dev_err(dev, "Cannot allocate memory for frame queues\n");
7189 + return -ENOMEM;
7190 +
7191 +invalid_default_queue:
7192 +invalid_error_queue:
7193 + dev_err(dev, "Too many default or error queues\n");
7194 + return -EINVAL;
7195 +}
7196 +EXPORT_SYMBOL(dpa_fq_probe_mac);
7197 +
7198 +static u32 rx_pool_channel;
7199 +static DEFINE_SPINLOCK(rx_pool_channel_init);
7200 +
7201 +int dpa_get_channel(void)
7202 +{
7203 + spin_lock(&rx_pool_channel_init);
7204 + if (!rx_pool_channel) {
7205 + u32 pool;
7206 + int ret = qman_alloc_pool(&pool);
7207 + if (!ret)
7208 + rx_pool_channel = pool;
7209 + }
7210 + spin_unlock(&rx_pool_channel_init);
7211 + if (!rx_pool_channel)
7212 + return -ENOMEM;
7213 + return rx_pool_channel;
7214 +}
7215 +EXPORT_SYMBOL(dpa_get_channel);
7216 +
7217 +void dpa_release_channel(void)
7218 +{
7219 + qman_release_pool(rx_pool_channel);
7220 +}
7221 +EXPORT_SYMBOL(dpa_release_channel);
7222 +
7223 +void dpaa_eth_add_channel(u16 channel)
7224 +{
7225 + const cpumask_t *cpus = qman_affine_cpus();
7226 + u32 pool = QM_SDQCR_CHANNELS_POOL_CONV(channel);
7227 + int cpu;
7228 + struct qman_portal *portal;
7229 +
7230 + for_each_cpu(cpu, cpus) {
7231 + portal = (struct qman_portal *)qman_get_affine_portal(cpu);
7232 + qman_p_static_dequeue_add(portal, pool);
7233 + }
7234 +}
7235 +EXPORT_SYMBOL(dpaa_eth_add_channel);
7236 +
7237 +/**
7238 + * Congestion group state change notification callback.
7239 + * Stops the device's egress queues while they are congested and
7240 + * wakes them upon exiting congested state.
7241 + * Also updates some CGR-related stats.
7242 + */
7243 +static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr,
7244 +
7245 + int congested)
7246 +{
7247 + struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr,
7248 + struct dpa_priv_s, cgr_data.cgr);
7249 +
7250 + if (congested) {
7251 + priv->cgr_data.congestion_start_jiffies = jiffies;
7252 + netif_tx_stop_all_queues(priv->net_dev);
7253 + priv->cgr_data.cgr_congested_count++;
7254 + } else {
7255 + priv->cgr_data.congested_jiffies +=
7256 + (jiffies - priv->cgr_data.congestion_start_jiffies);
7257 + netif_tx_wake_all_queues(priv->net_dev);
7258 + }
7259 +}
7260 +
7261 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv)
7262 +{
7263 + struct qm_mcc_initcgr initcgr;
7264 + u32 cs_th;
7265 + int err;
7266 +
7267 + err = qman_alloc_cgrid(&priv->cgr_data.cgr.cgrid);
7268 + if (err < 0) {
7269 + pr_err("Error %d allocating CGR ID\n", err);
7270 + goto out_error;
7271 + }
7272 + priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
7273 +
7274 + /* Enable Congestion State Change Notifications and CS taildrop */
7275 + initcgr.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES;
7276 + initcgr.cgr.cscn_en = QM_CGR_EN;
7277 +
7278 + /* Set different thresholds based on the MAC speed.
7279 + * TODO: this may turn suboptimal if the MAC is reconfigured at a speed
7280 + * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
7281 + * In such cases, we ought to reconfigure the threshold, too.
7282 + */
7283 + if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
7284 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
7285 + else
7286 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
7287 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
7288 +
7289 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
7290 + initcgr.cgr.cstd_en = QM_CGR_EN;
7291 +
7292 + err = qman_create_cgr(&priv->cgr_data.cgr, QMAN_CGR_FLAG_USE_INIT,
7293 + &initcgr);
7294 + if (err < 0) {
7295 + pr_err("Error %d creating CGR with ID %d\n", err,
7296 + priv->cgr_data.cgr.cgrid);
7297 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
7298 + goto out_error;
7299 + }
7300 + pr_debug("Created CGR %d for netdev with hwaddr %pM on QMan channel %d\n",
7301 + priv->cgr_data.cgr.cgrid, priv->mac_dev->addr,
7302 + priv->cgr_data.cgr.chan);
7303 +
7304 +out_error:
7305 + return err;
7306 +}
7307 +EXPORT_SYMBOL(dpaa_eth_cgr_init);
7308 +
7309 +static inline void dpa_setup_ingress(const struct dpa_priv_s *priv,
7310 + struct dpa_fq *fq,
7311 + const struct qman_fq *template)
7312 +{
7313 + fq->fq_base = *template;
7314 + fq->net_dev = priv->net_dev;
7315 +
7316 + fq->flags = QMAN_FQ_FLAG_NO_ENQUEUE;
7317 + fq->channel = priv->channel;
7318 +}
7319 +
7320 +static inline void dpa_setup_egress(const struct dpa_priv_s *priv,
7321 + struct dpa_fq *fq,
7322 + struct fm_port *port,
7323 + const struct qman_fq *template)
7324 +{
7325 + fq->fq_base = *template;
7326 + fq->net_dev = priv->net_dev;
7327 +
7328 + if (port) {
7329 + fq->flags = QMAN_FQ_FLAG_TO_DCPORTAL;
7330 + fq->channel = (uint16_t)fm_get_tx_port_channel(port);
7331 + } else {
7332 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
7333 + }
7334 +}
7335 +
7336 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
7337 + struct fm_port *tx_port)
7338 +{
7339 + struct dpa_fq *fq;
7340 + uint16_t portals[NR_CPUS];
7341 + int cpu, portal_cnt = 0, num_portals = 0;
7342 + uint32_t pcd_fqid, pcd_fqid_hi_prio;
7343 + const cpumask_t *affine_cpus = qman_affine_cpus();
7344 + int egress_cnt = 0, conf_cnt = 0;
7345 +
7346 + /* Prepare for PCD FQs init */
7347 + for_each_cpu(cpu, affine_cpus)
7348 + portals[num_portals++] = qman_affine_channel(cpu);
7349 + if (num_portals == 0)
7350 + dev_err(priv->net_dev->dev.parent,
7351 + "No Qman software (affine) channels found");
7352 +
7353 + pcd_fqid = (priv->mac_dev) ?
7354 + DPAA_ETH_PCD_FQ_BASE(priv->mac_dev->res->start) : 0;
7355 + pcd_fqid_hi_prio = (priv->mac_dev) ?
7356 + DPAA_ETH_PCD_FQ_HI_PRIO_BASE(priv->mac_dev->res->start) : 0;
7357 +
7358 + /* Initialize each FQ in the list */
7359 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7360 + switch (fq->fq_type) {
7361 + case FQ_TYPE_RX_DEFAULT:
7362 + BUG_ON(!priv->mac_dev);
7363 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7364 + break;
7365 + case FQ_TYPE_RX_ERROR:
7366 + BUG_ON(!priv->mac_dev);
7367 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_errq);
7368 + break;
7369 + case FQ_TYPE_RX_PCD:
7370 + /* For MACless we can't have dynamic Rx queues */
7371 + BUG_ON(!priv->mac_dev && !fq->fqid);
7372 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7373 + if (!fq->fqid)
7374 + fq->fqid = pcd_fqid++;
7375 + fq->channel = portals[portal_cnt];
7376 + portal_cnt = (portal_cnt + 1) % num_portals;
7377 + break;
7378 + case FQ_TYPE_RX_PCD_HI_PRIO:
7379 + /* For MACless we can't have dynamic Hi Pri Rx queues */
7380 + BUG_ON(!priv->mac_dev && !fq->fqid);
7381 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7382 + if (!fq->fqid)
7383 + fq->fqid = pcd_fqid_hi_prio++;
7384 + fq->channel = portals[portal_cnt];
7385 + portal_cnt = (portal_cnt + 1) % num_portals;
7386 + break;
7387 + case FQ_TYPE_TX:
7388 + dpa_setup_egress(priv, fq, tx_port,
7389 + &fq_cbs->egress_ern);
7390 + /* If we have more Tx queues than the number of cores,
7391 + * just ignore the extra ones.
7392 + */
7393 + if (egress_cnt < DPAA_ETH_TX_QUEUES)
7394 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7395 + break;
7396 + case FQ_TYPE_TX_CONFIRM:
7397 + BUG_ON(!priv->mac_dev);
7398 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7399 + break;
7400 + case FQ_TYPE_TX_CONF_MQ:
7401 + BUG_ON(!priv->mac_dev);
7402 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7403 + priv->conf_fqs[conf_cnt++] = &fq->fq_base;
7404 + break;
7405 + case FQ_TYPE_TX_ERROR:
7406 + BUG_ON(!priv->mac_dev);
7407 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_errq);
7408 + break;
7409 + default:
7410 + dev_warn(priv->net_dev->dev.parent,
7411 + "Unknown FQ type detected!\n");
7412 + break;
7413 + }
7414 + }
7415 +
7416 + /* The number of Tx queues may be smaller than the number of cores, if
7417 + * the Tx queue range is specified in the device tree instead of being
7418 + * dynamically allocated.
7419 + * Make sure all CPUs receive a corresponding Tx queue.
7420 + */
7421 + while (egress_cnt < DPAA_ETH_TX_QUEUES) {
7422 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7423 + if (fq->fq_type != FQ_TYPE_TX)
7424 + continue;
7425 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7426 + if (egress_cnt == DPAA_ETH_TX_QUEUES)
7427 + break;
7428 + }
7429 + }
7430 +}
7431 +EXPORT_SYMBOL(dpa_fq_setup);
7432 +
7433 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
7434 +{
7435 + int _errno;
7436 + const struct dpa_priv_s *priv;
7437 + struct device *dev;
7438 + struct qman_fq *fq;
7439 + struct qm_mcc_initfq initfq;
7440 + struct qman_fq *confq;
7441 + int queue_id;
7442 +
7443 + priv = netdev_priv(dpa_fq->net_dev);
7444 + dev = dpa_fq->net_dev->dev.parent;
7445 +
7446 + if (dpa_fq->fqid == 0)
7447 + dpa_fq->flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
7448 +
7449 + dpa_fq->init = !(dpa_fq->flags & QMAN_FQ_FLAG_NO_MODIFY);
7450 +
7451 + _errno = qman_create_fq(dpa_fq->fqid, dpa_fq->flags, &dpa_fq->fq_base);
7452 + if (_errno) {
7453 + dev_err(dev, "qman_create_fq() failed\n");
7454 + return _errno;
7455 + }
7456 + fq = &dpa_fq->fq_base;
7457 +
7458 + if (dpa_fq->init) {
7459 + memset(&initfq, 0, sizeof(initfq));
7460 +
7461 + initfq.we_mask = QM_INITFQ_WE_FQCTRL;
7462 + /* FIXME: why would we want to keep an empty FQ in cache? */
7463 + initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE;
7464 +
7465 + /* Try to reduce the number of portal interrupts for
7466 + * Tx Confirmation FQs.
7467 + */
7468 + if (dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM)
7469 + initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE;
7470 +
7471 + /* FQ placement */
7472 + initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
7473 +
7474 + initfq.fqd.dest.channel = dpa_fq->channel;
7475 + initfq.fqd.dest.wq = dpa_fq->wq;
7476 +
7477 + /* Put all egress queues in a congestion group of their own.
7478 + * Sensu stricto, the Tx confirmation queues are Rx FQs,
7479 + * rather than Tx - but they nonetheless account for the
7480 + * memory footprint on behalf of egress traffic. We therefore
7481 + * place them in the netdev's CGR, along with the Tx FQs.
7482 + */
7483 + if (dpa_fq->fq_type == FQ_TYPE_TX ||
7484 + dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM ||
7485 + dpa_fq->fq_type == FQ_TYPE_TX_CONF_MQ) {
7486 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7487 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7488 + initfq.fqd.cgid = (uint8_t)priv->cgr_data.cgr.cgrid;
7489 + /* Set a fixed overhead accounting, in an attempt to
7490 + * reduce the impact of fixed-size skb shells and the
7491 + * driver's needed headroom on system memory. This is
7492 + * especially the case when the egress traffic is
7493 + * composed of small datagrams.
7494 + * Unfortunately, QMan's OAL value is capped to an
7495 + * insufficient value, but even that is better than
7496 + * no overhead accounting at all.
7497 + */
7498 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7499 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7500 + initfq.fqd.oac_init.oal =
7501 + (signed char)(min(sizeof(struct sk_buff) +
7502 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7503 + }
7504 +
7505 + if (td_enable) {
7506 + initfq.we_mask |= QM_INITFQ_WE_TDTHRESH;
7507 + qm_fqd_taildrop_set(&initfq.fqd.td,
7508 + DPA_FQ_TD, 1);
7509 + initfq.fqd.fq_ctrl = QM_FQCTRL_TDE;
7510 + }
7511 +
7512 + /* Configure the Tx confirmation queue, now that we know
7513 + * which Tx queue it pairs with.
7514 + */
7515 + if (dpa_fq->fq_type == FQ_TYPE_TX) {
7516 + queue_id = _dpa_tx_fq_to_id(priv, &dpa_fq->fq_base);
7517 + if (queue_id >= 0) {
7518 + confq = priv->conf_fqs[queue_id];
7519 + if (confq) {
7520 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7521 + /* ContextA: OVOM=1 (use contextA2 bits instead of ICAD)
7522 + * A2V=1 (contextA A2 field is valid)
7523 + * A0V=1 (contextA A0 field is valid)
7524 + * B0V=1 (contextB field is valid)
7525 + * ContextA A2: EBD=1 (deallocate buffers inside FMan)
7526 + * ContextB B0(ASPID): 0 (absolute Virtual Storage ID)
7527 + */
7528 + initfq.fqd.context_a.hi = 0x1e000000;
7529 + initfq.fqd.context_a.lo = 0x80000000;
7530 + }
7531 + }
7532 + }
7533 +
7534 + /* Put all *private* ingress queues in our "ingress CGR". */
7535 + if (priv->use_ingress_cgr &&
7536 + (dpa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
7537 + dpa_fq->fq_type == FQ_TYPE_RX_ERROR ||
7538 + dpa_fq->fq_type == FQ_TYPE_RX_PCD ||
7539 + dpa_fq->fq_type == FQ_TYPE_RX_PCD_HI_PRIO)) {
7540 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7541 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7542 + initfq.fqd.cgid = (uint8_t)priv->ingress_cgr.cgrid;
7543 + /* Set a fixed overhead accounting, just like for the
7544 + * egress CGR.
7545 + */
7546 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7547 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7548 + initfq.fqd.oac_init.oal =
7549 + (signed char)(min(sizeof(struct sk_buff) +
7550 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7551 + }
7552 +
7553 + /* Initialization common to all ingress queues */
7554 + if (dpa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
7555 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7556 + initfq.fqd.fq_ctrl |=
7557 + QM_FQCTRL_CTXASTASHING | QM_FQCTRL_AVOIDBLOCK;
7558 + initfq.fqd.context_a.stashing.exclusive =
7559 + QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX |
7560 + QM_STASHING_EXCL_ANNOTATION;
7561 + initfq.fqd.context_a.stashing.data_cl = 2;
7562 + initfq.fqd.context_a.stashing.annotation_cl = 1;
7563 + initfq.fqd.context_a.stashing.context_cl =
7564 + DIV_ROUND_UP(sizeof(struct qman_fq), 64);
7565 + }
7566 +
7567 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
7568 + if (_errno < 0) {
7569 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno)) {
7570 + dpa_fq->init = 0;
7571 + } else {
7572 + dev_err(dev, "qman_init_fq(%u) = %d\n",
7573 + qman_fq_fqid(fq), _errno);
7574 + qman_destroy_fq(fq, 0);
7575 + }
7576 + return _errno;
7577 + }
7578 + }
7579 +
7580 + dpa_fq->fqid = qman_fq_fqid(fq);
7581 +
7582 + return 0;
7583 +}
7584 +EXPORT_SYMBOL(dpa_fq_init);
7585 +
7586 +int __cold __attribute__((nonnull))
7587 +_dpa_fq_free(struct device *dev, struct qman_fq *fq)
7588 +{
7589 + int _errno, __errno;
7590 + struct dpa_fq *dpa_fq;
7591 + const struct dpa_priv_s *priv;
7592 +
7593 + _errno = 0;
7594 +
7595 + dpa_fq = container_of(fq, struct dpa_fq, fq_base);
7596 + priv = netdev_priv(dpa_fq->net_dev);
7597 +
7598 + if (dpa_fq->init) {
7599 + _errno = qman_retire_fq(fq, NULL);
7600 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
7601 + dev_err(dev, "qman_retire_fq(%u) = %d\n",
7602 + qman_fq_fqid(fq), _errno);
7603 +
7604 + __errno = qman_oos_fq(fq);
7605 + if (unlikely(__errno < 0) && netif_msg_drv(priv)) {
7606 + dev_err(dev, "qman_oos_fq(%u) = %d\n",
7607 + qman_fq_fqid(fq), __errno);
7608 + if (_errno >= 0)
7609 + _errno = __errno;
7610 + }
7611 + }
7612 +
7613 + qman_destroy_fq(fq, 0);
7614 + list_del(&dpa_fq->list);
7615 +
7616 + return _errno;
7617 +}
7618 +EXPORT_SYMBOL(_dpa_fq_free);
7619 +
7620 +int __cold __attribute__((nonnull))
7621 +dpa_fq_free(struct device *dev, struct list_head *list)
7622 +{
7623 + int _errno, __errno;
7624 + struct dpa_fq *dpa_fq, *tmp;
7625 +
7626 + _errno = 0;
7627 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7628 + __errno = _dpa_fq_free(dev, (struct qman_fq *)dpa_fq);
7629 + if (unlikely(__errno < 0) && _errno >= 0)
7630 + _errno = __errno;
7631 + }
7632 +
7633 + return _errno;
7634 +}
7635 +EXPORT_SYMBOL(dpa_fq_free);
7636 +
7637 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable)
7638 +{
7639 + int _errno, __errno;
7640 + struct dpa_fq *dpa_fq, *tmp;
7641 + static bool print_msg __read_mostly;
7642 +
7643 + _errno = 0;
7644 + print_msg = true;
7645 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7646 + __errno = dpa_fq_init(dpa_fq, td_enable);
7647 + if (unlikely(__errno < 0) && _errno >= 0) {
7648 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, __errno)) {
7649 + if (print_msg) {
7650 + dev_warn(dev,
7651 + "Skip RX PCD High Priority FQs initialization\n");
7652 + print_msg = false;
7653 + }
7654 + if (_dpa_fq_free(dev, (struct qman_fq *)dpa_fq))
7655 + dev_warn(dev,
7656 + "Error freeing frame queues\n");
7657 + } else {
7658 + _errno = __errno;
7659 + break;
7660 + }
7661 + }
7662 + }
7663 +
7664 + return _errno;
7665 +}
7666 +EXPORT_SYMBOL(dpa_fqs_init);
7667 +static void
7668 +dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq,
7669 + struct dpa_fq *defq, struct dpa_buffer_layout_s *buf_layout)
7670 +{
7671 + struct fm_port_params tx_port_param;
7672 + bool frag_enabled = false;
7673 +
7674 + memset(&tx_port_param, 0, sizeof(tx_port_param));
7675 + dpaa_eth_init_port(tx, port, tx_port_param, errq->fqid, defq->fqid,
7676 + buf_layout, frag_enabled);
7677 +}
7678 +
7679 +static void
7680 +dpaa_eth_init_rx_port(struct fm_port *port, struct dpa_bp *bp, size_t count,
7681 + struct dpa_fq *errq, struct dpa_fq *defq,
7682 + struct dpa_buffer_layout_s *buf_layout)
7683 +{
7684 + struct fm_port_params rx_port_param;
7685 + int i;
7686 + bool frag_enabled = false;
7687 +
7688 + memset(&rx_port_param, 0, sizeof(rx_port_param));
7689 + count = min(ARRAY_SIZE(rx_port_param.pool_param), count);
7690 + rx_port_param.num_pools = (uint8_t)count;
7691 + for (i = 0; i < count; i++) {
7692 + if (i >= rx_port_param.num_pools)
7693 + break;
7694 + rx_port_param.pool_param[i].id = bp[i].bpid;
7695 + rx_port_param.pool_param[i].size = (uint16_t)bp[i].size;
7696 + }
7697 +
7698 + dpaa_eth_init_port(rx, port, rx_port_param, errq->fqid, defq->fqid,
7699 + buf_layout, frag_enabled);
7700 +}
7701 +
7702 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
7703 +/* Defined as weak, to be implemented by fman pcd tester. */
7704 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *)
7705 +__attribute__((weak));
7706 +
7707 +int dpa_free_pcd_fqids(struct device *, uint32_t) __attribute__((weak));
7708 +#else
7709 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *);
7710 +
7711 +int dpa_free_pcd_fqids(struct device *, uint32_t);
7712 +
7713 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
7714 +
7715 +
7716 +int dpa_alloc_pcd_fqids(struct device *dev, uint32_t num,
7717 + uint8_t alignment, uint32_t *base_fqid)
7718 +{
7719 + dev_crit(dev, "callback not implemented!\n");
7720 +
7721 + return 0;
7722 +}
7723 +
7724 +int dpa_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
7725 +{
7726 +
7727 + dev_crit(dev, "callback not implemented!\n");
7728 +
7729 + return 0;
7730 +}
7731 +
7732 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
7733 + struct dpa_bp *bp, size_t count,
7734 + struct fm_port_fqs *port_fqs,
7735 + struct dpa_buffer_layout_s *buf_layout,
7736 + struct device *dev)
7737 +{
7738 + struct fm_port_pcd_param rx_port_pcd_param;
7739 + struct fm_port *rxport = mac_dev->port_dev[RX];
7740 + struct fm_port *txport = mac_dev->port_dev[TX];
7741 +
7742 + dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
7743 + port_fqs->tx_defq, &buf_layout[TX]);
7744 + dpaa_eth_init_rx_port(rxport, bp, count, port_fqs->rx_errq,
7745 + port_fqs->rx_defq, &buf_layout[RX]);
7746 +
7747 + rx_port_pcd_param.cba = dpa_alloc_pcd_fqids;
7748 + rx_port_pcd_param.cbf = dpa_free_pcd_fqids;
7749 + rx_port_pcd_param.dev = dev;
7750 + fm_port_pcd_bind(rxport, &rx_port_pcd_param);
7751 +}
7752 +EXPORT_SYMBOL(dpaa_eth_init_ports);
7753 +
7754 +void dpa_release_sgt(struct qm_sg_entry *sgt)
7755 +{
7756 + struct dpa_bp *dpa_bp;
7757 + struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX];
7758 + uint8_t i = 0, j;
7759 +
7760 + memset(bmb, 0, DPA_BUFF_RELEASE_MAX * sizeof(struct bm_buffer));
7761 +
7762 + do {
7763 + dpa_bp = dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i]));
7764 + DPA_BUG_ON(!dpa_bp);
7765 +
7766 + j = 0;
7767 + do {
7768 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
7769 + bm_buffer_set64(&bmb[j], qm_sg_addr(&sgt[i]));
7770 +
7771 + j++; i++;
7772 + } while (j < ARRAY_SIZE(bmb) &&
7773 + !qm_sg_entry_get_final(&sgt[i-1]) &&
7774 + qm_sg_entry_get_bpid(&sgt[i-1]) ==
7775 + qm_sg_entry_get_bpid(&sgt[i]));
7776 +
7777 + while (bman_release(dpa_bp->pool, bmb, j, 0))
7778 + cpu_relax();
7779 + } while (!qm_sg_entry_get_final(&sgt[i-1]));
7780 +}
7781 +EXPORT_SYMBOL(dpa_release_sgt);
7782 +
7783 +void __attribute__((nonnull))
7784 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
7785 +{
7786 + struct qm_sg_entry *sgt;
7787 + struct dpa_bp *dpa_bp;
7788 + struct bm_buffer bmb;
7789 + dma_addr_t addr;
7790 + void *vaddr;
7791 +
7792 + bmb.opaque = 0;
7793 + bm_buffer_set64(&bmb, qm_fd_addr(fd));
7794 +
7795 + dpa_bp = dpa_bpid2pool(fd->bpid);
7796 + DPA_BUG_ON(!dpa_bp);
7797 +
7798 + if (fd->format == qm_fd_sg) {
7799 + vaddr = phys_to_virt(qm_fd_addr(fd));
7800 + sgt = vaddr + dpa_fd_offset(fd);
7801 +
7802 + dma_unmap_single(dpa_bp->dev, qm_fd_addr(fd), dpa_bp->size,
7803 + DMA_BIDIRECTIONAL);
7804 +
7805 + dpa_release_sgt(sgt);
7806 + addr = dma_map_single(dpa_bp->dev, vaddr, dpa_bp->size,
7807 + DMA_BIDIRECTIONAL);
7808 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
7809 + dev_err(dpa_bp->dev, "DMA mapping failed");
7810 + return;
7811 + }
7812 + bm_buffer_set64(&bmb, addr);
7813 + }
7814 +
7815 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
7816 + cpu_relax();
7817 +}
7818 +EXPORT_SYMBOL(dpa_fd_release);
7819 +
7820 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
7821 + const struct qm_mr_entry *msg)
7822 +{
7823 + switch (msg->ern.rc & QM_MR_RC_MASK) {
7824 + case QM_MR_RC_CGR_TAILDROP:
7825 + percpu_priv->ern_cnt.cg_tdrop++;
7826 + break;
7827 + case QM_MR_RC_WRED:
7828 + percpu_priv->ern_cnt.wred++;
7829 + break;
7830 + case QM_MR_RC_ERROR:
7831 + percpu_priv->ern_cnt.err_cond++;
7832 + break;
7833 + case QM_MR_RC_ORPWINDOW_EARLY:
7834 + percpu_priv->ern_cnt.early_window++;
7835 + break;
7836 + case QM_MR_RC_ORPWINDOW_LATE:
7837 + percpu_priv->ern_cnt.late_window++;
7838 + break;
7839 + case QM_MR_RC_FQ_TAILDROP:
7840 + percpu_priv->ern_cnt.fq_tdrop++;
7841 + break;
7842 + case QM_MR_RC_ORPWINDOW_RETIRED:
7843 + percpu_priv->ern_cnt.fq_retired++;
7844 + break;
7845 + case QM_MR_RC_ORP_ZERO:
7846 + percpu_priv->ern_cnt.orp_zero++;
7847 + break;
7848 + }
7849 +}
7850 +EXPORT_SYMBOL(count_ern);
7851 +
7852 +/**
7853 + * Turn on HW checksum computation for this outgoing frame.
7854 + * If the current protocol is not something we support in this regard
7855 + * (or if the stack has already computed the SW checksum), we do nothing.
7856 + *
7857 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
7858 + * otherwise.
7859 + *
7860 + * Note that this function may modify the fd->cmd field and the skb data buffer
7861 + * (the Parse Results area).
7862 + */
7863 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
7864 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results)
7865 +{
7866 + fm_prs_result_t *parse_result;
7867 + struct iphdr *iph;
7868 + struct ipv6hdr *ipv6h = NULL;
7869 + u8 l4_proto;
7870 + u16 ethertype = ntohs(skb->protocol);
7871 + int retval = 0;
7872 +
7873 + if (skb->ip_summed != CHECKSUM_PARTIAL)
7874 + return 0;
7875 +
7876 + /* Note: L3 csum seems to be already computed in sw, but we can't choose
7877 + * L4 alone from the FM configuration anyway.
7878 + */
7879 +
7880 + /* Fill in some fields of the Parse Results array, so the FMan
7881 + * can find them as if they came from the FMan Parser.
7882 + */
7883 + parse_result = (fm_prs_result_t *)parse_results;
7884 +
7885 + /* If we're dealing with VLAN, get the real Ethernet type */
7886 + if (ethertype == ETH_P_8021Q) {
7887 + /* We can't always assume the MAC header is set correctly
7888 + * by the stack, so reset to beginning of skb->data
7889 + */
7890 + skb_reset_mac_header(skb);
7891 + ethertype = ntohs(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
7892 + }
7893 +
7894 + /* Fill in the relevant L3 parse result fields
7895 + * and read the L4 protocol type
7896 + */
7897 + switch (ethertype) {
7898 + case ETH_P_IP:
7899 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4);
7900 + iph = ip_hdr(skb);
7901 + DPA_BUG_ON(iph == NULL);
7902 + l4_proto = iph->protocol;
7903 + break;
7904 + case ETH_P_IPV6:
7905 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6);
7906 + ipv6h = ipv6_hdr(skb);
7907 + DPA_BUG_ON(ipv6h == NULL);
7908 + l4_proto = ipv6h->nexthdr;
7909 + break;
7910 + default:
7911 + /* We shouldn't even be here */
7912 + if (netif_msg_tx_err(priv) && net_ratelimit())
7913 + netdev_alert(priv->net_dev,
7914 + "Can't compute HW csum for L3 proto 0x%x\n",
7915 + ntohs(skb->protocol));
7916 + retval = -EIO;
7917 + goto return_error;
7918 + }
7919 +
7920 + /* Fill in the relevant L4 parse result fields */
7921 + switch (l4_proto) {
7922 + case IPPROTO_UDP:
7923 + parse_result->l4r = FM_L4_PARSE_RESULT_UDP;
7924 + break;
7925 + case IPPROTO_TCP:
7926 + parse_result->l4r = FM_L4_PARSE_RESULT_TCP;
7927 + break;
7928 + default:
7929 + /* This can as well be a BUG() */
7930 + if (netif_msg_tx_err(priv) && net_ratelimit())
7931 + netdev_alert(priv->net_dev,
7932 + "Can't compute HW csum for L4 proto 0x%x\n",
7933 + l4_proto);
7934 + retval = -EIO;
7935 + goto return_error;
7936 + }
7937 +
7938 + /* At index 0 is IPOffset_1 as defined in the Parse Results */
7939 + parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb);
7940 + parse_result->l4_off = (uint8_t)skb_transport_offset(skb);
7941 +
7942 + /* Enable L3 (and L4, if TCP or UDP) HW checksum. */
7943 + fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
7944 +
7945 + /* On P1023 and similar platforms fd->cmd interpretation could
7946 + * be disabled by setting CONTEXT_A bit ICMD; currently this bit
7947 + * is not set so we do not need to check; in the future, if/when
7948 + * using context_a we need to check this bit
7949 + */
7950 +
7951 +return_error:
7952 + return retval;
7953 +}
7954 +EXPORT_SYMBOL(dpa_enable_tx_csum);
7955 +
7956 +#ifdef CONFIG_FSL_DPAA_CEETM
7957 +void dpa_enable_ceetm(struct net_device *dev)
7958 +{
7959 + struct dpa_priv_s *priv = netdev_priv(dev);
7960 + priv->ceetm_en = true;
7961 +}
7962 +EXPORT_SYMBOL(dpa_enable_ceetm);
7963 +
7964 +void dpa_disable_ceetm(struct net_device *dev)
7965 +{
7966 + struct dpa_priv_s *priv = netdev_priv(dev);
7967 + priv->ceetm_en = false;
7968 +}
7969 +EXPORT_SYMBOL(dpa_disable_ceetm);
7970 +#endif
7971 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
7972 new file mode 100644
7973 index 00000000..41db4302
7974 --- /dev/null
7975 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
7976 @@ -0,0 +1,225 @@
7977 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
7978 + *
7979 + * Redistribution and use in source and binary forms, with or without
7980 + * modification, are permitted provided that the following conditions are met:
7981 + * * Redistributions of source code must retain the above copyright
7982 + * notice, this list of conditions and the following disclaimer.
7983 + * * Redistributions in binary form must reproduce the above copyright
7984 + * notice, this list of conditions and the following disclaimer in the
7985 + * documentation and/or other materials provided with the distribution.
7986 + * * Neither the name of Freescale Semiconductor nor the
7987 + * names of its contributors may be used to endorse or promote products
7988 + * derived from this software without specific prior written permission.
7989 + *
7990 + *
7991 + * ALTERNATIVELY, this software may be distributed under the terms of the
7992 + * GNU General Public License ("GPL") as published by the Free Software
7993 + * Foundation, either version 2 of that License or (at your option) any
7994 + * later version.
7995 + *
7996 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
7997 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7998 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7999 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8000 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8001 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8002 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8003 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8004 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8005 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8006 + */
8007 +
8008 +#ifndef __DPAA_ETH_COMMON_H
8009 +#define __DPAA_ETH_COMMON_H
8010 +
8011 +#include <linux/etherdevice.h> /* struct net_device */
8012 +#include <linux/fsl_bman.h> /* struct bm_buffer */
8013 +#include <linux/of_platform.h> /* struct platform_device */
8014 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
8015 +
8016 +#include "dpaa_eth.h"
8017 +#include "lnxwrp_fsl_fman.h"
8018 +
8019 +#define dpaa_eth_init_port(type, port, param, errq_id, defq_id, buf_layout,\
8020 + frag_enabled) \
8021 +{ \
8022 + param.errq = errq_id; \
8023 + param.defq = defq_id; \
8024 + param.priv_data_size = buf_layout->priv_data_size; \
8025 + param.parse_results = buf_layout->parse_results; \
8026 + param.hash_results = buf_layout->hash_results; \
8027 + param.frag_enable = frag_enabled; \
8028 + param.time_stamp = buf_layout->time_stamp; \
8029 + param.manip_extra_space = buf_layout->manip_extra_space; \
8030 + param.data_align = buf_layout->data_align; \
8031 + fm_set_##type##_port_params(port, &param); \
8032 +}
8033 +
8034 +#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
8035 +
8036 +#define DPA_SGT_ENTRIES_THRESHOLD DPA_SGT_MAX_ENTRIES
8037 +
8038 +#define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */
8039 +
8040 +#define DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno) \
8041 + (((dpa_fq)->fq_type == FQ_TYPE_RX_PCD_HI_PRIO) && \
8042 + (_errno == -EIO))
8043 +/* return codes for the dpaa-eth hooks */
8044 +enum dpaa_eth_hook_result {
8045 + /* fd/skb was retained by the hook.
8046 + *
8047 + * On the Rx path, this means the Ethernet driver will _not_
8048 + * deliver the skb to the stack. Instead, the hook implementation
8049 + * is expected to properly dispose of the skb.
8050 + *
8051 + * On the Tx path, the Ethernet driver's dpa_tx() function will
8052 + * immediately return NETDEV_TX_OK. The hook implementation is expected
8053 + * to free the skb. *DO*NOT* release it to BMan, or enqueue it to FMan,
8054 + * unless you know exactly what you're doing!
8055 + *
8056 + * On the confirmation/error paths, the Ethernet driver will _not_
8057 + * perform any fd cleanup, nor update the interface statistics.
8058 + */
8059 + DPAA_ETH_STOLEN,
8060 + /* fd/skb was returned to the Ethernet driver for regular processing.
8061 + * The hook is not allowed to, for instance, reallocate the skb (as if
8062 + * by linearizing, copying, cloning or reallocating the headroom).
8063 + */
8064 + DPAA_ETH_CONTINUE
8065 +};
8066 +
8067 +typedef enum dpaa_eth_hook_result (*dpaa_eth_ingress_hook_t)(
8068 + struct sk_buff *skb, struct net_device *net_dev, u32 fqid);
8069 +typedef enum dpaa_eth_hook_result (*dpaa_eth_egress_hook_t)(
8070 + struct sk_buff *skb, struct net_device *net_dev);
8071 +typedef enum dpaa_eth_hook_result (*dpaa_eth_confirm_hook_t)(
8072 + struct net_device *net_dev, const struct qm_fd *fd, u32 fqid);
8073 +
8074 +/* used in napi related functions */
8075 +extern u16 qman_portal_max;
8076 +
8077 +/* from dpa_ethtool.c */
8078 +extern const struct ethtool_ops dpa_ethtool_ops;
8079 +
8080 +#ifdef CONFIG_FSL_DPAA_HOOKS
8081 +/* Various hooks used for unit-testing and/or fastpath optimizations.
8082 + * Currently only one set of such hooks is supported.
8083 + */
8084 +struct dpaa_eth_hooks_s {
8085 + /* Invoked on the Tx private path, immediately after receiving the skb
8086 + * from the stack.
8087 + */
8088 + dpaa_eth_egress_hook_t tx;
8089 +
8090 + /* Invoked on the Rx private path, right before passing the skb
8091 + * up the stack. At that point, the packet's protocol id has already
8092 + * been set. The skb's data pointer is now at the L3 header, and
8093 + * skb->mac_header points to the L2 header. skb->len has been adjusted
8094 + * to be the length of L3+payload (i.e., the length of the
8095 + * original frame minus the L2 header len).
8096 + * For more details on what the skb looks like, see eth_type_trans().
8097 + */
8098 + dpaa_eth_ingress_hook_t rx_default;
8099 +
8100 + /* Driver hook for the Rx error private path. */
8101 + dpaa_eth_confirm_hook_t rx_error;
8102 + /* Driver hook for the Tx confirmation private path. */
8103 + dpaa_eth_confirm_hook_t tx_confirm;
8104 + /* Driver hook for the Tx error private path. */
8105 + dpaa_eth_confirm_hook_t tx_error;
8106 +};
8107 +
8108 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks);
8109 +
8110 +extern struct dpaa_eth_hooks_s dpaa_eth_hooks;
8111 +#endif
8112 +
8113 +int dpa_netdev_init(struct net_device *net_dev,
8114 + const uint8_t *mac_addr,
8115 + uint16_t tx_timeout);
8116 +int __cold dpa_start(struct net_device *net_dev);
8117 +int __cold dpa_stop(struct net_device *net_dev);
8118 +void __cold dpa_timeout(struct net_device *net_dev);
8119 +void __cold
8120 +dpa_get_stats64(struct net_device *net_dev,
8121 + struct rtnl_link_stats64 *stats);
8122 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu);
8123 +int dpa_ndo_init(struct net_device *net_dev);
8124 +int dpa_set_features(struct net_device *dev, netdev_features_t features);
8125 +netdev_features_t dpa_fix_features(struct net_device *dev,
8126 + netdev_features_t features);
8127 +#ifdef CONFIG_FSL_DPAA_TS
8128 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv,
8129 + enum port_type rx_tx, const void *data);
8130 +/* Updates the skb shared hw timestamp from the hardware timestamp */
8131 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
8132 + struct skb_shared_hwtstamps *shhwtstamps, const void *data);
8133 +#endif /* CONFIG_FSL_DPAA_TS */
8134 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
8135 +int __cold dpa_remove(struct platform_device *of_dev);
8136 +struct mac_device * __cold __must_check
8137 +__attribute__((nonnull)) dpa_mac_probe(struct platform_device *_of_dev);
8138 +int dpa_set_mac_address(struct net_device *net_dev, void *addr);
8139 +void dpa_set_rx_mode(struct net_device *net_dev);
8140 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
8141 + struct dpa_buffer_layout_s *layout);
8142 +int __attribute__((nonnull))
8143 +dpa_bp_alloc(struct dpa_bp *dpa_bp);
8144 +void __cold __attribute__((nonnull))
8145 +dpa_bp_free(struct dpa_priv_s *priv);
8146 +struct dpa_bp *dpa_bpid2pool(int bpid);
8147 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp);
8148 +bool dpa_bpid2pool_use(int bpid);
8149 +void dpa_bp_drain(struct dpa_bp *bp);
8150 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
8151 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
8152 + void *accel_priv, select_queue_fallback_t fallback);
8153 +#endif
8154 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
8155 + u32 fq_start,
8156 + u32 fq_count,
8157 + struct list_head *list,
8158 + enum dpa_fq_type fq_type);
8159 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
8160 + struct fm_port_fqs *port_fqs,
8161 + bool tx_conf_fqs_per_core,
8162 + enum port_type ptype);
8163 +int dpa_get_channel(void);
8164 +void dpa_release_channel(void);
8165 +void dpaa_eth_add_channel(u16 channel);
8166 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv);
8167 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
8168 + struct fm_port *tx_port);
8169 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable);
8170 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable);
8171 +int __cold __attribute__((nonnull))
8172 +dpa_fq_free(struct device *dev, struct list_head *list);
8173 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
8174 + struct dpa_bp *bp, size_t count,
8175 + struct fm_port_fqs *port_fqs,
8176 + struct dpa_buffer_layout_s *buf_layout,
8177 + struct device *dev);
8178 +void dpa_release_sgt(struct qm_sg_entry *sgt);
8179 +void __attribute__((nonnull))
8180 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd);
8181 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
8182 + const struct qm_mr_entry *msg);
8183 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
8184 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
8185 +#ifdef CONFIG_FSL_DPAA_CEETM
8186 +void dpa_enable_ceetm(struct net_device *dev);
8187 +void dpa_disable_ceetm(struct net_device *dev);
8188 +#endif
8189 +struct proxy_device {
8190 + struct mac_device *mac_dev;
8191 +};
8192 +
8193 +/* mac device control functions exposed by proxy interface*/
8194 +int dpa_proxy_start(struct net_device *net_dev);
8195 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev);
8196 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8197 + struct net_device *net_dev);
8198 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8199 + struct net_device *net_dev);
8200 +
8201 +#endif /* __DPAA_ETH_COMMON_H */
8202 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
8203 new file mode 100644
8204 index 00000000..994d38cd
8205 --- /dev/null
8206 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
8207 @@ -0,0 +1,381 @@
8208 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
8209 + *
8210 + * Redistribution and use in source and binary forms, with or without
8211 + * modification, are permitted provided that the following conditions are met:
8212 + * * Redistributions of source code must retain the above copyright
8213 + * notice, this list of conditions and the following disclaimer.
8214 + * * Redistributions in binary form must reproduce the above copyright
8215 + * notice, this list of conditions and the following disclaimer in the
8216 + * documentation and/or other materials provided with the distribution.
8217 + * * Neither the name of Freescale Semiconductor nor the
8218 + * names of its contributors may be used to endorse or promote products
8219 + * derived from this software without specific prior written permission.
8220 + *
8221 + *
8222 + * ALTERNATIVELY, this software may be distributed under the terms of the
8223 + * GNU General Public License ("GPL") as published by the Free Software
8224 + * Foundation, either version 2 of that License or (at your option) any
8225 + * later version.
8226 + *
8227 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8228 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8229 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8230 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8231 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8232 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8233 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8234 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8235 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8236 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8237 + */
8238 +
8239 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8240 +#define pr_fmt(fmt) \
8241 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8242 + KBUILD_BASENAME".c", __LINE__, __func__
8243 +#else
8244 +#define pr_fmt(fmt) \
8245 + KBUILD_MODNAME ": " fmt
8246 +#endif
8247 +
8248 +#include <linux/init.h>
8249 +#include <linux/module.h>
8250 +#include <linux/of_platform.h>
8251 +#include "dpaa_eth.h"
8252 +#include "dpaa_eth_common.h"
8253 +#include "dpaa_eth_base.h"
8254 +#include "lnxwrp_fsl_fman.h" /* fm_get_rx_extra_headroom(), fm_get_max_frm() */
8255 +#include "mac.h"
8256 +
8257 +#define DPA_DESCRIPTION "FSL DPAA Proxy initialization driver"
8258 +
8259 +MODULE_LICENSE("Dual BSD/GPL");
8260 +
8261 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
8262 +
8263 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev);
8264 +#ifdef CONFIG_PM
8265 +
8266 +static int proxy_suspend(struct device *dev)
8267 +{
8268 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8269 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8270 + int err = 0;
8271 +
8272 + err = fm_port_suspend(mac_dev->port_dev[RX]);
8273 + if (err)
8274 + goto port_suspend_failed;
8275 +
8276 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8277 + if (err)
8278 + err = fm_port_resume(mac_dev->port_dev[RX]);
8279 +
8280 +port_suspend_failed:
8281 + return err;
8282 +}
8283 +
8284 +static int proxy_resume(struct device *dev)
8285 +{
8286 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8287 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8288 + int err = 0;
8289 +
8290 + err = fm_port_resume(mac_dev->port_dev[TX]);
8291 + if (err)
8292 + goto port_resume_failed;
8293 +
8294 + err = fm_port_resume(mac_dev->port_dev[RX]);
8295 + if (err)
8296 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8297 +
8298 +port_resume_failed:
8299 + return err;
8300 +}
8301 +
8302 +static const struct dev_pm_ops proxy_pm_ops = {
8303 + .suspend = proxy_suspend,
8304 + .resume = proxy_resume,
8305 +};
8306 +
8307 +#define PROXY_PM_OPS (&proxy_pm_ops)
8308 +
8309 +#else /* CONFIG_PM */
8310 +
8311 +#define PROXY_PM_OPS NULL
8312 +
8313 +#endif /* CONFIG_PM */
8314 +
8315 +static int dpaa_eth_proxy_probe(struct platform_device *_of_dev)
8316 +{
8317 + int err = 0, i;
8318 + struct device *dev;
8319 + struct device_node *dpa_node;
8320 + struct dpa_bp *dpa_bp;
8321 + struct list_head proxy_fq_list;
8322 + size_t count;
8323 + struct fm_port_fqs port_fqs;
8324 + struct dpa_buffer_layout_s *buf_layout = NULL;
8325 + struct mac_device *mac_dev;
8326 + struct proxy_device *proxy_dev;
8327 +
8328 + dev = &_of_dev->dev;
8329 +
8330 + dpa_node = dev->of_node;
8331 +
8332 + if (!of_device_is_available(dpa_node))
8333 + return -ENODEV;
8334 +
8335 + /* Get the buffer pools assigned to this interface */
8336 + dpa_bp = dpa_bp_probe(_of_dev, &count);
8337 + if (IS_ERR(dpa_bp))
8338 + return PTR_ERR(dpa_bp);
8339 +
8340 + mac_dev = dpa_mac_probe(_of_dev);
8341 + if (IS_ERR(mac_dev))
8342 + return PTR_ERR(mac_dev);
8343 +
8344 + proxy_dev = devm_kzalloc(dev, sizeof(*proxy_dev), GFP_KERNEL);
8345 + if (!proxy_dev) {
8346 + dev_err(dev, "devm_kzalloc() failed\n");
8347 + return -ENOMEM;
8348 + }
8349 +
8350 + proxy_dev->mac_dev = mac_dev;
8351 + dev_set_drvdata(dev, proxy_dev);
8352 +
8353 + /* We have physical ports, so we need to establish
8354 + * the buffer layout.
8355 + */
8356 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
8357 + GFP_KERNEL);
8358 + if (!buf_layout) {
8359 + dev_err(dev, "devm_kzalloc() failed\n");
8360 + return -ENOMEM;
8361 + }
8362 + dpa_set_buffers_layout(mac_dev, buf_layout);
8363 +
8364 + INIT_LIST_HEAD(&proxy_fq_list);
8365 +
8366 + memset(&port_fqs, 0, sizeof(port_fqs));
8367 +
8368 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true, RX);
8369 + if (!err)
8370 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true,
8371 + TX);
8372 + if (err < 0) {
8373 + devm_kfree(dev, buf_layout);
8374 + return err;
8375 + }
8376 +
8377 + /* Proxy initializer - Just configures the MAC on behalf of
8378 + * another partition.
8379 + */
8380 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
8381 + buf_layout, dev);
8382 +
8383 + /* Proxy interfaces need to be started, and the allocated
8384 + * memory freed
8385 + */
8386 + devm_kfree(dev, buf_layout);
8387 + devm_kfree(dev, dpa_bp);
8388 +
8389 + /* Free FQ structures */
8390 + devm_kfree(dev, port_fqs.rx_defq);
8391 + devm_kfree(dev, port_fqs.rx_errq);
8392 + devm_kfree(dev, port_fqs.tx_defq);
8393 + devm_kfree(dev, port_fqs.tx_errq);
8394 +
8395 + for_each_port_device(i, mac_dev->port_dev) {
8396 + err = fm_port_enable(mac_dev->port_dev[i]);
8397 + if (err)
8398 + goto port_enable_fail;
8399 + }
8400 +
8401 + dev_info(dev, "probed MAC device with MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
8402 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
8403 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
8404 +
8405 + return 0; /* Proxy interface initialization ended */
8406 +
8407 +port_enable_fail:
8408 + for_each_port_device(i, mac_dev->port_dev)
8409 + fm_port_disable(mac_dev->port_dev[i]);
8410 + dpa_eth_proxy_remove(_of_dev);
8411 +
8412 + return err;
8413 +}
8414 +
8415 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8416 + struct net_device *net_dev)
8417 +{
8418 + struct mac_device *mac_dev;
8419 + int _errno;
8420 +
8421 + mac_dev = proxy_dev->mac_dev;
8422 +
8423 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
8424 + net_dev->dev_addr);
8425 + if (_errno < 0)
8426 + return _errno;
8427 +
8428 + return 0;
8429 +}
8430 +EXPORT_SYMBOL(dpa_proxy_set_mac_address);
8431 +
8432 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8433 + struct net_device *net_dev)
8434 +{
8435 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8436 + int _errno;
8437 +
8438 + if (!!(net_dev->flags & IFF_PROMISC) != mac_dev->promisc) {
8439 + mac_dev->promisc = !mac_dev->promisc;
8440 + _errno = mac_dev->set_promisc(mac_dev->get_mac_handle(mac_dev),
8441 + mac_dev->promisc);
8442 + if (unlikely(_errno < 0))
8443 + netdev_err(net_dev, "mac_dev->set_promisc() = %d\n",
8444 + _errno);
8445 + }
8446 +
8447 + _errno = mac_dev->set_multi(net_dev, mac_dev);
8448 + if (unlikely(_errno < 0))
8449 + return _errno;
8450 +
8451 + return 0;
8452 +}
8453 +EXPORT_SYMBOL(dpa_proxy_set_rx_mode);
8454 +
8455 +int dpa_proxy_start(struct net_device *net_dev)
8456 +{
8457 + struct mac_device *mac_dev;
8458 + const struct dpa_priv_s *priv;
8459 + struct proxy_device *proxy_dev;
8460 + int _errno;
8461 + int i;
8462 +
8463 + priv = netdev_priv(net_dev);
8464 + proxy_dev = (struct proxy_device *)priv->peer;
8465 + mac_dev = proxy_dev->mac_dev;
8466 +
8467 + _errno = mac_dev->init_phy(net_dev, mac_dev);
8468 + if (_errno < 0) {
8469 + if (netif_msg_drv(priv))
8470 + netdev_err(net_dev, "init_phy() = %d\n",
8471 + _errno);
8472 + return _errno;
8473 + }
8474 +
8475 + for_each_port_device(i, mac_dev->port_dev) {
8476 + _errno = fm_port_enable(mac_dev->port_dev[i]);
8477 + if (_errno)
8478 + goto port_enable_fail;
8479 + }
8480 +
8481 + _errno = mac_dev->start(mac_dev);
8482 + if (_errno < 0) {
8483 + if (netif_msg_drv(priv))
8484 + netdev_err(net_dev, "mac_dev->start() = %d\n",
8485 + _errno);
8486 + goto port_enable_fail;
8487 + }
8488 +
8489 + return _errno;
8490 +
8491 +port_enable_fail:
8492 + for_each_port_device(i, mac_dev->port_dev)
8493 + fm_port_disable(mac_dev->port_dev[i]);
8494 +
8495 + return _errno;
8496 +}
8497 +EXPORT_SYMBOL(dpa_proxy_start);
8498 +
8499 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev)
8500 +{
8501 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8502 + const struct dpa_priv_s *priv = netdev_priv(net_dev);
8503 + int _errno, i, err;
8504 +
8505 + _errno = mac_dev->stop(mac_dev);
8506 + if (_errno < 0) {
8507 + if (netif_msg_drv(priv))
8508 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
8509 + _errno);
8510 + return _errno;
8511 + }
8512 +
8513 + for_each_port_device(i, mac_dev->port_dev) {
8514 + err = fm_port_disable(mac_dev->port_dev[i]);
8515 + _errno = err ? err : _errno;
8516 + }
8517 +
8518 + if (mac_dev->phy_dev)
8519 + phy_disconnect(mac_dev->phy_dev);
8520 + mac_dev->phy_dev = NULL;
8521 +
8522 + return _errno;
8523 +}
8524 +EXPORT_SYMBOL(dpa_proxy_stop);
8525 +
8526 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev)
8527 +{
8528 + struct device *dev = &of_dev->dev;
8529 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8530 +
8531 + kfree(proxy_dev);
8532 +
8533 + dev_set_drvdata(dev, NULL);
8534 +
8535 + return 0;
8536 +}
8537 +
8538 +static const struct of_device_id dpa_proxy_match[] = {
8539 + {
8540 + .compatible = "fsl,dpa-ethernet-init"
8541 + },
8542 + {}
8543 +};
8544 +MODULE_DEVICE_TABLE(of, dpa_proxy_match);
8545 +
8546 +static struct platform_driver dpa_proxy_driver = {
8547 + .driver = {
8548 + .name = KBUILD_MODNAME "-proxy",
8549 + .of_match_table = dpa_proxy_match,
8550 + .owner = THIS_MODULE,
8551 + .pm = PROXY_PM_OPS,
8552 + },
8553 + .probe = dpaa_eth_proxy_probe,
8554 + .remove = dpa_eth_proxy_remove
8555 +};
8556 +
8557 +static int __init __cold dpa_proxy_load(void)
8558 +{
8559 + int _errno;
8560 +
8561 + pr_info(DPA_DESCRIPTION "\n");
8562 +
8563 + /* Initialize dpaa_eth mirror values */
8564 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
8565 + dpa_max_frm = fm_get_max_frm();
8566 +
8567 + _errno = platform_driver_register(&dpa_proxy_driver);
8568 + if (unlikely(_errno < 0)) {
8569 + pr_err(KBUILD_MODNAME
8570 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
8571 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
8572 + }
8573 +
8574 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8575 + KBUILD_BASENAME".c", __func__);
8576 +
8577 + return _errno;
8578 +}
8579 +module_init(dpa_proxy_load);
8580 +
8581 +static void __exit __cold dpa_proxy_unload(void)
8582 +{
8583 + platform_driver_unregister(&dpa_proxy_driver);
8584 +
8585 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8586 + KBUILD_BASENAME".c", __func__);
8587 +}
8588 +module_exit(dpa_proxy_unload);
8589 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
8590 new file mode 100644
8591 index 00000000..32e62e6d
8592 --- /dev/null
8593 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
8594 @@ -0,0 +1,1168 @@
8595 +/* Copyright 2012 Freescale Semiconductor Inc.
8596 + *
8597 + * Redistribution and use in source and binary forms, with or without
8598 + * modification, are permitted provided that the following conditions are met:
8599 + * * Redistributions of source code must retain the above copyright
8600 + * notice, this list of conditions and the following disclaimer.
8601 + * * Redistributions in binary form must reproduce the above copyright
8602 + * notice, this list of conditions and the following disclaimer in the
8603 + * documentation and/or other materials provided with the distribution.
8604 + * * Neither the name of Freescale Semiconductor nor the
8605 + * names of its contributors may be used to endorse or promote products
8606 + * derived from this software without specific prior written permission.
8607 + *
8608 + *
8609 + * ALTERNATIVELY, this software may be distributed under the terms of the
8610 + * GNU General Public License ("GPL") as published by the Free Software
8611 + * Foundation, either version 2 of that License or (at your option) any
8612 + * later version.
8613 + *
8614 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8615 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8616 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8617 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8618 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8619 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8620 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8621 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8622 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8623 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8624 + */
8625 +
8626 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8627 +#define pr_fmt(fmt) \
8628 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8629 + KBUILD_BASENAME".c", __LINE__, __func__
8630 +#else
8631 +#define pr_fmt(fmt) \
8632 + KBUILD_MODNAME ": " fmt
8633 +#endif
8634 +
8635 +#include <linux/init.h>
8636 +#include <linux/skbuff.h>
8637 +#include <linux/highmem.h>
8638 +#include <linux/fsl_bman.h>
8639 +#include <net/sock.h>
8640 +
8641 +#include "dpaa_eth.h"
8642 +#include "dpaa_eth_common.h"
8643 +#ifdef CONFIG_FSL_DPAA_1588
8644 +#include "dpaa_1588.h"
8645 +#endif
8646 +#ifdef CONFIG_FSL_DPAA_CEETM
8647 +#include "dpaa_eth_ceetm.h"
8648 +#endif
8649 +
8650 +/* DMA map and add a page frag back into the bpool.
8651 + * @vaddr fragment must have been allocated with netdev_alloc_frag(),
8652 + * specifically for fitting into @dpa_bp.
8653 + */
8654 +static void dpa_bp_recycle_frag(struct dpa_bp *dpa_bp, unsigned long vaddr,
8655 + int *count_ptr)
8656 +{
8657 + struct bm_buffer bmb;
8658 + dma_addr_t addr;
8659 +
8660 + bmb.opaque = 0;
8661 +
8662 + addr = dma_map_single(dpa_bp->dev, (void *)vaddr, dpa_bp->size,
8663 + DMA_BIDIRECTIONAL);
8664 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
8665 + dev_err(dpa_bp->dev, "DMA mapping failed");
8666 + return;
8667 + }
8668 +
8669 + bm_buffer_set64(&bmb, addr);
8670 +
8671 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
8672 + cpu_relax();
8673 +
8674 + (*count_ptr)++;
8675 +}
8676 +
8677 +static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
8678 +{
8679 + struct bm_buffer bmb[8];
8680 + void *new_buf;
8681 + dma_addr_t addr;
8682 + uint8_t i;
8683 + struct device *dev = dpa_bp->dev;
8684 + struct sk_buff *skb, **skbh;
8685 +
8686 + memset(bmb, 0, sizeof(struct bm_buffer) * 8);
8687 +
8688 + for (i = 0; i < 8; i++) {
8689 + /* We'll prepend the skb back-pointer; can't use the DPA
8690 + * priv space, because FMan will overwrite it (from offset 0)
8691 + * if it ends up being the second, third, etc. fragment
8692 + * in a S/G frame.
8693 + *
8694 + * We only need enough space to store a pointer, but allocate
8695 + * an entire cacheline for performance reasons.
8696 + */
8697 +#ifndef CONFIG_PPC
8698 + if (unlikely(dpaa_errata_a010022)) {
8699 + struct page *new_page = alloc_page(GFP_ATOMIC);
8700 + if (unlikely(!new_page))
8701 + goto netdev_alloc_failed;
8702 + new_buf = page_address(new_page);
8703 + }
8704 + else
8705 +#endif
8706 + new_buf = netdev_alloc_frag(SMP_CACHE_BYTES + DPA_BP_RAW_SIZE);
8707 +
8708 + if (unlikely(!new_buf))
8709 + goto netdev_alloc_failed;
8710 + new_buf = PTR_ALIGN(new_buf + SMP_CACHE_BYTES, SMP_CACHE_BYTES);
8711 +
8712 + skb = build_skb(new_buf, DPA_SKB_SIZE(dpa_bp->size) +
8713 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
8714 + if (unlikely(!skb)) {
8715 + put_page(virt_to_head_page(new_buf));
8716 + goto build_skb_failed;
8717 + }
8718 + DPA_WRITE_SKB_PTR(skb, skbh, new_buf, -1);
8719 +
8720 + addr = dma_map_single(dev, new_buf,
8721 + dpa_bp->size, DMA_BIDIRECTIONAL);
8722 + if (unlikely(dma_mapping_error(dev, addr)))
8723 + goto dma_map_failed;
8724 +
8725 + bm_buffer_set64(&bmb[i], addr);
8726 + }
8727 +
8728 +release_bufs:
8729 + /* Release the buffers. In case bman is busy, keep trying
8730 + * until successful. bman_release() is guaranteed to succeed
8731 + * in a reasonable amount of time
8732 + */
8733 + while (unlikely(bman_release(dpa_bp->pool, bmb, i, 0)))
8734 + cpu_relax();
8735 + return i;
8736 +
8737 +dma_map_failed:
8738 + kfree_skb(skb);
8739 +
8740 +build_skb_failed:
8741 +netdev_alloc_failed:
8742 + net_err_ratelimited("dpa_bp_add_8_bufs() failed\n");
8743 + WARN_ONCE(1, "Memory allocation failure on Rx\n");
8744 +
8745 + bm_buffer_set64(&bmb[i], 0);
8746 + /* Avoid releasing a completely null buffer; bman_release() requires
8747 + * at least one buffer.
8748 + */
8749 + if (likely(i))
8750 + goto release_bufs;
8751 +
8752 + return 0;
8753 +}
8754 +
8755 +/* Cold path wrapper over _dpa_bp_add_8_bufs(). */
8756 +static void dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp, int cpu)
8757 +{
8758 + int *count_ptr = per_cpu_ptr(dpa_bp->percpu_count, cpu);
8759 + *count_ptr += _dpa_bp_add_8_bufs(dpa_bp);
8760 +}
8761 +
8762 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp)
8763 +{
8764 + int i;
8765 +
8766 + /* Give each CPU an allotment of "config_count" buffers */
8767 + for_each_possible_cpu(i) {
8768 + int j;
8769 +
8770 + /* Although we access another CPU's counters here
8771 + * we do it at boot time so it is safe
8772 + */
8773 + for (j = 0; j < dpa_bp->config_count; j += 8)
8774 + dpa_bp_add_8_bufs(dpa_bp, i);
8775 + }
8776 + return 0;
8777 +}
8778 +EXPORT_SYMBOL(dpa_bp_priv_seed);
8779 +
8780 +/* Add buffers/(pages) for Rx processing whenever bpool count falls below
8781 + * REFILL_THRESHOLD.
8782 + */
8783 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr)
8784 +{
8785 + int count = *countptr;
8786 + int new_bufs;
8787 +
8788 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD)) {
8789 + do {
8790 + new_bufs = _dpa_bp_add_8_bufs(dpa_bp);
8791 + if (unlikely(!new_bufs)) {
8792 + /* Avoid looping forever if we've temporarily
8793 + * run out of memory. We'll try again at the
8794 + * next NAPI cycle.
8795 + */
8796 + break;
8797 + }
8798 + count += new_bufs;
8799 + } while (count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT);
8800 +
8801 + *countptr = count;
8802 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT))
8803 + return -ENOMEM;
8804 + }
8805 +
8806 + return 0;
8807 +}
8808 +EXPORT_SYMBOL(dpaa_eth_refill_bpools);
8809 +
8810 +/* Cleanup function for outgoing frame descriptors that were built on Tx path,
8811 + * either contiguous frames or scatter/gather ones.
8812 + * Skb freeing is not handled here.
8813 + *
8814 + * This function may be called on error paths in the Tx function, so guard
8815 + * against cases when not all fd relevant fields were filled in.
8816 + *
8817 + * Return the skb backpointer, since for S/G frames the buffer containing it
8818 + * gets freed here.
8819 + */
8820 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
8821 + const struct qm_fd *fd)
8822 +{
8823 + const struct qm_sg_entry *sgt;
8824 + int i;
8825 + struct dpa_bp *dpa_bp = priv->dpa_bp;
8826 + dma_addr_t addr = qm_fd_addr(fd);
8827 + dma_addr_t sg_addr;
8828 + struct sk_buff **skbh;
8829 + struct sk_buff *skb = NULL;
8830 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
8831 + int nr_frags;
8832 + int sg_len;
8833 +
8834 + /* retrieve skb back pointer */
8835 + DPA_READ_SKB_PTR(skb, skbh, phys_to_virt(addr), 0);
8836 +
8837 + if (unlikely(fd->format == qm_fd_sg)) {
8838 + nr_frags = skb_shinfo(skb)->nr_frags;
8839 + dma_unmap_single(dpa_bp->dev, addr, dpa_fd_offset(fd) +
8840 + sizeof(struct qm_sg_entry) * (1 + nr_frags),
8841 + dma_dir);
8842 +
8843 + /* The sgt buffer has been allocated with netdev_alloc_frag(),
8844 + * it's from lowmem.
8845 + */
8846 + sgt = phys_to_virt(addr + dpa_fd_offset(fd));
8847 +#ifdef CONFIG_FSL_DPAA_1588
8848 + if (priv->tsu && priv->tsu->valid &&
8849 + priv->tsu->hwts_tx_en_ioctl)
8850 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8851 +#endif
8852 +#ifdef CONFIG_FSL_DPAA_TS
8853 + if (unlikely(priv->ts_tx_en &&
8854 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8855 + struct skb_shared_hwtstamps shhwtstamps;
8856 +
8857 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8858 + skb_tstamp_tx(skb, &shhwtstamps);
8859 + }
8860 +#endif /* CONFIG_FSL_DPAA_TS */
8861 +
8862 + /* sgt[0] is from lowmem, was dma_map_single()-ed */
8863 + sg_addr = qm_sg_addr(&sgt[0]);
8864 + sg_len = qm_sg_entry_get_len(&sgt[0]);
8865 + dma_unmap_single(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8866 +
8867 + /* remaining pages were mapped with dma_map_page() */
8868 + for (i = 1; i <= nr_frags; i++) {
8869 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
8870 + sg_addr = qm_sg_addr(&sgt[i]);
8871 + sg_len = qm_sg_entry_get_len(&sgt[i]);
8872 + dma_unmap_page(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8873 + }
8874 +
8875 + /* Free the page frag that we allocated on Tx */
8876 + put_page(virt_to_head_page(sgt));
8877 + } else {
8878 + dma_unmap_single(dpa_bp->dev, addr,
8879 + skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
8880 +#ifdef CONFIG_FSL_DPAA_TS
8881 + /* get the timestamp for non-SG frames */
8882 +#ifdef CONFIG_FSL_DPAA_1588
8883 + if (priv->tsu && priv->tsu->valid &&
8884 + priv->tsu->hwts_tx_en_ioctl)
8885 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8886 +#endif
8887 + if (unlikely(priv->ts_tx_en &&
8888 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8889 + struct skb_shared_hwtstamps shhwtstamps;
8890 +
8891 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8892 + skb_tstamp_tx(skb, &shhwtstamps);
8893 + }
8894 +#endif
8895 + }
8896 +
8897 + return skb;
8898 +}
8899 +EXPORT_SYMBOL(_dpa_cleanup_tx_fd);
8900 +
8901 +#ifndef CONFIG_FSL_DPAA_TS
8902 +bool dpa_skb_is_recyclable(struct sk_buff *skb)
8903 +{
8904 +#ifndef CONFIG_PPC
8905 + /* Do no recycle skbs realigned by the errata workaround */
8906 + if (unlikely(dpaa_errata_a010022) && skb->mark == NONREC_MARK)
8907 + return false;
8908 +#endif
8909 +
8910 + /* No recycling possible if skb buffer is kmalloc'ed */
8911 + if (skb->head_frag == 0)
8912 + return false;
8913 +
8914 + /* or if it's an userspace buffer */
8915 + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
8916 + return false;
8917 +
8918 + /* or if it's cloned or shared */
8919 + if (skb_shared(skb) || skb_cloned(skb) ||
8920 + skb->fclone != SKB_FCLONE_UNAVAILABLE)
8921 + return false;
8922 +
8923 + return true;
8924 +}
8925 +EXPORT_SYMBOL(dpa_skb_is_recyclable);
8926 +
8927 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
8928 + uint32_t min_size,
8929 + uint16_t min_offset,
8930 + unsigned char **new_buf_start)
8931 +{
8932 + unsigned char *new;
8933 +
8934 + /* In order to recycle a buffer, the following conditions must be met:
8935 + * - buffer size no less than the buffer pool size
8936 + * - buffer size no higher than an upper limit (to avoid moving too much
8937 + * system memory to the buffer pools)
8938 + * - buffer address aligned to cacheline bytes
8939 + * - offset of data from start of buffer no lower than a minimum value
8940 + * - offset of data from start of buffer no higher than a maximum value
8941 + */
8942 + new = min(skb_end_pointer(skb) - min_size, skb->data - min_offset);
8943 +
8944 + /* left align to the nearest cacheline */
8945 + new = (unsigned char *)((unsigned long)new & ~(SMP_CACHE_BYTES - 1));
8946 +
8947 + if (likely(new >= skb->head &&
8948 + new >= (skb->data - DPA_MAX_FD_OFFSET) &&
8949 + skb_end_pointer(skb) - new <= DPA_RECYCLE_MAX_SIZE)) {
8950 + *new_buf_start = new;
8951 + return true;
8952 + }
8953 +
8954 + return false;
8955 +}
8956 +EXPORT_SYMBOL(dpa_buf_is_recyclable);
8957 +#endif
8958 +
8959 +/* Build a linear skb around the received buffer.
8960 + * We are guaranteed there is enough room at the end of the data buffer to
8961 + * accommodate the shared info area of the skb.
8962 + */
8963 +static struct sk_buff *__hot contig_fd_to_skb(const struct dpa_priv_s *priv,
8964 + const struct qm_fd *fd, int *use_gro)
8965 +{
8966 + dma_addr_t addr = qm_fd_addr(fd);
8967 + ssize_t fd_off = dpa_fd_offset(fd);
8968 + void *vaddr;
8969 + const fm_prs_result_t *parse_results;
8970 + struct sk_buff *skb = NULL, **skbh;
8971 +
8972 + vaddr = phys_to_virt(addr);
8973 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
8974 +
8975 + /* Retrieve the skb and adjust data and tail pointers, to make sure
8976 + * forwarded skbs will have enough space on Tx if extra headers
8977 + * are added.
8978 + */
8979 + DPA_READ_SKB_PTR(skb, skbh, vaddr, -1);
8980 +
8981 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
8982 + /* When using jumbo Rx buffers, we risk having frames dropped due to
8983 + * the socket backlog reaching its maximum allowed size.
8984 + * Use the frame length for the skb truesize instead of the buffer
8985 + * size, as this is the size of the data that actually gets copied to
8986 + * userspace.
8987 + * The stack may increase the payload. In this case, it will want to
8988 + * warn us that the frame length is larger than the truesize. We
8989 + * bypass the warning.
8990 + */
8991 +#ifndef CONFIG_PPC
8992 + /* We do not support Jumbo frames on LS1043 and thus we edit
8993 + * the skb truesize only when the 4k errata is not present.
8994 + */
8995 + if (likely(!dpaa_errata_a010022))
8996 +#endif
8997 + skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd));
8998 +#endif
8999 +
9000 + DPA_BUG_ON(fd_off != priv->rx_headroom);
9001 + skb_reserve(skb, fd_off);
9002 + skb_put(skb, dpa_fd_length(fd));
9003 +
9004 + /* Peek at the parse results for csum validation */
9005 + parse_results = (const fm_prs_result_t *)(vaddr +
9006 + DPA_RX_PRIV_DATA_SIZE);
9007 + _dpa_process_parse_results(parse_results, fd, skb, use_gro);
9008 +
9009 +#ifdef CONFIG_FSL_DPAA_1588
9010 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl)
9011 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
9012 +#endif
9013 +#ifdef CONFIG_FSL_DPAA_TS
9014 + if (priv->ts_rx_en)
9015 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
9016 +#endif /* CONFIG_FSL_DPAA_TS */
9017 +
9018 + return skb;
9019 +}
9020 +
9021 +
9022 +/* Build an skb with the data of the first S/G entry in the linear portion and
9023 + * the rest of the frame as skb fragments.
9024 + *
9025 + * The page fragment holding the S/G Table is recycled here.
9026 + */
9027 +static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
9028 + const struct qm_fd *fd, int *use_gro,
9029 + int *count_ptr)
9030 +{
9031 + const struct qm_sg_entry *sgt;
9032 + dma_addr_t addr = qm_fd_addr(fd);
9033 + ssize_t fd_off = dpa_fd_offset(fd);
9034 + dma_addr_t sg_addr;
9035 + void *vaddr, *sg_vaddr;
9036 + struct dpa_bp *dpa_bp;
9037 + struct page *page, *head_page;
9038 + int frag_offset, frag_len;
9039 + int page_offset;
9040 + int i;
9041 + const fm_prs_result_t *parse_results;
9042 + struct sk_buff *skb = NULL, *skb_tmp, **skbh;
9043 +
9044 + vaddr = phys_to_virt(addr);
9045 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
9046 +
9047 + dpa_bp = priv->dpa_bp;
9048 + /* Iterate through the SGT entries and add data buffers to the skb */
9049 + sgt = vaddr + fd_off;
9050 + for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
9051 + /* Extension bit is not supported */
9052 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
9053 +
9054 + /* We use a single global Rx pool */
9055 + DPA_BUG_ON(dpa_bp !=
9056 + dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i])));
9057 +
9058 + sg_addr = qm_sg_addr(&sgt[i]);
9059 + sg_vaddr = phys_to_virt(sg_addr);
9060 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
9061 + SMP_CACHE_BYTES));
9062 +
9063 + dma_unmap_single(dpa_bp->dev, sg_addr, dpa_bp->size,
9064 + DMA_BIDIRECTIONAL);
9065 + if (i == 0) {
9066 + DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1);
9067 + DPA_BUG_ON(skb->head != sg_vaddr);
9068 +#ifdef CONFIG_FSL_DPAA_1588
9069 + if (priv->tsu && priv->tsu->valid &&
9070 + priv->tsu->hwts_rx_en_ioctl)
9071 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
9072 +#endif
9073 +#ifdef CONFIG_FSL_DPAA_TS
9074 + if (priv->ts_rx_en)
9075 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
9076 +#endif /* CONFIG_FSL_DPAA_TS */
9077 +
9078 + /* In the case of a SG frame, FMan stores the Internal
9079 + * Context in the buffer containing the sgt.
9080 + * Inspect the parse results before anything else.
9081 + */
9082 + parse_results = (const fm_prs_result_t *)(vaddr +
9083 + DPA_RX_PRIV_DATA_SIZE);
9084 + _dpa_process_parse_results(parse_results, fd, skb,
9085 + use_gro);
9086 +
9087 + /* Make sure forwarded skbs will have enough space
9088 + * on Tx, if extra headers are added.
9089 + */
9090 + DPA_BUG_ON(fd_off != priv->rx_headroom);
9091 + skb_reserve(skb, fd_off);
9092 + skb_put(skb, qm_sg_entry_get_len(&sgt[i]));
9093 + } else {
9094 + /* Not the first S/G entry; all data from buffer will
9095 + * be added in an skb fragment; fragment index is offset
9096 + * by one since first S/G entry was incorporated in the
9097 + * linear part of the skb.
9098 + *
9099 + * Caution: 'page' may be a tail page.
9100 + */
9101 + DPA_READ_SKB_PTR(skb_tmp, skbh, sg_vaddr, -1);
9102 + page = virt_to_page(sg_vaddr);
9103 + head_page = virt_to_head_page(sg_vaddr);
9104 +
9105 + /* Free (only) the skbuff shell because its data buffer
9106 + * is already a frag in the main skb.
9107 + */
9108 + get_page(head_page);
9109 + dev_kfree_skb(skb_tmp);
9110 +
9111 + /* Compute offset in (possibly tail) page */
9112 + page_offset = ((unsigned long)sg_vaddr &
9113 + (PAGE_SIZE - 1)) +
9114 + (page_address(page) - page_address(head_page));
9115 + /* page_offset only refers to the beginning of sgt[i];
9116 + * but the buffer itself may have an internal offset.
9117 + */
9118 + frag_offset = qm_sg_entry_get_offset(&sgt[i]) +
9119 + page_offset;
9120 + frag_len = qm_sg_entry_get_len(&sgt[i]);
9121 + /* skb_add_rx_frag() does no checking on the page; if
9122 + * we pass it a tail page, we'll end up with
9123 + * bad page accounting and eventually with segafults.
9124 + */
9125 + skb_add_rx_frag(skb, i - 1, head_page, frag_offset,
9126 + frag_len, dpa_bp->size);
9127 + }
9128 + /* Update the pool count for the current {cpu x bpool} */
9129 + (*count_ptr)--;
9130 +
9131 + if (qm_sg_entry_get_final(&sgt[i]))
9132 + break;
9133 + }
9134 + WARN_ONCE(i == DPA_SGT_MAX_ENTRIES, "No final bit on SGT\n");
9135 +
9136 + /* recycle the SGT fragment */
9137 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9138 + dpa_bp_recycle_frag(dpa_bp, (unsigned long)vaddr, count_ptr);
9139 + return skb;
9140 +}
9141 +
9142 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9143 +static inline int dpa_skb_loop(const struct dpa_priv_s *priv,
9144 + struct sk_buff *skb)
9145 +{
9146 + if (unlikely(priv->loop_to < 0))
9147 + return 0; /* loop disabled by default */
9148 +
9149 + skb_push(skb, ETH_HLEN); /* compensate for eth_type_trans */
9150 + dpa_tx(skb, dpa_loop_netdevs[priv->loop_to]);
9151 +
9152 + return 1; /* Frame Tx on the selected interface */
9153 +}
9154 +#endif
9155 +
9156 +void __hot _dpa_rx(struct net_device *net_dev,
9157 + struct qman_portal *portal,
9158 + const struct dpa_priv_s *priv,
9159 + struct dpa_percpu_priv_s *percpu_priv,
9160 + const struct qm_fd *fd,
9161 + u32 fqid,
9162 + int *count_ptr)
9163 +{
9164 + struct dpa_bp *dpa_bp;
9165 + struct sk_buff *skb;
9166 + dma_addr_t addr = qm_fd_addr(fd);
9167 + u32 fd_status = fd->status;
9168 + unsigned int skb_len;
9169 + struct rtnl_link_stats64 *percpu_stats = &percpu_priv->stats;
9170 + int use_gro = net_dev->features & NETIF_F_GRO;
9171 +
9172 + if (unlikely(fd_status & FM_FD_STAT_RX_ERRORS) != 0) {
9173 + if (netif_msg_hw(priv) && net_ratelimit())
9174 + netdev_warn(net_dev, "FD status = 0x%08x\n",
9175 + fd_status & FM_FD_STAT_RX_ERRORS);
9176 +
9177 + percpu_stats->rx_errors++;
9178 + goto _release_frame;
9179 + }
9180 +
9181 + dpa_bp = priv->dpa_bp;
9182 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9183 +
9184 + /* prefetch the first 64 bytes of the frame or the SGT start */
9185 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
9186 + prefetch(phys_to_virt(addr) + dpa_fd_offset(fd));
9187 +
9188 + /* The only FD types that we may receive are contig and S/G */
9189 + DPA_BUG_ON((fd->format != qm_fd_contig) && (fd->format != qm_fd_sg));
9190 +
9191 + if (likely(fd->format == qm_fd_contig)) {
9192 +#ifdef CONFIG_FSL_DPAA_HOOKS
9193 + /* Execute the Rx processing hook, if it exists. */
9194 + if (dpaa_eth_hooks.rx_default &&
9195 + dpaa_eth_hooks.rx_default((void *)fd, net_dev,
9196 + fqid) == DPAA_ETH_STOLEN) {
9197 + /* won't count the rx bytes in */
9198 + return;
9199 + }
9200 +#endif
9201 + skb = contig_fd_to_skb(priv, fd, &use_gro);
9202 + } else {
9203 + skb = sg_fd_to_skb(priv, fd, &use_gro, count_ptr);
9204 + percpu_priv->rx_sg++;
9205 + }
9206 +
9207 + /* Account for either the contig buffer or the SGT buffer (depending on
9208 + * which case we were in) having been removed from the pool.
9209 + */
9210 + (*count_ptr)--;
9211 + skb->protocol = eth_type_trans(skb, net_dev);
9212 +
9213 + skb_len = skb->len;
9214 +
9215 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9216 + if (dpa_skb_loop(priv, skb)) {
9217 + percpu_stats->rx_packets++;
9218 + percpu_stats->rx_bytes += skb_len;
9219 + return;
9220 + }
9221 +#endif
9222 +
9223 + if (use_gro) {
9224 + gro_result_t gro_result;
9225 + const struct qman_portal_config *pc =
9226 + qman_p_get_portal_config(portal);
9227 + struct dpa_napi_portal *np = &percpu_priv->np[pc->index];
9228 +
9229 + np->p = portal;
9230 + gro_result = napi_gro_receive(&np->napi, skb);
9231 + /* If frame is dropped by the stack, rx_dropped counter is
9232 + * incremented automatically, so no need for us to update it
9233 + */
9234 + if (unlikely(gro_result == GRO_DROP))
9235 + goto packet_dropped;
9236 + } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
9237 + goto packet_dropped;
9238 +
9239 + percpu_stats->rx_packets++;
9240 + percpu_stats->rx_bytes += skb_len;
9241 +
9242 +packet_dropped:
9243 + return;
9244 +
9245 +_release_frame:
9246 + dpa_fd_release(net_dev, fd);
9247 +}
9248 +
9249 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
9250 + struct sk_buff *skb, struct qm_fd *fd,
9251 + int *count_ptr, int *offset)
9252 +{
9253 + struct sk_buff **skbh;
9254 + dma_addr_t addr;
9255 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9256 + struct net_device *net_dev = priv->net_dev;
9257 + int err;
9258 + enum dma_data_direction dma_dir;
9259 + unsigned char *buffer_start;
9260 + int dma_map_size;
9261 +
9262 +#ifndef CONFIG_FSL_DPAA_TS
9263 + /* Check recycling conditions; only if timestamp support is not
9264 + * enabled, otherwise we need the fd back on tx confirmation
9265 + */
9266 +
9267 + /* We can recycle the buffer if:
9268 + * - the pool is not full
9269 + * - the buffer meets the skb recycling conditions
9270 + * - the buffer meets our own (size, offset, align) conditions
9271 + */
9272 + if (likely((*count_ptr < dpa_bp->target_count) &&
9273 + dpa_skb_is_recyclable(skb) &&
9274 + dpa_buf_is_recyclable(skb, dpa_bp->size,
9275 + priv->tx_headroom, &buffer_start))) {
9276 + /* Buffer is recyclable; use the new start address
9277 + * and set fd parameters and DMA mapping direction
9278 + */
9279 + fd->bpid = dpa_bp->bpid;
9280 + DPA_BUG_ON(skb->data - buffer_start > DPA_MAX_FD_OFFSET);
9281 + fd->offset = (uint16_t)(skb->data - buffer_start);
9282 + dma_dir = DMA_BIDIRECTIONAL;
9283 + dma_map_size = dpa_bp->size;
9284 +
9285 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, -1);
9286 + *offset = skb_headroom(skb) - fd->offset;
9287 + } else
9288 +#endif
9289 + {
9290 + /* Not recyclable.
9291 + * We are guaranteed to have at least tx_headroom bytes
9292 + * available, so just use that for offset.
9293 + */
9294 + fd->bpid = 0xff;
9295 + buffer_start = skb->data - priv->tx_headroom;
9296 + fd->offset = priv->tx_headroom;
9297 + dma_dir = DMA_TO_DEVICE;
9298 + dma_map_size = skb_tail_pointer(skb) - buffer_start;
9299 +
9300 + /* The buffer will be Tx-confirmed, but the TxConf cb must
9301 + * necessarily look at our Tx private data to retrieve the
9302 + * skbuff. (In short: can't use DPA_WRITE_SKB_PTR() here.)
9303 + */
9304 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, 0);
9305 + }
9306 +
9307 + /* Enable L3/L4 hardware checksum computation.
9308 + *
9309 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9310 + * need to write into the skb.
9311 + */
9312 + err = dpa_enable_tx_csum(priv, skb, fd,
9313 + ((char *)skbh) + DPA_TX_PRIV_DATA_SIZE);
9314 + if (unlikely(err < 0)) {
9315 + if (netif_msg_tx_err(priv) && net_ratelimit())
9316 + netdev_err(net_dev, "HW csum error: %d\n", err);
9317 + return err;
9318 + }
9319 +
9320 + /* Fill in the rest of the FD fields */
9321 + fd->format = qm_fd_contig;
9322 + fd->length20 = skb->len;
9323 + fd->cmd |= FM_FD_CMD_FCO;
9324 +
9325 + /* Map the entire buffer size that may be seen by FMan, but no more */
9326 + addr = dma_map_single(dpa_bp->dev, skbh, dma_map_size, dma_dir);
9327 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9328 + if (netif_msg_tx_err(priv) && net_ratelimit())
9329 + netdev_err(net_dev, "dma_map_single() failed\n");
9330 + return -EINVAL;
9331 + }
9332 + qm_fd_addr_set64(fd, addr);
9333 +
9334 + return 0;
9335 +}
9336 +EXPORT_SYMBOL(skb_to_contig_fd);
9337 +
9338 +#ifndef CONFIG_PPC
9339 +/* Verify the conditions that trigger the A010022 errata: data unaligned to
9340 + * 16 bytes and 4K memory address crossings.
9341 + */
9342 +static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv)
9343 +{
9344 + int nr_frags, i = 0;
9345 + skb_frag_t *frag;
9346 +
9347 + /* Check if the headroom is aligned */
9348 + if (((uintptr_t)skb->data - priv->tx_headroom) %
9349 + priv->buf_layout[TX].data_align != 0)
9350 + return true;
9351 +
9352 + /* Check if the headroom crosses a boundary */
9353 + if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb)))
9354 + return true;
9355 +
9356 + /* Check if the non-paged data crosses a boundary */
9357 + if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb)))
9358 + return true;
9359 +
9360 + /* Check if the entire linear skb crosses a boundary */
9361 + if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb)))
9362 + return true;
9363 +
9364 + nr_frags = skb_shinfo(skb)->nr_frags;
9365 +
9366 + while (i < nr_frags) {
9367 + frag = &skb_shinfo(skb)->frags[i];
9368 +
9369 + /* Check if a paged fragment crosses a boundary from its
9370 + * offset to its end.
9371 + */
9372 + if (HAS_DMA_ISSUE(frag->page_offset, frag->size))
9373 + return true;
9374 +
9375 + i++;
9376 + }
9377 +
9378 + return false;
9379 +}
9380 +
9381 +/* Realign the skb by copying its contents at the start of a newly allocated
9382 + * page. Build a new skb around the new buffer and release the old one.
9383 + * A performance drop should be expected.
9384 + */
9385 +static struct sk_buff *a010022_realign_skb(struct sk_buff *skb,
9386 + struct dpa_priv_s *priv)
9387 +{
9388 + int trans_offset = skb_transport_offset(skb);
9389 + int net_offset = skb_network_offset(skb);
9390 + struct sk_buff *nskb = NULL;
9391 + int nsize, headroom;
9392 + struct page *npage;
9393 + void *npage_addr;
9394 +
9395 + /* Guarantee the minimum required headroom */
9396 + if (skb_headroom(skb) >= priv->tx_headroom)
9397 + headroom = skb_headroom(skb);
9398 + else
9399 + headroom = priv->tx_headroom;
9400 +
9401 + npage = alloc_page(GFP_ATOMIC);
9402 + if (unlikely(!npage)) {
9403 + WARN_ONCE(1, "Memory allocation failure\n");
9404 + return NULL;
9405 + }
9406 + npage_addr = page_address(npage);
9407 +
9408 + /* For the new skb we only need the old one's data (both non-paged and
9409 + * paged) and a headroom large enough to fit our private info. We can
9410 + * skip the old tailroom.
9411 + *
9412 + * Make sure the new linearized buffer will not exceed a page's size.
9413 + */
9414 + nsize = headroom + skb->len +
9415 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
9416 + if (unlikely(nsize > 4096))
9417 + goto err;
9418 +
9419 + nskb = build_skb(npage_addr, nsize);
9420 + if (unlikely(!nskb))
9421 + goto err;
9422 +
9423 + /* Reserve only the needed headroom in order to guarantee the data's
9424 + * alignment.
9425 + * Code borrowed and adapted from skb_copy().
9426 + */
9427 + skb_reserve(nskb, priv->tx_headroom);
9428 + skb_put(nskb, skb->len);
9429 + if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
9430 + WARN_ONCE(1, "skb parsing failure\n");
9431 + goto err;
9432 + }
9433 + copy_skb_header(nskb, skb);
9434 +
9435 +#ifdef CONFIG_FSL_DPAA_TS
9436 + /* Copy relevant timestamp info from the old skb to the new */
9437 + if (priv->ts_tx_en) {
9438 + skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags;
9439 + skb_shinfo(nskb)->hwtstamps = skb_shinfo(skb)->hwtstamps;
9440 + skb_shinfo(nskb)->tskey = skb_shinfo(skb)->tskey;
9441 + if (skb->sk)
9442 + skb_set_owner_w(nskb, skb->sk);
9443 + }
9444 +#endif
9445 + /* We move the headroom when we align it so we have to reset the
9446 + * network and transport header offsets relative to the new data
9447 + * pointer. The checksum offload relies on these offsets.
9448 + */
9449 + skb_set_network_header(nskb, net_offset);
9450 + skb_set_transport_header(nskb, trans_offset);
9451 +
9452 + /* We don't want the buffer to be recycled so we mark it accordingly */
9453 + nskb->mark = NONREC_MARK;
9454 +
9455 + dev_kfree_skb(skb);
9456 + return nskb;
9457 +
9458 +err:
9459 + if (nskb)
9460 + dev_kfree_skb(nskb);
9461 + put_page(npage);
9462 + return NULL;
9463 +}
9464 +#endif
9465 +
9466 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
9467 + struct sk_buff *skb, struct qm_fd *fd)
9468 +{
9469 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9470 + dma_addr_t addr;
9471 + dma_addr_t sg_addr;
9472 + struct sk_buff **skbh;
9473 + struct net_device *net_dev = priv->net_dev;
9474 + int sg_len, sgt_size;
9475 + int err;
9476 +
9477 + struct qm_sg_entry *sgt;
9478 + void *sgt_buf;
9479 + skb_frag_t *frag;
9480 + int i = 0, j = 0;
9481 + int nr_frags;
9482 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
9483 +
9484 + nr_frags = skb_shinfo(skb)->nr_frags;
9485 + fd->format = qm_fd_sg;
9486 +
9487 + sgt_size = sizeof(struct qm_sg_entry) * (1 + nr_frags);
9488 +
9489 + /* Get a page frag to store the SGTable, or a full page if the errata
9490 + * is in place and we need to avoid crossing a 4k boundary.
9491 + */
9492 +#ifndef CONFIG_PPC
9493 + if (unlikely(dpaa_errata_a010022))
9494 + sgt_buf = page_address(alloc_page(GFP_ATOMIC));
9495 + else
9496 +#endif
9497 + sgt_buf = netdev_alloc_frag(priv->tx_headroom + sgt_size);
9498 + if (unlikely(!sgt_buf)) {
9499 + dev_err(dpa_bp->dev, "netdev_alloc_frag() failed\n");
9500 + return -ENOMEM;
9501 + }
9502 +
9503 + /* it seems that the memory allocator does not zero the allocated mem */
9504 + memset(sgt_buf, 0, priv->tx_headroom + sgt_size);
9505 +
9506 + /* Enable L3/L4 hardware checksum computation.
9507 + *
9508 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9509 + * need to write into the skb.
9510 + */
9511 + err = dpa_enable_tx_csum(priv, skb, fd,
9512 + sgt_buf + DPA_TX_PRIV_DATA_SIZE);
9513 + if (unlikely(err < 0)) {
9514 + if (netif_msg_tx_err(priv) && net_ratelimit())
9515 + netdev_err(net_dev, "HW csum error: %d\n", err);
9516 + goto csum_failed;
9517 + }
9518 +
9519 + /* Assign the data from skb->data to the first SG list entry */
9520 + sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
9521 + sg_len = skb_headlen(skb);
9522 + qm_sg_entry_set_bpid(&sgt[0], 0xff);
9523 + qm_sg_entry_set_offset(&sgt[0], 0);
9524 + qm_sg_entry_set_len(&sgt[0], sg_len);
9525 + qm_sg_entry_set_ext(&sgt[0], 0);
9526 + qm_sg_entry_set_final(&sgt[0], 0);
9527 +
9528 + addr = dma_map_single(dpa_bp->dev, skb->data, sg_len, dma_dir);
9529 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9530 + dev_err(dpa_bp->dev, "DMA mapping failed");
9531 + err = -EINVAL;
9532 + goto sg0_map_failed;
9533 + }
9534 +
9535 + qm_sg_entry_set64(&sgt[0], addr);
9536 +
9537 + /* populate the rest of SGT entries */
9538 + for (i = 1; i <= nr_frags; i++) {
9539 + frag = &skb_shinfo(skb)->frags[i - 1];
9540 + qm_sg_entry_set_bpid(&sgt[i], 0xff);
9541 + qm_sg_entry_set_offset(&sgt[i], 0);
9542 + qm_sg_entry_set_len(&sgt[i], frag->size);
9543 + qm_sg_entry_set_ext(&sgt[i], 0);
9544 +
9545 + if (i == nr_frags)
9546 + qm_sg_entry_set_final(&sgt[i], 1);
9547 + else
9548 + qm_sg_entry_set_final(&sgt[i], 0);
9549 +
9550 + DPA_BUG_ON(!skb_frag_page(frag));
9551 + addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->size,
9552 + dma_dir);
9553 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9554 + dev_err(dpa_bp->dev, "DMA mapping failed");
9555 + err = -EINVAL;
9556 + goto sg_map_failed;
9557 + }
9558 +
9559 + /* keep the offset in the address */
9560 + qm_sg_entry_set64(&sgt[i], addr);
9561 + }
9562 +
9563 + fd->length20 = skb->len;
9564 + fd->offset = priv->tx_headroom;
9565 +
9566 + /* DMA map the SGT page */
9567 + DPA_WRITE_SKB_PTR(skb, skbh, sgt_buf, 0);
9568 + addr = dma_map_single(dpa_bp->dev, sgt_buf,
9569 + priv->tx_headroom + sgt_size,
9570 + dma_dir);
9571 +
9572 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9573 + dev_err(dpa_bp->dev, "DMA mapping failed");
9574 + err = -EINVAL;
9575 + goto sgt_map_failed;
9576 + }
9577 +
9578 + qm_fd_addr_set64(fd, addr);
9579 + fd->bpid = 0xff;
9580 + fd->cmd |= FM_FD_CMD_FCO;
9581 +
9582 + return 0;
9583 +
9584 +sgt_map_failed:
9585 +sg_map_failed:
9586 + for (j = 0; j < i; j++) {
9587 + sg_addr = qm_sg_addr(&sgt[j]);
9588 + dma_unmap_page(dpa_bp->dev, sg_addr,
9589 + qm_sg_entry_get_len(&sgt[j]), dma_dir);
9590 + }
9591 +sg0_map_failed:
9592 +csum_failed:
9593 + put_page(virt_to_head_page(sgt_buf));
9594 +
9595 + return err;
9596 +}
9597 +EXPORT_SYMBOL(skb_to_sg_fd);
9598 +
9599 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev)
9600 +{
9601 + struct dpa_priv_s *priv;
9602 + const int queue_mapping = dpa_get_queue_mapping(skb);
9603 + struct qman_fq *egress_fq, *conf_fq;
9604 +
9605 +#ifdef CONFIG_FSL_DPAA_HOOKS
9606 + /* If there is a Tx hook, run it. */
9607 + if (dpaa_eth_hooks.tx &&
9608 + dpaa_eth_hooks.tx(skb, net_dev) == DPAA_ETH_STOLEN)
9609 + /* won't update any Tx stats */
9610 + return NETDEV_TX_OK;
9611 +#endif
9612 +
9613 + priv = netdev_priv(net_dev);
9614 +
9615 +#ifdef CONFIG_FSL_DPAA_CEETM
9616 + if (priv->ceetm_en)
9617 + return ceetm_tx(skb, net_dev);
9618 +#endif
9619 +
9620 + egress_fq = priv->egress_fqs[queue_mapping];
9621 + conf_fq = priv->conf_fqs[queue_mapping];
9622 +
9623 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
9624 +}
9625 +
9626 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
9627 + struct qman_fq *egress_fq, struct qman_fq *conf_fq)
9628 +{
9629 + struct dpa_priv_s *priv;
9630 + struct qm_fd fd;
9631 + struct dpa_percpu_priv_s *percpu_priv;
9632 + struct rtnl_link_stats64 *percpu_stats;
9633 + int err = 0;
9634 + bool nonlinear;
9635 + int *countptr, offset = 0;
9636 +
9637 + priv = netdev_priv(net_dev);
9638 + /* Non-migratable context, safe to use raw_cpu_ptr */
9639 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
9640 + percpu_stats = &percpu_priv->stats;
9641 + countptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
9642 +
9643 + clear_fd(&fd);
9644 +
9645 +#ifndef CONFIG_PPC
9646 + if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) {
9647 + skb = a010022_realign_skb(skb, priv);
9648 + if (!skb)
9649 + goto skb_to_fd_failed;
9650 + }
9651 +#endif
9652 +
9653 + nonlinear = skb_is_nonlinear(skb);
9654 +
9655 +#ifdef CONFIG_FSL_DPAA_1588
9656 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl)
9657 + fd.cmd |= FM_FD_CMD_UPD;
9658 +#endif
9659 +#ifdef CONFIG_FSL_DPAA_TS
9660 + if (unlikely(priv->ts_tx_en &&
9661 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
9662 + fd.cmd |= FM_FD_CMD_UPD;
9663 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
9664 +#endif /* CONFIG_FSL_DPAA_TS */
9665 +
9666 + /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure
9667 + * we don't feed FMan with more fragments than it supports.
9668 + * Btw, we're using the first sgt entry to store the linear part of
9669 + * the skb, so we're one extra frag short.
9670 + */
9671 + if (nonlinear &&
9672 + likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) {
9673 + /* Just create a S/G fd based on the skb */
9674 + err = skb_to_sg_fd(priv, skb, &fd);
9675 + percpu_priv->tx_frag_skbuffs++;
9676 + } else {
9677 + /* Make sure we have enough headroom to accommodate private
9678 + * data, parse results, etc. Normally this shouldn't happen if
9679 + * we're here via the standard kernel stack.
9680 + */
9681 + if (unlikely(skb_headroom(skb) < priv->tx_headroom)) {
9682 + struct sk_buff *skb_new;
9683 +
9684 + skb_new = skb_realloc_headroom(skb, priv->tx_headroom);
9685 + if (unlikely(!skb_new)) {
9686 + dev_kfree_skb(skb);
9687 + percpu_stats->tx_errors++;
9688 + return NETDEV_TX_OK;
9689 + }
9690 + dev_kfree_skb(skb);
9691 + skb = skb_new;
9692 + }
9693 +
9694 + /* We're going to store the skb backpointer at the beginning
9695 + * of the data buffer, so we need a privately owned skb
9696 + */
9697 +
9698 + /* Code borrowed from skb_unshare(). */
9699 + if (skb_cloned(skb)) {
9700 + struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
9701 + kfree_skb(skb);
9702 + skb = nskb;
9703 +#ifndef CONFIG_PPC
9704 + if (unlikely(dpaa_errata_a010022) &&
9705 + a010022_check_skb(skb, priv)) {
9706 + skb = a010022_realign_skb(skb, priv);
9707 + if (!skb)
9708 + goto skb_to_fd_failed;
9709 + }
9710 +#endif
9711 + /* skb_copy() has now linearized the skbuff. */
9712 + } else if (unlikely(nonlinear)) {
9713 + /* We are here because the egress skb contains
9714 + * more fragments than we support. In this case,
9715 + * we have no choice but to linearize it ourselves.
9716 + */
9717 + err = __skb_linearize(skb);
9718 + }
9719 + if (unlikely(!skb || err < 0))
9720 + /* Common out-of-memory error path */
9721 + goto enomem;
9722 +
9723 + err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset);
9724 + }
9725 + if (unlikely(err < 0))
9726 + goto skb_to_fd_failed;
9727 +
9728 + if (fd.bpid != 0xff) {
9729 + skb_recycle(skb);
9730 + /* skb_recycle() reserves NET_SKB_PAD as skb headroom,
9731 + * but we need the skb to look as if returned by build_skb().
9732 + * We need to manually adjust the tailptr as well.
9733 + */
9734 + skb->data = skb->head + offset;
9735 + skb_reset_tail_pointer(skb);
9736 +
9737 + (*countptr)++;
9738 + percpu_priv->tx_returned++;
9739 + }
9740 +
9741 + if (unlikely(dpa_xmit(priv, percpu_stats, &fd, egress_fq, conf_fq) < 0))
9742 + goto xmit_failed;
9743 +
9744 + netif_trans_update(net_dev);
9745 + return NETDEV_TX_OK;
9746 +
9747 +xmit_failed:
9748 + if (fd.bpid != 0xff) {
9749 + (*countptr)--;
9750 + percpu_priv->tx_returned--;
9751 + dpa_fd_release(net_dev, &fd);
9752 + percpu_stats->tx_errors++;
9753 + return NETDEV_TX_OK;
9754 + }
9755 + _dpa_cleanup_tx_fd(priv, &fd);
9756 +skb_to_fd_failed:
9757 +enomem:
9758 + percpu_stats->tx_errors++;
9759 + dev_kfree_skb(skb);
9760 + return NETDEV_TX_OK;
9761 +}
9762 +EXPORT_SYMBOL(dpa_tx_extended);
9763 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
9764 new file mode 100644
9765 index 00000000..3542d0b2
9766 --- /dev/null
9767 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
9768 @@ -0,0 +1,278 @@
9769 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
9770 + *
9771 + * Redistribution and use in source and binary forms, with or without
9772 + * modification, are permitted provided that the following conditions are met:
9773 + * * Redistributions of source code must retain the above copyright
9774 + * notice, this list of conditions and the following disclaimer.
9775 + * * Redistributions in binary form must reproduce the above copyright
9776 + * notice, this list of conditions and the following disclaimer in the
9777 + * documentation and/or other materials provided with the distribution.
9778 + * * Neither the name of Freescale Semiconductor nor the
9779 + * names of its contributors may be used to endorse or promote products
9780 + * derived from this software without specific prior written permission.
9781 + *
9782 + *
9783 + * ALTERNATIVELY, this software may be distributed under the terms of the
9784 + * GNU General Public License ("GPL") as published by the Free Software
9785 + * Foundation, either version 2 of that License or (at your option) any
9786 + * later version.
9787 + *
9788 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
9789 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9790 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9791 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
9792 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9793 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9794 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
9795 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9796 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
9797 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9798 + */
9799 +
9800 +#include <linux/init.h>
9801 +#include <linux/module.h>
9802 +#include <linux/kthread.h>
9803 +#include <linux/io.h>
9804 +#include <linux/of_net.h>
9805 +#include "dpaa_eth.h"
9806 +#include "mac.h" /* struct mac_device */
9807 +#ifdef CONFIG_FSL_DPAA_1588
9808 +#include "dpaa_1588.h"
9809 +#endif
9810 +
9811 +static ssize_t dpaa_eth_show_addr(struct device *dev,
9812 + struct device_attribute *attr, char *buf)
9813 +{
9814 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9815 + struct mac_device *mac_dev = priv->mac_dev;
9816 +
9817 + if (mac_dev)
9818 + return sprintf(buf, "%llx",
9819 + (unsigned long long)mac_dev->res->start);
9820 + else
9821 + return sprintf(buf, "none");
9822 +}
9823 +
9824 +static ssize_t dpaa_eth_show_type(struct device *dev,
9825 + struct device_attribute *attr, char *buf)
9826 +{
9827 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9828 + ssize_t res = 0;
9829 +
9830 + if (priv)
9831 + res = sprintf(buf, "%s", priv->if_type);
9832 +
9833 + return res;
9834 +}
9835 +
9836 +static ssize_t dpaa_eth_show_fqids(struct device *dev,
9837 + struct device_attribute *attr, char *buf)
9838 +{
9839 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9840 + ssize_t bytes = 0;
9841 + int i = 0;
9842 + char *str;
9843 + struct dpa_fq *fq;
9844 + struct dpa_fq *tmp;
9845 + struct dpa_fq *prev = NULL;
9846 + u32 first_fqid = 0;
9847 + u32 last_fqid = 0;
9848 + char *prevstr = NULL;
9849 +
9850 + list_for_each_entry_safe(fq, tmp, &priv->dpa_fq_list, list) {
9851 + switch (fq->fq_type) {
9852 + case FQ_TYPE_RX_DEFAULT:
9853 + str = "Rx default";
9854 + break;
9855 + case FQ_TYPE_RX_ERROR:
9856 + str = "Rx error";
9857 + break;
9858 + case FQ_TYPE_RX_PCD:
9859 + str = "Rx PCD";
9860 + break;
9861 + case FQ_TYPE_TX_CONFIRM:
9862 + str = "Tx default confirmation";
9863 + break;
9864 + case FQ_TYPE_TX_CONF_MQ:
9865 + str = "Tx confirmation (mq)";
9866 + break;
9867 + case FQ_TYPE_TX_ERROR:
9868 + str = "Tx error";
9869 + break;
9870 + case FQ_TYPE_TX:
9871 + str = "Tx";
9872 + break;
9873 + case FQ_TYPE_RX_PCD_HI_PRIO:
9874 + str ="Rx PCD High Priority";
9875 + break;
9876 + default:
9877 + str = "Unknown";
9878 + }
9879 +
9880 + if (prev && (abs(fq->fqid - prev->fqid) != 1 ||
9881 + str != prevstr)) {
9882 + if (last_fqid == first_fqid)
9883 + bytes += sprintf(buf + bytes,
9884 + "%s: %d\n", prevstr, prev->fqid);
9885 + else
9886 + bytes += sprintf(buf + bytes,
9887 + "%s: %d - %d\n", prevstr,
9888 + first_fqid, last_fqid);
9889 + }
9890 +
9891 + if (prev && abs(fq->fqid - prev->fqid) == 1 && str == prevstr)
9892 + last_fqid = fq->fqid;
9893 + else
9894 + first_fqid = last_fqid = fq->fqid;
9895 +
9896 + prev = fq;
9897 + prevstr = str;
9898 + i++;
9899 + }
9900 +
9901 + if (prev) {
9902 + if (last_fqid == first_fqid)
9903 + bytes += sprintf(buf + bytes, "%s: %d\n", prevstr,
9904 + prev->fqid);
9905 + else
9906 + bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr,
9907 + first_fqid, last_fqid);
9908 + }
9909 +
9910 + return bytes;
9911 +}
9912 +
9913 +static ssize_t dpaa_eth_show_bpids(struct device *dev,
9914 + struct device_attribute *attr, char *buf)
9915 +{
9916 + ssize_t bytes = 0;
9917 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9918 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9919 + int i = 0;
9920 +
9921 + for (i = 0; i < priv->bp_count; i++)
9922 + bytes += snprintf(buf + bytes, PAGE_SIZE, "%u\n",
9923 + dpa_bp[i].bpid);
9924 +
9925 + return bytes;
9926 +}
9927 +
9928 +static ssize_t dpaa_eth_show_mac_regs(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 + int n = 0;
9934 +
9935 + if (mac_dev)
9936 + n = fm_mac_dump_regs(mac_dev, buf, n);
9937 + else
9938 + return sprintf(buf, "no mac registers\n");
9939 +
9940 + return n;
9941 +}
9942 +
9943 +static ssize_t dpaa_eth_show_mac_rx_stats(struct device *dev,
9944 + struct device_attribute *attr, char *buf)
9945 +{
9946 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9947 + struct mac_device *mac_dev = priv->mac_dev;
9948 + int n = 0;
9949 +
9950 + if (mac_dev)
9951 + n = fm_mac_dump_rx_stats(mac_dev, buf, n);
9952 + else
9953 + return sprintf(buf, "no mac rx stats\n");
9954 +
9955 + return n;
9956 +}
9957 +
9958 +static ssize_t dpaa_eth_show_mac_tx_stats(struct device *dev,
9959 + struct device_attribute *attr, char *buf)
9960 +{
9961 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9962 + struct mac_device *mac_dev = priv->mac_dev;
9963 + int n = 0;
9964 +
9965 + if (mac_dev)
9966 + n = fm_mac_dump_tx_stats(mac_dev, buf, n);
9967 + else
9968 + return sprintf(buf, "no mac tx stats\n");
9969 +
9970 + return n;
9971 +}
9972 +
9973 +#ifdef CONFIG_FSL_DPAA_1588
9974 +static ssize_t dpaa_eth_show_ptp_1588(struct device *dev,
9975 + struct device_attribute *attr, char *buf)
9976 +{
9977 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9978 +
9979 + if (priv->tsu && priv->tsu->valid)
9980 + return sprintf(buf, "1\n");
9981 + else
9982 + return sprintf(buf, "0\n");
9983 +}
9984 +
9985 +static ssize_t dpaa_eth_set_ptp_1588(struct device *dev,
9986 + struct device_attribute *attr,
9987 + const char *buf, size_t count)
9988 +{
9989 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9990 + unsigned int num;
9991 + unsigned long flags;
9992 +
9993 + if (kstrtouint(buf, 0, &num) < 0)
9994 + return -EINVAL;
9995 +
9996 + local_irq_save(flags);
9997 +
9998 + if (num) {
9999 + if (priv->tsu)
10000 + priv->tsu->valid = TRUE;
10001 + } else {
10002 + if (priv->tsu)
10003 + priv->tsu->valid = FALSE;
10004 + }
10005 +
10006 + local_irq_restore(flags);
10007 +
10008 + return count;
10009 +}
10010 +#endif
10011 +
10012 +static struct device_attribute dpaa_eth_attrs[] = {
10013 + __ATTR(device_addr, S_IRUGO, dpaa_eth_show_addr, NULL),
10014 + __ATTR(device_type, S_IRUGO, dpaa_eth_show_type, NULL),
10015 + __ATTR(fqids, S_IRUGO, dpaa_eth_show_fqids, NULL),
10016 + __ATTR(bpids, S_IRUGO, dpaa_eth_show_bpids, NULL),
10017 + __ATTR(mac_regs, S_IRUGO, dpaa_eth_show_mac_regs, NULL),
10018 + __ATTR(mac_rx_stats, S_IRUGO, dpaa_eth_show_mac_rx_stats, NULL),
10019 + __ATTR(mac_tx_stats, S_IRUGO, dpaa_eth_show_mac_tx_stats, NULL),
10020 +#ifdef CONFIG_FSL_DPAA_1588
10021 + __ATTR(ptp_1588, S_IRUGO | S_IWUSR, dpaa_eth_show_ptp_1588,
10022 + dpaa_eth_set_ptp_1588),
10023 +#endif
10024 +};
10025 +
10026 +void dpaa_eth_sysfs_init(struct device *dev)
10027 +{
10028 + int i;
10029 +
10030 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
10031 + if (device_create_file(dev, &dpaa_eth_attrs[i])) {
10032 + dev_err(dev, "Error creating sysfs file\n");
10033 + while (i > 0)
10034 + device_remove_file(dev, &dpaa_eth_attrs[--i]);
10035 + return;
10036 + }
10037 +}
10038 +EXPORT_SYMBOL(dpaa_eth_sysfs_init);
10039 +
10040 +void dpaa_eth_sysfs_remove(struct device *dev)
10041 +{
10042 + int i;
10043 +
10044 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
10045 + device_remove_file(dev, &dpaa_eth_attrs[i]);
10046 +}
10047 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
10048 new file mode 100644
10049 index 00000000..30069ef9
10050 --- /dev/null
10051 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
10052 @@ -0,0 +1,144 @@
10053 +/* Copyright 2013 Freescale Semiconductor Inc.
10054 + *
10055 + * Redistribution and use in source and binary forms, with or without
10056 + * modification, are permitted provided that the following conditions are met:
10057 + * * Redistributions of source code must retain the above copyright
10058 + * notice, this list of conditions and the following disclaimer.
10059 + * * Redistributions in binary form must reproduce the above copyright
10060 + * notice, this list of conditions and the following disclaimer in the
10061 + * documentation and/or other materials provided with the distribution.
10062 + * * Neither the name of Freescale Semiconductor nor the
10063 + * names of its contributors may be used to endorse or promote products
10064 + * derived from this software without specific prior written permission.
10065 + *
10066 + *
10067 + * ALTERNATIVELY, this software may be distributed under the terms of the
10068 + * GNU General Public License ("GPL") as published by the Free Software
10069 + * Foundation, either version 2 of that License or (at your option) any
10070 + * later version.
10071 + *
10072 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10073 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10074 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10075 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10076 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10077 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10078 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10079 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10080 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10081 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10082 + */
10083 +
10084 +#undef TRACE_SYSTEM
10085 +#define TRACE_SYSTEM dpaa_eth
10086 +
10087 +#if !defined(_DPAA_ETH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
10088 +#define _DPAA_ETH_TRACE_H
10089 +
10090 +#include <linux/skbuff.h>
10091 +#include <linux/netdevice.h>
10092 +#include "dpaa_eth.h"
10093 +#include <linux/tracepoint.h>
10094 +
10095 +#define fd_format_name(format) { qm_fd_##format, #format }
10096 +#define fd_format_list \
10097 + fd_format_name(contig), \
10098 + fd_format_name(sg)
10099 +#define TR_FMT "[%s] fqid=%d, fd: addr=0x%llx, format=%s, off=%u, len=%u," \
10100 + " status=0x%08x"
10101 +
10102 +/* This is used to declare a class of events.
10103 + * individual events of this type will be defined below.
10104 + */
10105 +
10106 +/* Store details about a frame descriptor and the FQ on which it was
10107 + * transmitted/received.
10108 + */
10109 +DECLARE_EVENT_CLASS(dpaa_eth_fd,
10110 + /* Trace function prototype */
10111 + TP_PROTO(struct net_device *netdev,
10112 + struct qman_fq *fq,
10113 + const struct qm_fd *fd),
10114 +
10115 + /* Repeat argument list here */
10116 + TP_ARGS(netdev, fq, fd),
10117 +
10118 + /* A structure containing the relevant information we want to record.
10119 + * Declare name and type for each normal element, name, type and size
10120 + * for arrays. Use __string for variable length strings.
10121 + */
10122 + TP_STRUCT__entry(
10123 + __field(u32, fqid)
10124 + __field(u64, fd_addr)
10125 + __field(u8, fd_format)
10126 + __field(u16, fd_offset)
10127 + __field(u32, fd_length)
10128 + __field(u32, fd_status)
10129 + __string(name, netdev->name)
10130 + ),
10131 +
10132 + /* The function that assigns values to the above declared fields */
10133 + TP_fast_assign(
10134 + __entry->fqid = fq->fqid;
10135 + __entry->fd_addr = qm_fd_addr_get64(fd);
10136 + __entry->fd_format = fd->format;
10137 + __entry->fd_offset = dpa_fd_offset(fd);
10138 + __entry->fd_length = dpa_fd_length(fd);
10139 + __entry->fd_status = fd->status;
10140 + __assign_str(name, netdev->name);
10141 + ),
10142 +
10143 + /* This is what gets printed when the trace event is triggered */
10144 + /* TODO: print the status using __print_flags() */
10145 + TP_printk(TR_FMT,
10146 + __get_str(name), __entry->fqid, __entry->fd_addr,
10147 + __print_symbolic(__entry->fd_format, fd_format_list),
10148 + __entry->fd_offset, __entry->fd_length, __entry->fd_status)
10149 +);
10150 +
10151 +/* Now declare events of the above type. Format is:
10152 + * DEFINE_EVENT(class, name, proto, args), with proto and args same as for class
10153 + */
10154 +
10155 +/* Tx (egress) fd */
10156 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_fd,
10157 +
10158 + TP_PROTO(struct net_device *netdev,
10159 + struct qman_fq *fq,
10160 + const struct qm_fd *fd),
10161 +
10162 + TP_ARGS(netdev, fq, fd)
10163 +);
10164 +
10165 +/* Rx fd */
10166 +DEFINE_EVENT(dpaa_eth_fd, dpa_rx_fd,
10167 +
10168 + TP_PROTO(struct net_device *netdev,
10169 + struct qman_fq *fq,
10170 + const struct qm_fd *fd),
10171 +
10172 + TP_ARGS(netdev, fq, fd)
10173 +);
10174 +
10175 +/* Tx confirmation fd */
10176 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_conf_fd,
10177 +
10178 + TP_PROTO(struct net_device *netdev,
10179 + struct qman_fq *fq,
10180 + const struct qm_fd *fd),
10181 +
10182 + TP_ARGS(netdev, fq, fd)
10183 +);
10184 +
10185 +/* If only one event of a certain type needs to be declared, use TRACE_EVENT().
10186 + * The syntax is the same as for DECLARE_EVENT_CLASS().
10187 + */
10188 +
10189 +#endif /* _DPAA_ETH_TRACE_H */
10190 +
10191 +/* This must be outside ifdef _DPAA_ETH_TRACE_H */
10192 +#undef TRACE_INCLUDE_PATH
10193 +#define TRACE_INCLUDE_PATH .
10194 +#undef TRACE_INCLUDE_FILE
10195 +#define TRACE_INCLUDE_FILE dpaa_eth_trace
10196 +#include <trace/define_trace.h>
10197 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
10198 new file mode 100644
10199 index 00000000..4b784662
10200 --- /dev/null
10201 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
10202 @@ -0,0 +1,544 @@
10203 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
10204 + *
10205 + * Redistribution and use in source and binary forms, with or without
10206 + * modification, are permitted provided that the following conditions are met:
10207 + * * Redistributions of source code must retain the above copyright
10208 + * notice, this list of conditions and the following disclaimer.
10209 + * * Redistributions in binary form must reproduce the above copyright
10210 + * notice, this list of conditions and the following disclaimer in the
10211 + * documentation and/or other materials provided with the distribution.
10212 + * * Neither the name of Freescale Semiconductor nor the
10213 + * names of its contributors may be used to endorse or promote products
10214 + * derived from this software without specific prior written permission.
10215 + *
10216 + *
10217 + * ALTERNATIVELY, this software may be distributed under the terms of the
10218 + * GNU General Public License ("GPL") as published by the Free Software
10219 + * Foundation, either version 2 of that License or (at your option) any
10220 + * later version.
10221 + *
10222 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10223 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10224 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10225 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10226 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10227 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10228 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10229 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10230 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10231 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10232 + */
10233 +
10234 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
10235 +#define pr_fmt(fmt) \
10236 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
10237 + KBUILD_BASENAME".c", __LINE__, __func__
10238 +#else
10239 +#define pr_fmt(fmt) \
10240 + KBUILD_MODNAME ": " fmt
10241 +#endif
10242 +
10243 +#include <linux/string.h>
10244 +
10245 +#include "dpaa_eth.h"
10246 +#include "mac.h" /* struct mac_device */
10247 +#include "dpaa_eth_common.h"
10248 +
10249 +static const char dpa_stats_percpu[][ETH_GSTRING_LEN] = {
10250 + "interrupts",
10251 + "rx packets",
10252 + "tx packets",
10253 + "tx recycled",
10254 + "tx confirm",
10255 + "tx S/G",
10256 + "rx S/G",
10257 + "tx error",
10258 + "rx error",
10259 + "bp count"
10260 +};
10261 +
10262 +static char dpa_stats_global[][ETH_GSTRING_LEN] = {
10263 + /* dpa rx errors */
10264 + "rx dma error",
10265 + "rx frame physical error",
10266 + "rx frame size error",
10267 + "rx header error",
10268 + "rx csum error",
10269 +
10270 + /* demultiplexing errors */
10271 + "qman cg_tdrop",
10272 + "qman wred",
10273 + "qman error cond",
10274 + "qman early window",
10275 + "qman late window",
10276 + "qman fq tdrop",
10277 + "qman fq retired",
10278 + "qman orp disabled",
10279 +
10280 + /* congestion related stats */
10281 + "congestion time (ms)",
10282 + "entered congestion",
10283 + "congested (0/1)"
10284 +};
10285 +
10286 +#define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu)
10287 +#define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global)
10288 +
10289 +static int __cold dpa_get_settings(struct net_device *net_dev,
10290 + struct ethtool_cmd *et_cmd)
10291 +{
10292 + int _errno;
10293 + struct dpa_priv_s *priv;
10294 +
10295 + priv = netdev_priv(net_dev);
10296 +
10297 + if (priv->mac_dev == NULL) {
10298 + netdev_info(net_dev, "This is a MAC-less interface\n");
10299 + return -ENODEV;
10300 + }
10301 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10302 + netdev_dbg(net_dev, "phy device not initialized\n");
10303 + return 0;
10304 + }
10305 +
10306 + _errno = phy_ethtool_gset(priv->mac_dev->phy_dev, et_cmd);
10307 + if (unlikely(_errno < 0))
10308 + netdev_err(net_dev, "phy_ethtool_gset() = %d\n", _errno);
10309 +
10310 + return _errno;
10311 +}
10312 +
10313 +static int __cold dpa_set_settings(struct net_device *net_dev,
10314 + struct ethtool_cmd *et_cmd)
10315 +{
10316 + int _errno;
10317 + struct dpa_priv_s *priv;
10318 +
10319 + priv = netdev_priv(net_dev);
10320 +
10321 + if (priv->mac_dev == NULL) {
10322 + netdev_info(net_dev, "This is a MAC-less interface\n");
10323 + return -ENODEV;
10324 + }
10325 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10326 + netdev_err(net_dev, "phy device not initialized\n");
10327 + return -ENODEV;
10328 + }
10329 +
10330 + _errno = phy_ethtool_sset(priv->mac_dev->phy_dev, et_cmd);
10331 + if (unlikely(_errno < 0))
10332 + netdev_err(net_dev, "phy_ethtool_sset() = %d\n", _errno);
10333 +
10334 + return _errno;
10335 +}
10336 +
10337 +static void __cold dpa_get_drvinfo(struct net_device *net_dev,
10338 + struct ethtool_drvinfo *drvinfo)
10339 +{
10340 + int _errno;
10341 +
10342 + strncpy(drvinfo->driver, KBUILD_MODNAME,
10343 + sizeof(drvinfo->driver) - 1)[sizeof(drvinfo->driver)-1] = 0;
10344 + _errno = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
10345 + "%X", 0);
10346 +
10347 + if (unlikely(_errno >= sizeof(drvinfo->fw_version))) {
10348 + /* Truncated output */
10349 + netdev_notice(net_dev, "snprintf() = %d\n", _errno);
10350 + } else if (unlikely(_errno < 0)) {
10351 + netdev_warn(net_dev, "snprintf() = %d\n", _errno);
10352 + memset(drvinfo->fw_version, 0, sizeof(drvinfo->fw_version));
10353 + }
10354 + strncpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
10355 + sizeof(drvinfo->bus_info)-1)[sizeof(drvinfo->bus_info)-1] = 0;
10356 +}
10357 +
10358 +static uint32_t __cold dpa_get_msglevel(struct net_device *net_dev)
10359 +{
10360 + return ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable;
10361 +}
10362 +
10363 +static void __cold dpa_set_msglevel(struct net_device *net_dev,
10364 + uint32_t msg_enable)
10365 +{
10366 + ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable = msg_enable;
10367 +}
10368 +
10369 +static int __cold dpa_nway_reset(struct net_device *net_dev)
10370 +{
10371 + int _errno;
10372 + struct dpa_priv_s *priv;
10373 +
10374 + priv = netdev_priv(net_dev);
10375 +
10376 + if (priv->mac_dev == NULL) {
10377 + netdev_info(net_dev, "This is a MAC-less interface\n");
10378 + return -ENODEV;
10379 + }
10380 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10381 + netdev_err(net_dev, "phy device not initialized\n");
10382 + return -ENODEV;
10383 + }
10384 +
10385 + _errno = 0;
10386 + if (priv->mac_dev->phy_dev->autoneg) {
10387 + _errno = phy_start_aneg(priv->mac_dev->phy_dev);
10388 + if (unlikely(_errno < 0))
10389 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10390 + _errno);
10391 + }
10392 +
10393 + return _errno;
10394 +}
10395 +
10396 +static void __cold dpa_get_pauseparam(struct net_device *net_dev,
10397 + struct ethtool_pauseparam *epause)
10398 +{
10399 + struct dpa_priv_s *priv;
10400 + struct mac_device *mac_dev;
10401 + struct phy_device *phy_dev;
10402 +
10403 + priv = netdev_priv(net_dev);
10404 + mac_dev = priv->mac_dev;
10405 +
10406 + if (mac_dev == NULL) {
10407 + netdev_info(net_dev, "This is a MAC-less interface\n");
10408 + return;
10409 + }
10410 +
10411 + phy_dev = mac_dev->phy_dev;
10412 + if (unlikely(phy_dev == NULL)) {
10413 + netdev_err(net_dev, "phy device not initialized\n");
10414 + return;
10415 + }
10416 +
10417 + epause->autoneg = mac_dev->autoneg_pause;
10418 + epause->rx_pause = mac_dev->rx_pause_active;
10419 + epause->tx_pause = mac_dev->tx_pause_active;
10420 +}
10421 +
10422 +static int __cold dpa_set_pauseparam(struct net_device *net_dev,
10423 + struct ethtool_pauseparam *epause)
10424 +{
10425 + struct dpa_priv_s *priv;
10426 + struct mac_device *mac_dev;
10427 + struct phy_device *phy_dev;
10428 + int _errno;
10429 + u32 newadv, oldadv;
10430 + bool rx_pause, tx_pause;
10431 +
10432 + priv = netdev_priv(net_dev);
10433 + mac_dev = priv->mac_dev;
10434 +
10435 + if (mac_dev == NULL) {
10436 + netdev_info(net_dev, "This is a MAC-less interface\n");
10437 + return -ENODEV;
10438 + }
10439 +
10440 + phy_dev = mac_dev->phy_dev;
10441 + if (unlikely(phy_dev == NULL)) {
10442 + netdev_err(net_dev, "phy device not initialized\n");
10443 + return -ENODEV;
10444 + }
10445 +
10446 + if (!(phy_dev->supported & SUPPORTED_Pause) ||
10447 + (!(phy_dev->supported & SUPPORTED_Asym_Pause) &&
10448 + (epause->rx_pause != epause->tx_pause)))
10449 + return -EINVAL;
10450 +
10451 + /* The MAC should know how to handle PAUSE frame autonegotiation before
10452 + * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
10453 + * settings.
10454 + */
10455 + mac_dev->autoneg_pause = !!epause->autoneg;
10456 + mac_dev->rx_pause_req = !!epause->rx_pause;
10457 + mac_dev->tx_pause_req = !!epause->tx_pause;
10458 +
10459 + /* Determine the sym/asym advertised PAUSE capabilities from the desired
10460 + * rx/tx pause settings.
10461 + */
10462 + newadv = 0;
10463 + if (epause->rx_pause)
10464 + newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause;
10465 + if (epause->tx_pause)
10466 + newadv |= ADVERTISED_Asym_Pause;
10467 +
10468 + oldadv = phy_dev->advertising &
10469 + (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
10470 +
10471 + /* If there are differences between the old and the new advertised
10472 + * values, restart PHY autonegotiation and advertise the new values.
10473 + */
10474 + if (oldadv != newadv) {
10475 + phy_dev->advertising &= ~(ADVERTISED_Pause
10476 + | ADVERTISED_Asym_Pause);
10477 + phy_dev->advertising |= newadv;
10478 + if (phy_dev->autoneg) {
10479 + _errno = phy_start_aneg(phy_dev);
10480 + if (unlikely(_errno < 0))
10481 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10482 + _errno);
10483 + }
10484 + }
10485 +
10486 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
10487 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
10488 + if (unlikely(_errno < 0))
10489 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
10490 +
10491 + return _errno;
10492 +}
10493 +
10494 +#ifdef CONFIG_PM
10495 +static void dpa_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10496 +{
10497 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10498 +
10499 + wol->supported = 0;
10500 + wol->wolopts = 0;
10501 +
10502 + if (!priv->wol || !device_can_wakeup(net_dev->dev.parent))
10503 + return;
10504 +
10505 + if (priv->wol & DPAA_WOL_MAGIC) {
10506 + wol->supported = WAKE_MAGIC;
10507 + wol->wolopts = WAKE_MAGIC;
10508 + }
10509 +}
10510 +
10511 +static int dpa_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10512 +{
10513 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10514 +
10515 + if (priv->mac_dev == NULL) {
10516 + netdev_info(net_dev, "This is a MAC-less interface\n");
10517 + return -ENODEV;
10518 + }
10519 +
10520 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10521 + netdev_dbg(net_dev, "phy device not initialized\n");
10522 + return -ENODEV;
10523 + }
10524 +
10525 + if (!device_can_wakeup(net_dev->dev.parent) ||
10526 + (wol->wolopts & ~WAKE_MAGIC))
10527 + return -EOPNOTSUPP;
10528 +
10529 + priv->wol = 0;
10530 +
10531 + if (wol->wolopts & WAKE_MAGIC) {
10532 + priv->wol = DPAA_WOL_MAGIC;
10533 + device_set_wakeup_enable(net_dev->dev.parent, 1);
10534 + } else {
10535 + device_set_wakeup_enable(net_dev->dev.parent, 0);
10536 + }
10537 +
10538 + return 0;
10539 +}
10540 +#endif
10541 +
10542 +static int dpa_get_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10543 +{
10544 + struct dpa_priv_s *priv;
10545 +
10546 + priv = netdev_priv(net_dev);
10547 + if (priv->mac_dev == NULL) {
10548 + netdev_info(net_dev, "This is a MAC-less interface\n");
10549 + return -ENODEV;
10550 + }
10551 +
10552 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10553 + netdev_err(net_dev, "phy device not initialized\n");
10554 + return -ENODEV;
10555 + }
10556 +
10557 + return phy_ethtool_get_eee(priv->mac_dev->phy_dev, et_eee);
10558 +}
10559 +
10560 +static int dpa_set_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10561 +{
10562 + struct dpa_priv_s *priv;
10563 +
10564 + priv = netdev_priv(net_dev);
10565 + if (priv->mac_dev == NULL) {
10566 + netdev_info(net_dev, "This is a MAC-less interface\n");
10567 + return -ENODEV;
10568 + }
10569 +
10570 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10571 + netdev_err(net_dev, "phy device not initialized\n");
10572 + return -ENODEV;
10573 + }
10574 +
10575 + return phy_ethtool_set_eee(priv->mac_dev->phy_dev, et_eee);
10576 +}
10577 +
10578 +static int dpa_get_sset_count(struct net_device *net_dev, int type)
10579 +{
10580 + unsigned int total_stats, num_stats;
10581 +
10582 + num_stats = num_online_cpus() + 1;
10583 + total_stats = num_stats * DPA_STATS_PERCPU_LEN + DPA_STATS_GLOBAL_LEN;
10584 +
10585 + switch (type) {
10586 + case ETH_SS_STATS:
10587 + return total_stats;
10588 + default:
10589 + return -EOPNOTSUPP;
10590 + }
10591 +}
10592 +
10593 +static void copy_stats(struct dpa_percpu_priv_s *percpu_priv, int num_cpus,
10594 + int crr_cpu, u64 bp_count, u64 *data)
10595 +{
10596 + int num_stat_values = num_cpus + 1;
10597 + int crr_stat = 0;
10598 +
10599 + /* update current CPU's stats and also add them to the total values */
10600 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->in_interrupt;
10601 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->in_interrupt;
10602 +
10603 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_packets;
10604 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_packets;
10605 +
10606 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_packets;
10607 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_packets;
10608 +
10609 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_returned;
10610 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_returned;
10611 +
10612 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_confirm;
10613 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_confirm;
10614 +
10615 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_frag_skbuffs;
10616 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_frag_skbuffs;
10617 +
10618 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->rx_sg;
10619 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->rx_sg;
10620 +
10621 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_errors;
10622 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_errors;
10623 +
10624 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_errors;
10625 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_errors;
10626 +
10627 + data[crr_stat * num_stat_values + crr_cpu] = bp_count;
10628 + data[crr_stat++ * num_stat_values + num_cpus] += bp_count;
10629 +}
10630 +
10631 +static void dpa_get_ethtool_stats(struct net_device *net_dev,
10632 + struct ethtool_stats *stats, u64 *data)
10633 +{
10634 + u64 bp_count, cg_time, cg_num, cg_status;
10635 + struct dpa_percpu_priv_s *percpu_priv;
10636 + struct qm_mcr_querycgr query_cgr;
10637 + struct dpa_rx_errors rx_errors;
10638 + struct dpa_ern_cnt ern_cnt;
10639 + struct dpa_priv_s *priv;
10640 + unsigned int num_cpus, offset;
10641 + struct dpa_bp *dpa_bp;
10642 + int total_stats, i;
10643 +
10644 + total_stats = dpa_get_sset_count(net_dev, ETH_SS_STATS);
10645 + priv = netdev_priv(net_dev);
10646 + dpa_bp = priv->dpa_bp;
10647 + num_cpus = num_online_cpus();
10648 + bp_count = 0;
10649 +
10650 + memset(&rx_errors, 0, sizeof(struct dpa_rx_errors));
10651 + memset(&ern_cnt, 0, sizeof(struct dpa_ern_cnt));
10652 + memset(data, 0, total_stats * sizeof(u64));
10653 +
10654 + for_each_online_cpu(i) {
10655 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
10656 +
10657 + if (dpa_bp->percpu_count)
10658 + bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i));
10659 +
10660 + rx_errors.dme += percpu_priv->rx_errors.dme;
10661 + rx_errors.fpe += percpu_priv->rx_errors.fpe;
10662 + rx_errors.fse += percpu_priv->rx_errors.fse;
10663 + rx_errors.phe += percpu_priv->rx_errors.phe;
10664 + rx_errors.cse += percpu_priv->rx_errors.cse;
10665 +
10666 + ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop;
10667 + ern_cnt.wred += percpu_priv->ern_cnt.wred;
10668 + ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond;
10669 + ern_cnt.early_window += percpu_priv->ern_cnt.early_window;
10670 + ern_cnt.late_window += percpu_priv->ern_cnt.late_window;
10671 + ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop;
10672 + ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired;
10673 + ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero;
10674 +
10675 + copy_stats(percpu_priv, num_cpus, i, bp_count, data);
10676 + }
10677 +
10678 + offset = (num_cpus + 1) * DPA_STATS_PERCPU_LEN;
10679 + memcpy(data + offset, &rx_errors, sizeof(struct dpa_rx_errors));
10680 +
10681 + offset += sizeof(struct dpa_rx_errors) / sizeof(u64);
10682 + memcpy(data + offset, &ern_cnt, sizeof(struct dpa_ern_cnt));
10683 +
10684 + /* gather congestion related counters */
10685 + cg_num = 0;
10686 + cg_status = 0;
10687 + cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies);
10688 + if (qman_query_cgr(&priv->cgr_data.cgr, &query_cgr) == 0) {
10689 + cg_num = priv->cgr_data.cgr_congested_count;
10690 + cg_status = query_cgr.cgr.cs;
10691 +
10692 + /* reset congestion stats (like QMan API does */
10693 + priv->cgr_data.congested_jiffies = 0;
10694 + priv->cgr_data.cgr_congested_count = 0;
10695 + }
10696 +
10697 + offset += sizeof(struct dpa_ern_cnt) / sizeof(u64);
10698 + data[offset++] = cg_time;
10699 + data[offset++] = cg_num;
10700 + data[offset++] = cg_status;
10701 +}
10702 +
10703 +static void dpa_get_strings(struct net_device *net_dev, u32 stringset, u8 *data)
10704 +{
10705 + unsigned int i, j, num_cpus, size;
10706 + char stat_string_cpu[ETH_GSTRING_LEN];
10707 + u8 *strings;
10708 +
10709 + strings = data;
10710 + num_cpus = num_online_cpus();
10711 + size = DPA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN;
10712 +
10713 + for (i = 0; i < DPA_STATS_PERCPU_LEN; i++) {
10714 + for (j = 0; j < num_cpus; j++) {
10715 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", dpa_stats_percpu[i], j);
10716 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10717 + strings += ETH_GSTRING_LEN;
10718 + }
10719 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", dpa_stats_percpu[i]);
10720 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10721 + strings += ETH_GSTRING_LEN;
10722 + }
10723 + memcpy(strings, dpa_stats_global, size);
10724 +}
10725 +
10726 +const struct ethtool_ops dpa_ethtool_ops = {
10727 + .get_settings = dpa_get_settings,
10728 + .set_settings = dpa_set_settings,
10729 + .get_drvinfo = dpa_get_drvinfo,
10730 + .get_msglevel = dpa_get_msglevel,
10731 + .set_msglevel = dpa_set_msglevel,
10732 + .nway_reset = dpa_nway_reset,
10733 + .get_pauseparam = dpa_get_pauseparam,
10734 + .set_pauseparam = dpa_set_pauseparam,
10735 + .self_test = NULL, /* TODO invoke the cold-boot unit-test? */
10736 + .get_link = ethtool_op_get_link,
10737 + .get_eee = dpa_get_eee,
10738 + .set_eee = dpa_set_eee,
10739 + .get_sset_count = dpa_get_sset_count,
10740 + .get_ethtool_stats = dpa_get_ethtool_stats,
10741 + .get_strings = dpa_get_strings,
10742 +#ifdef CONFIG_PM
10743 + .get_wol = dpa_get_wol,
10744 + .set_wol = dpa_set_wol,
10745 +#endif
10746 +};
10747 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
10748 new file mode 100644
10749 index 00000000..f54a3d67
10750 --- /dev/null
10751 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
10752 @@ -0,0 +1,291 @@
10753 +/*
10754 + * DPAA Ethernet Driver -- PTP 1588 clock using the dTSEC
10755 + *
10756 + * Author: Yangbo Lu <yangbo.lu@freescale.com>
10757 + *
10758 + * Copyright 2014 Freescale Semiconductor, Inc.
10759 + *
10760 + * This program is free software; you can redistribute it and/or modify it
10761 + * under the terms of the GNU General Public License as published by the
10762 + * Free Software Foundation; either version 2 of the License, or (at your
10763 + * option) any later version.
10764 +*/
10765 +
10766 +#include <linux/device.h>
10767 +#include <linux/hrtimer.h>
10768 +#include <linux/init.h>
10769 +#include <linux/interrupt.h>
10770 +#include <linux/kernel.h>
10771 +#include <linux/module.h>
10772 +#include <linux/of.h>
10773 +#include <linux/of_platform.h>
10774 +#include <linux/timex.h>
10775 +#include <linux/io.h>
10776 +
10777 +#include <linux/ptp_clock_kernel.h>
10778 +
10779 +#include "dpaa_eth.h"
10780 +#include "mac.h"
10781 +
10782 +static struct mac_device *mac_dev;
10783 +static u32 freqCompensation;
10784 +
10785 +/* Bit definitions for the TMR_CTRL register */
10786 +#define ALM1P (1<<31) /* Alarm1 output polarity */
10787 +#define ALM2P (1<<30) /* Alarm2 output polarity */
10788 +#define FS (1<<28) /* FIPER start indication */
10789 +#define PP1L (1<<27) /* Fiper1 pulse loopback mode enabled. */
10790 +#define PP2L (1<<26) /* Fiper2 pulse loopback mode enabled. */
10791 +#define TCLK_PERIOD_SHIFT (16) /* 1588 timer reference clock period. */
10792 +#define TCLK_PERIOD_MASK (0x3ff)
10793 +#define RTPE (1<<15) /* Record Tx Timestamp to PAL Enable. */
10794 +#define FRD (1<<14) /* FIPER Realignment Disable */
10795 +#define ESFDP (1<<11) /* External Tx/Rx SFD Polarity. */
10796 +#define ESFDE (1<<10) /* External Tx/Rx SFD Enable. */
10797 +#define ETEP2 (1<<9) /* External trigger 2 edge polarity */
10798 +#define ETEP1 (1<<8) /* External trigger 1 edge polarity */
10799 +#define COPH (1<<7) /* Generated clock output phase. */
10800 +#define CIPH (1<<6) /* External oscillator input clock phase */
10801 +#define TMSR (1<<5) /* Timer soft reset. */
10802 +#define BYP (1<<3) /* Bypass drift compensated clock */
10803 +#define TE (1<<2) /* 1588 timer enable. */
10804 +#define CKSEL_SHIFT (0) /* 1588 Timer reference clock source */
10805 +#define CKSEL_MASK (0x3)
10806 +
10807 +/* Bit definitions for the TMR_TEVENT register */
10808 +#define ETS2 (1<<25) /* External trigger 2 timestamp sampled */
10809 +#define ETS1 (1<<24) /* External trigger 1 timestamp sampled */
10810 +#define ALM2 (1<<17) /* Current time = alarm time register 2 */
10811 +#define ALM1 (1<<16) /* Current time = alarm time register 1 */
10812 +#define PP1 (1<<7) /* periodic pulse generated on FIPER1 */
10813 +#define PP2 (1<<6) /* periodic pulse generated on FIPER2 */
10814 +#define PP3 (1<<5) /* periodic pulse generated on FIPER3 */
10815 +
10816 +/* Bit definitions for the TMR_TEMASK register */
10817 +#define ETS2EN (1<<25) /* External trigger 2 timestamp enable */
10818 +#define ETS1EN (1<<24) /* External trigger 1 timestamp enable */
10819 +#define ALM2EN (1<<17) /* Timer ALM2 event enable */
10820 +#define ALM1EN (1<<16) /* Timer ALM1 event enable */
10821 +#define PP1EN (1<<7) /* Periodic pulse event 1 enable */
10822 +#define PP2EN (1<<6) /* Periodic pulse event 2 enable */
10823 +
10824 +/* Bit definitions for the TMR_PEVENT register */
10825 +#define TXP2 (1<<9) /* PTP transmitted timestamp im TXTS2 */
10826 +#define TXP1 (1<<8) /* PTP transmitted timestamp in TXTS1 */
10827 +#define RXP (1<<0) /* PTP frame has been received */
10828 +
10829 +/* Bit definitions for the TMR_PEMASK register */
10830 +#define TXP2EN (1<<9) /* Transmit PTP packet event 2 enable */
10831 +#define TXP1EN (1<<8) /* Transmit PTP packet event 1 enable */
10832 +#define RXPEN (1<<0) /* Receive PTP packet event enable */
10833 +
10834 +/* Bit definitions for the TMR_STAT register */
10835 +#define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */
10836 +#define STAT_VEC_MASK (0x3f)
10837 +
10838 +/* Bit definitions for the TMR_PRSC register */
10839 +#define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */
10840 +#define PRSC_OCK_MASK (0xffff)
10841 +
10842 +
10843 +#define N_EXT_TS 2
10844 +
10845 +static void set_alarm(void)
10846 +{
10847 + u64 ns;
10848 +
10849 + if (mac_dev->fm_rtc_get_cnt)
10850 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10851 + ns += 1500000000ULL;
10852 + ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
10853 + ns -= DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10854 + if (mac_dev->fm_rtc_set_alarm)
10855 + mac_dev->fm_rtc_set_alarm(mac_dev->fm_dev, 0, ns);
10856 +}
10857 +
10858 +static void set_fipers(void)
10859 +{
10860 + u64 fiper;
10861 +
10862 + if (mac_dev->fm_rtc_disable)
10863 + mac_dev->fm_rtc_disable(mac_dev->fm_dev);
10864 +
10865 + set_alarm();
10866 + fiper = 1000000000ULL - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10867 + if (mac_dev->fm_rtc_set_fiper)
10868 + mac_dev->fm_rtc_set_fiper(mac_dev->fm_dev, 0, fiper);
10869 +
10870 + if (mac_dev->fm_rtc_enable)
10871 + mac_dev->fm_rtc_enable(mac_dev->fm_dev);
10872 +}
10873 +
10874 +/* PTP clock operations */
10875 +
10876 +static int ptp_dpa_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
10877 +{
10878 + u64 adj;
10879 + u32 diff, tmr_add;
10880 + int neg_adj = 0;
10881 +
10882 + if (ppb < 0) {
10883 + neg_adj = 1;
10884 + ppb = -ppb;
10885 + }
10886 +
10887 + tmr_add = freqCompensation;
10888 + adj = tmr_add;
10889 + adj *= ppb;
10890 + diff = div_u64(adj, 1000000000ULL);
10891 +
10892 + tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
10893 +
10894 + if (mac_dev->fm_rtc_set_drift)
10895 + mac_dev->fm_rtc_set_drift(mac_dev->fm_dev, tmr_add);
10896 +
10897 + return 0;
10898 +}
10899 +
10900 +static int ptp_dpa_adjtime(struct ptp_clock_info *ptp, s64 delta)
10901 +{
10902 + s64 now;
10903 +
10904 + if (mac_dev->fm_rtc_get_cnt)
10905 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &now);
10906 +
10907 + now += delta;
10908 +
10909 + if (mac_dev->fm_rtc_set_cnt)
10910 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, now);
10911 + set_fipers();
10912 +
10913 + return 0;
10914 +}
10915 +
10916 +static int ptp_dpa_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
10917 +{
10918 + u64 ns;
10919 + u32 remainder;
10920 +
10921 + if (mac_dev->fm_rtc_get_cnt)
10922 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10923 +
10924 + ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
10925 + ts->tv_nsec = remainder;
10926 + return 0;
10927 +}
10928 +
10929 +static int ptp_dpa_settime(struct ptp_clock_info *ptp,
10930 + const struct timespec64 *ts)
10931 +{
10932 + u64 ns;
10933 +
10934 + ns = ts->tv_sec * 1000000000ULL;
10935 + ns += ts->tv_nsec;
10936 +
10937 + if (mac_dev->fm_rtc_set_cnt)
10938 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, ns);
10939 + set_fipers();
10940 + return 0;
10941 +}
10942 +
10943 +static int ptp_dpa_enable(struct ptp_clock_info *ptp,
10944 + struct ptp_clock_request *rq, int on)
10945 +{
10946 + u32 bit;
10947 +
10948 + switch (rq->type) {
10949 + case PTP_CLK_REQ_EXTTS:
10950 + switch (rq->extts.index) {
10951 + case 0:
10952 + bit = ETS1EN;
10953 + break;
10954 + case 1:
10955 + bit = ETS2EN;
10956 + break;
10957 + default:
10958 + return -EINVAL;
10959 + }
10960 + if (on) {
10961 + if (mac_dev->fm_rtc_enable_interrupt)
10962 + mac_dev->fm_rtc_enable_interrupt(
10963 + mac_dev->fm_dev, bit);
10964 + } else {
10965 + if (mac_dev->fm_rtc_disable_interrupt)
10966 + mac_dev->fm_rtc_disable_interrupt(
10967 + mac_dev->fm_dev, bit);
10968 + }
10969 + return 0;
10970 +
10971 + case PTP_CLK_REQ_PPS:
10972 + if (on) {
10973 + if (mac_dev->fm_rtc_enable_interrupt)
10974 + mac_dev->fm_rtc_enable_interrupt(
10975 + mac_dev->fm_dev, PP1EN);
10976 + } else {
10977 + if (mac_dev->fm_rtc_disable_interrupt)
10978 + mac_dev->fm_rtc_disable_interrupt(
10979 + mac_dev->fm_dev, PP1EN);
10980 + }
10981 + return 0;
10982 +
10983 + default:
10984 + break;
10985 + }
10986 +
10987 + return -EOPNOTSUPP;
10988 +}
10989 +
10990 +static struct ptp_clock_info ptp_dpa_caps = {
10991 + .owner = THIS_MODULE,
10992 + .name = "dpaa clock",
10993 + .max_adj = 512000,
10994 + .n_alarm = 0,
10995 + .n_ext_ts = N_EXT_TS,
10996 + .n_per_out = 0,
10997 + .pps = 1,
10998 + .adjfreq = ptp_dpa_adjfreq,
10999 + .adjtime = ptp_dpa_adjtime,
11000 + .gettime64 = ptp_dpa_gettime,
11001 + .settime64 = ptp_dpa_settime,
11002 + .enable = ptp_dpa_enable,
11003 +};
11004 +
11005 +static int __init __cold dpa_ptp_load(void)
11006 +{
11007 + struct device *ptp_dev;
11008 + struct timespec64 now;
11009 + struct ptp_clock *clock = ptp_priv.clock;
11010 + int dpa_phc_index;
11011 + int err;
11012 +
11013 + if (!(ptp_priv.of_dev && ptp_priv.mac_dev))
11014 + return -ENODEV;
11015 +
11016 + ptp_dev = &ptp_priv.of_dev->dev;
11017 + mac_dev = ptp_priv.mac_dev;
11018 +
11019 + if (mac_dev->fm_rtc_get_drift)
11020 + mac_dev->fm_rtc_get_drift(mac_dev->fm_dev, &freqCompensation);
11021 +
11022 + getnstimeofday64(&now);
11023 + ptp_dpa_settime(&ptp_dpa_caps, &now);
11024 +
11025 + clock = ptp_clock_register(&ptp_dpa_caps, ptp_dev);
11026 + if (IS_ERR(clock)) {
11027 + err = PTR_ERR(clock);
11028 + return err;
11029 + }
11030 + dpa_phc_index = ptp_clock_index(clock);
11031 + return 0;
11032 +}
11033 +module_init(dpa_ptp_load);
11034 +
11035 +static void __exit __cold dpa_ptp_unload(void)
11036 +{
11037 + struct ptp_clock *clock = ptp_priv.clock;
11038 +
11039 + if (mac_dev->fm_rtc_disable_interrupt)
11040 + mac_dev->fm_rtc_disable_interrupt(mac_dev->fm_dev, 0xffffffff);
11041 + ptp_clock_unregister(clock);
11042 +}
11043 +module_exit(dpa_ptp_unload);
11044 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
11045 new file mode 100644
11046 index 00000000..2c5652d9
11047 --- /dev/null
11048 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
11049 @@ -0,0 +1,907 @@
11050 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11051 + *
11052 + * Redistribution and use in source and binary forms, with or without
11053 + * modification, are permitted provided that the following conditions are met:
11054 + * * Redistributions of source code must retain the above copyright
11055 + * notice, this list of conditions and the following disclaimer.
11056 + * * Redistributions in binary form must reproduce the above copyright
11057 + * notice, this list of conditions and the following disclaimer in the
11058 + * documentation and/or other materials provided with the distribution.
11059 + * * Neither the name of Freescale Semiconductor nor the
11060 + * names of its contributors may be used to endorse or promote products
11061 + * derived from this software without specific prior written permission.
11062 + *
11063 + *
11064 + * ALTERNATIVELY, this software may be distributed under the terms of the
11065 + * GNU General Public License ("GPL") as published by the Free Software
11066 + * Foundation, either version 2 of that License or (at your option) any
11067 + * later version.
11068 + *
11069 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11070 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11071 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11072 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11073 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11074 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11075 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11076 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11077 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11078 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11079 + */
11080 +
11081 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11082 +#define pr_fmt(fmt) \
11083 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11084 + KBUILD_BASENAME".c", __LINE__, __func__
11085 +#else
11086 +#define pr_fmt(fmt) \
11087 + KBUILD_MODNAME ": " fmt
11088 +#endif
11089 +
11090 +#include <linux/init.h>
11091 +#include <linux/module.h>
11092 +#include <linux/io.h>
11093 +#include <linux/of_platform.h>
11094 +#include <linux/of_mdio.h>
11095 +#include <linux/phy.h>
11096 +#include <linux/netdevice.h>
11097 +
11098 +#include "dpaa_eth.h"
11099 +#include "mac.h"
11100 +#include "lnxwrp_fsl_fman.h"
11101 +
11102 +#include "error_ext.h" /* GET_ERROR_TYPE, E_OK */
11103 +
11104 +#include "fsl_fman_dtsec.h"
11105 +#include "fsl_fman_tgec.h"
11106 +#include "fsl_fman_memac.h"
11107 +#include "../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h"
11108 +
11109 +#define MAC_DESCRIPTION "FSL FMan MAC API based driver"
11110 +
11111 +MODULE_LICENSE("Dual BSD/GPL");
11112 +
11113 +MODULE_AUTHOR("Emil Medve <Emilian.Medve@Freescale.com>");
11114 +
11115 +MODULE_DESCRIPTION(MAC_DESCRIPTION);
11116 +
11117 +struct mac_priv_s {
11118 + struct fm_mac_dev *fm_mac;
11119 +};
11120 +
11121 +const char *mac_driver_description __initconst = MAC_DESCRIPTION;
11122 +const size_t mac_sizeof_priv[] = {
11123 + [DTSEC] = sizeof(struct mac_priv_s),
11124 + [XGMAC] = sizeof(struct mac_priv_s),
11125 + [MEMAC] = sizeof(struct mac_priv_s)
11126 +};
11127 +
11128 +static const enet_mode_t _100[] = {
11129 + [PHY_INTERFACE_MODE_MII] = e_ENET_MODE_MII_100,
11130 + [PHY_INTERFACE_MODE_RMII] = e_ENET_MODE_RMII_100
11131 +};
11132 +
11133 +static const enet_mode_t _1000[] = {
11134 + [PHY_INTERFACE_MODE_GMII] = e_ENET_MODE_GMII_1000,
11135 + [PHY_INTERFACE_MODE_SGMII] = e_ENET_MODE_SGMII_1000,
11136 + [PHY_INTERFACE_MODE_QSGMII] = e_ENET_MODE_QSGMII_1000,
11137 + [PHY_INTERFACE_MODE_TBI] = e_ENET_MODE_TBI_1000,
11138 + [PHY_INTERFACE_MODE_RGMII] = e_ENET_MODE_RGMII_1000,
11139 + [PHY_INTERFACE_MODE_RGMII_ID] = e_ENET_MODE_RGMII_1000,
11140 + [PHY_INTERFACE_MODE_RGMII_RXID] = e_ENET_MODE_RGMII_1000,
11141 + [PHY_INTERFACE_MODE_RGMII_TXID] = e_ENET_MODE_RGMII_1000,
11142 + [PHY_INTERFACE_MODE_RTBI] = e_ENET_MODE_RTBI_1000
11143 +};
11144 +
11145 +static enet_mode_t __cold __attribute__((nonnull))
11146 +macdev2enetinterface(const struct mac_device *mac_dev)
11147 +{
11148 + switch (mac_dev->max_speed) {
11149 + case SPEED_100:
11150 + return _100[mac_dev->phy_if];
11151 + case SPEED_1000:
11152 + return _1000[mac_dev->phy_if];
11153 + case SPEED_2500:
11154 + return e_ENET_MODE_SGMII_2500;
11155 + case SPEED_10000:
11156 + return e_ENET_MODE_XGMII_10000;
11157 + default:
11158 + return e_ENET_MODE_MII_100;
11159 + }
11160 +}
11161 +
11162 +static void mac_exception(handle_t _mac_dev, e_FmMacExceptions exception)
11163 +{
11164 + struct mac_device *mac_dev;
11165 +
11166 + mac_dev = (struct mac_device *)_mac_dev;
11167 +
11168 + if (e_FM_MAC_EX_10G_RX_FIFO_OVFL == exception) {
11169 + /* don't flag RX FIFO after the first */
11170 + fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11171 + e_FM_MAC_EX_10G_RX_FIFO_OVFL, false);
11172 + dev_err(mac_dev->dev, "10G MAC got RX FIFO Error = %x\n",
11173 + exception);
11174 + }
11175 +
11176 + dev_dbg(mac_dev->dev, "%s:%s() -> %d\n", KBUILD_BASENAME".c", __func__,
11177 + exception);
11178 +}
11179 +
11180 +static int __cold init(struct mac_device *mac_dev)
11181 +{
11182 + int _errno;
11183 + struct mac_priv_s *priv;
11184 + t_FmMacParams param;
11185 + uint32_t version;
11186 +
11187 + priv = macdev_priv(mac_dev);
11188 +
11189 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11190 + mac_dev->dev, mac_dev->res->start, 0x2000);
11191 + param.enetMode = macdev2enetinterface(mac_dev);
11192 + memcpy(&param.addr, mac_dev->addr, min(sizeof(param.addr),
11193 + sizeof(mac_dev->addr)));
11194 + param.macId = mac_dev->cell_index;
11195 + param.h_Fm = (handle_t)mac_dev->fm;
11196 + param.mdioIrq = NO_IRQ;
11197 + param.f_Exception = mac_exception;
11198 + param.f_Event = mac_exception;
11199 + param.h_App = mac_dev;
11200 +
11201 + priv->fm_mac = fm_mac_config(&param);
11202 + if (unlikely(priv->fm_mac == NULL)) {
11203 + _errno = -EINVAL;
11204 + goto _return;
11205 + }
11206 +
11207 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11208 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11209 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11210 +
11211 + _errno = fm_mac_config_max_frame_length(priv->fm_mac,
11212 + fm_get_max_frm());
11213 + if (unlikely(_errno < 0))
11214 + goto _return_fm_mac_free;
11215 +
11216 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11217 + /* 10G always works with pad and CRC */
11218 + _errno = fm_mac_config_pad_and_crc(priv->fm_mac, true);
11219 + if (unlikely(_errno < 0))
11220 + goto _return_fm_mac_free;
11221 +
11222 + _errno = fm_mac_config_half_duplex(priv->fm_mac,
11223 + mac_dev->half_duplex);
11224 + if (unlikely(_errno < 0))
11225 + goto _return_fm_mac_free;
11226 + } else {
11227 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11228 + if (unlikely(_errno < 0))
11229 + goto _return_fm_mac_free;
11230 + }
11231 +
11232 + _errno = fm_mac_init(priv->fm_mac);
11233 + if (unlikely(_errno < 0))
11234 + goto _return_fm_mac_free;
11235 +
11236 +#ifndef CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN
11237 + /* For 1G MAC, disable by default the MIB counters overflow interrupt */
11238 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11239 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11240 + e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, FALSE);
11241 + if (unlikely(_errno < 0))
11242 + goto _return_fm_mac_free;
11243 + }
11244 +#endif /* !CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN */
11245 +
11246 + /* For 10G MAC, disable Tx ECC exception */
11247 + if (macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) {
11248 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11249 + e_FM_MAC_EX_10G_1TX_ECC_ER, FALSE);
11250 + if (unlikely(_errno < 0))
11251 + goto _return_fm_mac_free;
11252 + }
11253 +
11254 + _errno = fm_mac_get_version(priv->fm_mac, &version);
11255 + if (unlikely(_errno < 0))
11256 + goto _return_fm_mac_free;
11257 +
11258 + dev_info(mac_dev->dev, "FMan %s version: 0x%08x\n",
11259 + ((macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11260 + "dTSEC" : "XGEC"), version);
11261 +
11262 + goto _return;
11263 +
11264 +
11265 +_return_fm_mac_free:
11266 + fm_mac_free(mac_dev->get_mac_handle(mac_dev));
11267 +
11268 +_return:
11269 + return _errno;
11270 +}
11271 +
11272 +static int __cold memac_init(struct mac_device *mac_dev)
11273 +{
11274 + int _errno;
11275 + struct mac_priv_s *priv;
11276 + t_FmMacParams param;
11277 +
11278 + priv = macdev_priv(mac_dev);
11279 +
11280 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11281 + mac_dev->dev, mac_dev->res->start, 0x2000);
11282 + param.enetMode = macdev2enetinterface(mac_dev);
11283 + memcpy(&param.addr, mac_dev->addr, sizeof(mac_dev->addr));
11284 + param.macId = mac_dev->cell_index;
11285 + param.h_Fm = (handle_t)mac_dev->fm;
11286 + param.mdioIrq = NO_IRQ;
11287 + param.f_Exception = mac_exception;
11288 + param.f_Event = mac_exception;
11289 + param.h_App = mac_dev;
11290 +
11291 + priv->fm_mac = fm_mac_config(&param);
11292 + if (unlikely(priv->fm_mac == NULL)) {
11293 + _errno = -EINVAL;
11294 + goto _return;
11295 + }
11296 +
11297 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11298 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11299 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11300 +
11301 + _errno = fm_mac_config_max_frame_length(priv->fm_mac, fm_get_max_frm());
11302 + if (unlikely(_errno < 0))
11303 + goto _return_fm_mac_free;
11304 +
11305 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11306 + if (unlikely(_errno < 0))
11307 + goto _return_fm_mac_free;
11308 +
11309 + _errno = fm_mac_init(priv->fm_mac);
11310 + if (unlikely(_errno < 0))
11311 + goto _return_fm_mac_free;
11312 +
11313 + dev_info(mac_dev->dev, "FMan MEMAC\n");
11314 +
11315 + goto _return;
11316 +
11317 +_return_fm_mac_free:
11318 + fm_mac_free(priv->fm_mac);
11319 +
11320 +_return:
11321 + return _errno;
11322 +}
11323 +
11324 +static int __cold start(struct mac_device *mac_dev)
11325 +{
11326 + int _errno;
11327 + struct phy_device *phy_dev = mac_dev->phy_dev;
11328 +
11329 + _errno = fm_mac_enable(mac_dev->get_mac_handle(mac_dev));
11330 +
11331 + if (!_errno && phy_dev)
11332 + phy_start(phy_dev);
11333 +
11334 + return _errno;
11335 +}
11336 +
11337 +static int __cold stop(struct mac_device *mac_dev)
11338 +{
11339 + if (mac_dev->phy_dev)
11340 + phy_stop(mac_dev->phy_dev);
11341 +
11342 + return fm_mac_disable(mac_dev->get_mac_handle(mac_dev));
11343 +}
11344 +
11345 +static int __cold set_multi(struct net_device *net_dev,
11346 + struct mac_device *mac_dev)
11347 +{
11348 + struct mac_priv_s *mac_priv;
11349 + struct mac_address *old_addr, *tmp;
11350 + struct netdev_hw_addr *ha;
11351 + int _errno;
11352 +
11353 + mac_priv = macdev_priv(mac_dev);
11354 +
11355 + /* Clear previous address list */
11356 + list_for_each_entry_safe(old_addr, tmp, &mac_dev->mc_addr_list, list) {
11357 + _errno = fm_mac_remove_hash_mac_addr(mac_priv->fm_mac,
11358 + (t_EnetAddr *)old_addr->addr);
11359 + if (_errno < 0)
11360 + return _errno;
11361 +
11362 + list_del(&old_addr->list);
11363 + kfree(old_addr);
11364 + }
11365 +
11366 + /* Add all the addresses from the new list */
11367 + netdev_for_each_mc_addr(ha, net_dev) {
11368 + _errno = fm_mac_add_hash_mac_addr(mac_priv->fm_mac,
11369 + (t_EnetAddr *)ha->addr);
11370 + if (_errno < 0)
11371 + return _errno;
11372 +
11373 + tmp = kmalloc(sizeof(struct mac_address), GFP_ATOMIC);
11374 + if (!tmp) {
11375 + dev_err(mac_dev->dev, "Out of memory\n");
11376 + return -ENOMEM;
11377 + }
11378 + memcpy(tmp->addr, ha->addr, ETH_ALEN);
11379 + list_add(&tmp->list, &mac_dev->mc_addr_list);
11380 + }
11381 + return 0;
11382 +}
11383 +
11384 +/* Avoid redundant calls to FMD, if the MAC driver already contains the desired
11385 + * active PAUSE settings. Otherwise, the new active settings should be reflected
11386 + * in FMan.
11387 + */
11388 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
11389 +{
11390 + struct fm_mac_dev *fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11391 + int _errno = 0;
11392 +
11393 + if (unlikely(rx != mac_dev->rx_pause_active)) {
11394 + _errno = fm_mac_set_rx_pause_frames(fm_mac_dev, rx);
11395 + if (likely(_errno == 0))
11396 + mac_dev->rx_pause_active = rx;
11397 + }
11398 +
11399 + if (unlikely(tx != mac_dev->tx_pause_active)) {
11400 + _errno = fm_mac_set_tx_pause_frames(fm_mac_dev, tx);
11401 + if (likely(_errno == 0))
11402 + mac_dev->tx_pause_active = tx;
11403 + }
11404 +
11405 + return _errno;
11406 +}
11407 +EXPORT_SYMBOL(set_mac_active_pause);
11408 +
11409 +/* Determine the MAC RX/TX PAUSE frames settings based on PHY
11410 + * autonegotiation or values set by eththool.
11411 + */
11412 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause)
11413 +{
11414 + struct phy_device *phy_dev = mac_dev->phy_dev;
11415 + u16 lcl_adv, rmt_adv;
11416 + u8 flowctrl;
11417 +
11418 + *rx_pause = *tx_pause = false;
11419 +
11420 + if (!phy_dev->duplex)
11421 + return;
11422 +
11423 + /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
11424 + * are those set by ethtool.
11425 + */
11426 + if (!mac_dev->autoneg_pause) {
11427 + *rx_pause = mac_dev->rx_pause_req;
11428 + *tx_pause = mac_dev->tx_pause_req;
11429 + return;
11430 + }
11431 +
11432 + /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
11433 + * settings depend on the result of the link negotiation.
11434 + */
11435 +
11436 + /* get local capabilities */
11437 + lcl_adv = 0;
11438 + if (phy_dev->advertising & ADVERTISED_Pause)
11439 + lcl_adv |= ADVERTISE_PAUSE_CAP;
11440 + if (phy_dev->advertising & ADVERTISED_Asym_Pause)
11441 + lcl_adv |= ADVERTISE_PAUSE_ASYM;
11442 +
11443 + /* get link partner capabilities */
11444 + rmt_adv = 0;
11445 + if (phy_dev->pause)
11446 + rmt_adv |= LPA_PAUSE_CAP;
11447 + if (phy_dev->asym_pause)
11448 + rmt_adv |= LPA_PAUSE_ASYM;
11449 +
11450 + /* Calculate TX/RX settings based on local and peer advertised
11451 + * symmetric/asymmetric PAUSE capabilities.
11452 + */
11453 + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
11454 + if (flowctrl & FLOW_CTRL_RX)
11455 + *rx_pause = true;
11456 + if (flowctrl & FLOW_CTRL_TX)
11457 + *tx_pause = true;
11458 +}
11459 +EXPORT_SYMBOL(get_pause_cfg);
11460 +
11461 +static void adjust_link_void(struct net_device *net_dev)
11462 +{
11463 +}
11464 +
11465 +static void adjust_link(struct net_device *net_dev)
11466 +{
11467 + struct dpa_priv_s *priv = netdev_priv(net_dev);
11468 + struct mac_device *mac_dev = priv->mac_dev;
11469 + struct phy_device *phy_dev = mac_dev->phy_dev;
11470 + struct fm_mac_dev *fm_mac_dev;
11471 + bool rx_pause, tx_pause;
11472 + int _errno;
11473 +
11474 + fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11475 + fm_mac_adjust_link(fm_mac_dev, phy_dev->link, phy_dev->speed,
11476 + phy_dev->duplex);
11477 +
11478 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
11479 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
11480 + if (unlikely(_errno < 0))
11481 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
11482 +}
11483 +
11484 +/* Initializes driver's PHY state, and attaches to the PHY.
11485 + * Returns 0 on success.
11486 + */
11487 +static int dtsec_init_phy(struct net_device *net_dev,
11488 + struct mac_device *mac_dev)
11489 +{
11490 + struct phy_device *phy_dev;
11491 +
11492 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11493 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11494 + 0, mac_dev->phy_if);
11495 + else
11496 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11497 + &adjust_link, 0, mac_dev->phy_if);
11498 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11499 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11500 + mac_dev->phy_node ?
11501 + mac_dev->phy_node->full_name :
11502 + mac_dev->fixed_bus_id);
11503 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11504 + }
11505 +
11506 + /* Remove any features not supported by the controller */
11507 + phy_dev->supported &= mac_dev->if_support;
11508 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11509 + * as most of the PHY drivers do not enable them by default.
11510 + */
11511 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11512 + phy_dev->advertising = phy_dev->supported;
11513 +
11514 + mac_dev->phy_dev = phy_dev;
11515 +
11516 + return 0;
11517 +}
11518 +
11519 +static int xgmac_init_phy(struct net_device *net_dev,
11520 + struct mac_device *mac_dev)
11521 +{
11522 + struct phy_device *phy_dev;
11523 +
11524 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11525 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11526 + 0, mac_dev->phy_if);
11527 + else
11528 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11529 + &adjust_link_void, 0, mac_dev->phy_if);
11530 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11531 + netdev_err(net_dev, "Could not attach to PHY %s\n",
11532 + mac_dev->phy_node ?
11533 + mac_dev->phy_node->full_name :
11534 + mac_dev->fixed_bus_id);
11535 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11536 + }
11537 +
11538 + phy_dev->supported &= mac_dev->if_support;
11539 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11540 + * as most of the PHY drivers do not enable them by default.
11541 + */
11542 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11543 + phy_dev->advertising = phy_dev->supported;
11544 +
11545 + mac_dev->phy_dev = phy_dev;
11546 +
11547 + return 0;
11548 +}
11549 +
11550 +static int memac_init_phy(struct net_device *net_dev,
11551 + struct mac_device *mac_dev)
11552 +{
11553 + struct phy_device *phy_dev;
11554 +
11555 + if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) ||
11556 + (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500) ||
11557 + of_phy_is_fixed_link(mac_dev->phy_node)) {
11558 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11559 + &adjust_link_void, 0,
11560 + mac_dev->phy_if);
11561 + } else {
11562 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11563 + &adjust_link, 0, mac_dev->phy_if);
11564 + }
11565 +
11566 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11567 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11568 + mac_dev->phy_node ?
11569 + mac_dev->phy_node->full_name :
11570 + mac_dev->fixed_bus_id);
11571 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11572 + }
11573 +
11574 + /* Remove any features not supported by the controller */
11575 + phy_dev->supported &= mac_dev->if_support;
11576 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11577 + * as most of the PHY drivers do not enable them by default.
11578 + */
11579 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11580 + phy_dev->advertising = phy_dev->supported;
11581 +
11582 + mac_dev->phy_dev = phy_dev;
11583 +
11584 + return 0;
11585 +}
11586 +
11587 +static int __cold uninit(struct fm_mac_dev *fm_mac_dev)
11588 +{
11589 + int _errno, __errno;
11590 +
11591 + _errno = fm_mac_disable(fm_mac_dev);
11592 + __errno = fm_mac_free(fm_mac_dev);
11593 +
11594 + if (unlikely(__errno < 0))
11595 + _errno = __errno;
11596 +
11597 + return _errno;
11598 +}
11599 +
11600 +static struct fm_mac_dev *get_mac_handle(struct mac_device *mac_dev)
11601 +{
11602 + const struct mac_priv_s *priv;
11603 + priv = macdev_priv(mac_dev);
11604 + return priv->fm_mac;
11605 +}
11606 +
11607 +static int dtsec_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11608 +{
11609 + struct dtsec_regs *p_mm = (struct dtsec_regs *) h_mac->vaddr;
11610 + int i = 0, n = nn;
11611 +
11612 + FM_DMP_SUBTITLE(buf, n, "\n");
11613 +
11614 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - DTSEC-%d", h_mac->cell_index);
11615 +
11616 + FM_DMP_V32(buf, n, p_mm, tsec_id);
11617 + FM_DMP_V32(buf, n, p_mm, tsec_id2);
11618 + FM_DMP_V32(buf, n, p_mm, ievent);
11619 + FM_DMP_V32(buf, n, p_mm, imask);
11620 + FM_DMP_V32(buf, n, p_mm, ecntrl);
11621 + FM_DMP_V32(buf, n, p_mm, ptv);
11622 + FM_DMP_V32(buf, n, p_mm, tmr_ctrl);
11623 + FM_DMP_V32(buf, n, p_mm, tmr_pevent);
11624 + FM_DMP_V32(buf, n, p_mm, tmr_pemask);
11625 + FM_DMP_V32(buf, n, p_mm, tctrl);
11626 + FM_DMP_V32(buf, n, p_mm, rctrl);
11627 + FM_DMP_V32(buf, n, p_mm, maccfg1);
11628 + FM_DMP_V32(buf, n, p_mm, maccfg2);
11629 + FM_DMP_V32(buf, n, p_mm, ipgifg);
11630 + FM_DMP_V32(buf, n, p_mm, hafdup);
11631 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11632 +
11633 + FM_DMP_V32(buf, n, p_mm, macstnaddr1);
11634 + FM_DMP_V32(buf, n, p_mm, macstnaddr2);
11635 +
11636 + for (i = 0; i < 7; ++i) {
11637 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match1);
11638 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match2);
11639 + }
11640 +
11641 + FM_DMP_V32(buf, n, p_mm, car1);
11642 + FM_DMP_V32(buf, n, p_mm, car2);
11643 +
11644 + return n;
11645 +}
11646 +
11647 +static int xgmac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11648 +{
11649 + struct tgec_regs *p_mm = (struct tgec_regs *) h_mac->vaddr;
11650 + int n = nn;
11651 +
11652 + FM_DMP_SUBTITLE(buf, n, "\n");
11653 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - TGEC -%d", h_mac->cell_index);
11654 +
11655 + FM_DMP_V32(buf, n, p_mm, tgec_id);
11656 + FM_DMP_V32(buf, n, p_mm, command_config);
11657 + FM_DMP_V32(buf, n, p_mm, mac_addr_0);
11658 + FM_DMP_V32(buf, n, p_mm, mac_addr_1);
11659 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11660 + FM_DMP_V32(buf, n, p_mm, pause_quant);
11661 + FM_DMP_V32(buf, n, p_mm, rx_fifo_sections);
11662 + FM_DMP_V32(buf, n, p_mm, tx_fifo_sections);
11663 + FM_DMP_V32(buf, n, p_mm, rx_fifo_almost_f_e);
11664 + FM_DMP_V32(buf, n, p_mm, tx_fifo_almost_f_e);
11665 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11666 + FM_DMP_V32(buf, n, p_mm, mdio_cfg_status);
11667 + FM_DMP_V32(buf, n, p_mm, mdio_command);
11668 + FM_DMP_V32(buf, n, p_mm, mdio_data);
11669 + FM_DMP_V32(buf, n, p_mm, mdio_regaddr);
11670 + FM_DMP_V32(buf, n, p_mm, status);
11671 + FM_DMP_V32(buf, n, p_mm, tx_ipg_len);
11672 + FM_DMP_V32(buf, n, p_mm, mac_addr_2);
11673 + FM_DMP_V32(buf, n, p_mm, mac_addr_3);
11674 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_rd);
11675 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_wr);
11676 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_rd);
11677 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_wr);
11678 + FM_DMP_V32(buf, n, p_mm, imask);
11679 + FM_DMP_V32(buf, n, p_mm, ievent);
11680 +
11681 + return n;
11682 +}
11683 +
11684 +static int memac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11685 +{
11686 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11687 + int i = 0, n = nn;
11688 +
11689 + FM_DMP_SUBTITLE(buf, n, "\n");
11690 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d", h_mac->cell_index);
11691 +
11692 + FM_DMP_V32(buf, n, p_mm, command_config);
11693 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_l);
11694 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_u);
11695 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11696 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11697 + FM_DMP_V32(buf, n, p_mm, ievent);
11698 + FM_DMP_V32(buf, n, p_mm, tx_ipg_length);
11699 + FM_DMP_V32(buf, n, p_mm, imask);
11700 +
11701 + for (i = 0; i < 4; ++i)
11702 + FM_DMP_V32(buf, n, p_mm, pause_quanta[i]);
11703 +
11704 + for (i = 0; i < 4; ++i)
11705 + FM_DMP_V32(buf, n, p_mm, pause_thresh[i]);
11706 +
11707 + FM_DMP_V32(buf, n, p_mm, rx_pause_status);
11708 +
11709 + for (i = 0; i < MEMAC_NUM_OF_PADDRS; ++i) {
11710 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_l);
11711 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_u);
11712 + }
11713 +
11714 + FM_DMP_V32(buf, n, p_mm, lpwake_timer);
11715 + FM_DMP_V32(buf, n, p_mm, sleep_timer);
11716 + FM_DMP_V32(buf, n, p_mm, statn_config);
11717 + FM_DMP_V32(buf, n, p_mm, if_mode);
11718 + FM_DMP_V32(buf, n, p_mm, if_status);
11719 + FM_DMP_V32(buf, n, p_mm, hg_config);
11720 + FM_DMP_V32(buf, n, p_mm, hg_pause_quanta);
11721 + FM_DMP_V32(buf, n, p_mm, hg_pause_thresh);
11722 + FM_DMP_V32(buf, n, p_mm, hgrx_pause_status);
11723 + FM_DMP_V32(buf, n, p_mm, hg_fifos_status);
11724 + FM_DMP_V32(buf, n, p_mm, rhm);
11725 + FM_DMP_V32(buf, n, p_mm, thm);
11726 +
11727 + return n;
11728 +}
11729 +
11730 +static int memac_dump_regs_rx(struct mac_device *h_mac, char *buf, int nn)
11731 +{
11732 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11733 + int n = nn;
11734 +
11735 + FM_DMP_SUBTITLE(buf, n, "\n");
11736 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Rx stats", h_mac->cell_index);
11737 +
11738 + /* Rx Statistics Counter */
11739 + FM_DMP_V32(buf, n, p_mm, reoct_l);
11740 + FM_DMP_V32(buf, n, p_mm, reoct_u);
11741 + FM_DMP_V32(buf, n, p_mm, roct_l);
11742 + FM_DMP_V32(buf, n, p_mm, roct_u);
11743 + FM_DMP_V32(buf, n, p_mm, raln_l);
11744 + FM_DMP_V32(buf, n, p_mm, raln_u);
11745 + FM_DMP_V32(buf, n, p_mm, rxpf_l);
11746 + FM_DMP_V32(buf, n, p_mm, rxpf_u);
11747 + FM_DMP_V32(buf, n, p_mm, rfrm_l);
11748 + FM_DMP_V32(buf, n, p_mm, rfrm_u);
11749 + FM_DMP_V32(buf, n, p_mm, rfcs_l);
11750 + FM_DMP_V32(buf, n, p_mm, rfcs_u);
11751 + FM_DMP_V32(buf, n, p_mm, rvlan_l);
11752 + FM_DMP_V32(buf, n, p_mm, rvlan_u);
11753 + FM_DMP_V32(buf, n, p_mm, rerr_l);
11754 + FM_DMP_V32(buf, n, p_mm, rerr_u);
11755 + FM_DMP_V32(buf, n, p_mm, ruca_l);
11756 + FM_DMP_V32(buf, n, p_mm, ruca_u);
11757 + FM_DMP_V32(buf, n, p_mm, rmca_l);
11758 + FM_DMP_V32(buf, n, p_mm, rmca_u);
11759 + FM_DMP_V32(buf, n, p_mm, rbca_l);
11760 + FM_DMP_V32(buf, n, p_mm, rbca_u);
11761 + FM_DMP_V32(buf, n, p_mm, rdrp_l);
11762 + FM_DMP_V32(buf, n, p_mm, rdrp_u);
11763 + FM_DMP_V32(buf, n, p_mm, rpkt_l);
11764 + FM_DMP_V32(buf, n, p_mm, rpkt_u);
11765 + FM_DMP_V32(buf, n, p_mm, rund_l);
11766 + FM_DMP_V32(buf, n, p_mm, rund_u);
11767 + FM_DMP_V32(buf, n, p_mm, r64_l);
11768 + FM_DMP_V32(buf, n, p_mm, r64_u);
11769 + FM_DMP_V32(buf, n, p_mm, r127_l);
11770 + FM_DMP_V32(buf, n, p_mm, r127_u);
11771 + FM_DMP_V32(buf, n, p_mm, r255_l);
11772 + FM_DMP_V32(buf, n, p_mm, r255_u);
11773 + FM_DMP_V32(buf, n, p_mm, r511_l);
11774 + FM_DMP_V32(buf, n, p_mm, r511_u);
11775 + FM_DMP_V32(buf, n, p_mm, r1023_l);
11776 + FM_DMP_V32(buf, n, p_mm, r1023_u);
11777 + FM_DMP_V32(buf, n, p_mm, r1518_l);
11778 + FM_DMP_V32(buf, n, p_mm, r1518_u);
11779 + FM_DMP_V32(buf, n, p_mm, r1519x_l);
11780 + FM_DMP_V32(buf, n, p_mm, r1519x_u);
11781 + FM_DMP_V32(buf, n, p_mm, rovr_l);
11782 + FM_DMP_V32(buf, n, p_mm, rovr_u);
11783 + FM_DMP_V32(buf, n, p_mm, rjbr_l);
11784 + FM_DMP_V32(buf, n, p_mm, rjbr_u);
11785 + FM_DMP_V32(buf, n, p_mm, rfrg_l);
11786 + FM_DMP_V32(buf, n, p_mm, rfrg_u);
11787 + FM_DMP_V32(buf, n, p_mm, rcnp_l);
11788 + FM_DMP_V32(buf, n, p_mm, rcnp_u);
11789 + FM_DMP_V32(buf, n, p_mm, rdrntp_l);
11790 + FM_DMP_V32(buf, n, p_mm, rdrntp_u);
11791 +
11792 + return n;
11793 +}
11794 +
11795 +static int memac_dump_regs_tx(struct mac_device *h_mac, char *buf, int nn)
11796 +{
11797 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11798 + int n = nn;
11799 +
11800 + FM_DMP_SUBTITLE(buf, n, "\n");
11801 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Tx stats", h_mac->cell_index);
11802 +
11803 +
11804 + /* Tx Statistics Counter */
11805 + FM_DMP_V32(buf, n, p_mm, teoct_l);
11806 + FM_DMP_V32(buf, n, p_mm, teoct_u);
11807 + FM_DMP_V32(buf, n, p_mm, toct_l);
11808 + FM_DMP_V32(buf, n, p_mm, toct_u);
11809 + FM_DMP_V32(buf, n, p_mm, txpf_l);
11810 + FM_DMP_V32(buf, n, p_mm, txpf_u);
11811 + FM_DMP_V32(buf, n, p_mm, tfrm_l);
11812 + FM_DMP_V32(buf, n, p_mm, tfrm_u);
11813 + FM_DMP_V32(buf, n, p_mm, tfcs_l);
11814 + FM_DMP_V32(buf, n, p_mm, tfcs_u);
11815 + FM_DMP_V32(buf, n, p_mm, tvlan_l);
11816 + FM_DMP_V32(buf, n, p_mm, tvlan_u);
11817 + FM_DMP_V32(buf, n, p_mm, terr_l);
11818 + FM_DMP_V32(buf, n, p_mm, terr_u);
11819 + FM_DMP_V32(buf, n, p_mm, tuca_l);
11820 + FM_DMP_V32(buf, n, p_mm, tuca_u);
11821 + FM_DMP_V32(buf, n, p_mm, tmca_l);
11822 + FM_DMP_V32(buf, n, p_mm, tmca_u);
11823 + FM_DMP_V32(buf, n, p_mm, tbca_l);
11824 + FM_DMP_V32(buf, n, p_mm, tbca_u);
11825 + FM_DMP_V32(buf, n, p_mm, tpkt_l);
11826 + FM_DMP_V32(buf, n, p_mm, tpkt_u);
11827 + FM_DMP_V32(buf, n, p_mm, tund_l);
11828 + FM_DMP_V32(buf, n, p_mm, tund_u);
11829 + FM_DMP_V32(buf, n, p_mm, t64_l);
11830 + FM_DMP_V32(buf, n, p_mm, t64_u);
11831 + FM_DMP_V32(buf, n, p_mm, t127_l);
11832 + FM_DMP_V32(buf, n, p_mm, t127_u);
11833 + FM_DMP_V32(buf, n, p_mm, t255_l);
11834 + FM_DMP_V32(buf, n, p_mm, t255_u);
11835 + FM_DMP_V32(buf, n, p_mm, t511_l);
11836 + FM_DMP_V32(buf, n, p_mm, t511_u);
11837 + FM_DMP_V32(buf, n, p_mm, t1023_l);
11838 + FM_DMP_V32(buf, n, p_mm, t1023_u);
11839 + FM_DMP_V32(buf, n, p_mm, t1518_l);
11840 + FM_DMP_V32(buf, n, p_mm, t1518_u);
11841 + FM_DMP_V32(buf, n, p_mm, t1519x_l);
11842 + FM_DMP_V32(buf, n, p_mm, t1519x_u);
11843 + FM_DMP_V32(buf, n, p_mm, tcnp_l);
11844 + FM_DMP_V32(buf, n, p_mm, tcnp_u);
11845 +
11846 + return n;
11847 +}
11848 +
11849 +int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11850 +{
11851 + int n = nn;
11852 +
11853 + n = h_mac->dump_mac_regs(h_mac, buf, n);
11854 +
11855 + return n;
11856 +}
11857 +EXPORT_SYMBOL(fm_mac_dump_regs);
11858 +
11859 +int fm_mac_dump_rx_stats(struct mac_device *h_mac, char *buf, int nn)
11860 +{
11861 + int n = nn;
11862 +
11863 + if(h_mac->dump_mac_rx_stats)
11864 + n = h_mac->dump_mac_rx_stats(h_mac, buf, n);
11865 +
11866 + return n;
11867 +}
11868 +EXPORT_SYMBOL(fm_mac_dump_rx_stats);
11869 +
11870 +int fm_mac_dump_tx_stats(struct mac_device *h_mac, char *buf, int nn)
11871 +{
11872 + int n = nn;
11873 +
11874 + if(h_mac->dump_mac_tx_stats)
11875 + n = h_mac->dump_mac_tx_stats(h_mac, buf, n);
11876 +
11877 + return n;
11878 +}
11879 +EXPORT_SYMBOL(fm_mac_dump_tx_stats);
11880 +
11881 +static void __cold setup_dtsec(struct mac_device *mac_dev)
11882 +{
11883 + mac_dev->init_phy = dtsec_init_phy;
11884 + mac_dev->init = init;
11885 + mac_dev->start = start;
11886 + mac_dev->stop = stop;
11887 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11888 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11889 + mac_dev->set_multi = set_multi;
11890 + mac_dev->uninit = uninit;
11891 + mac_dev->ptp_enable = fm_mac_enable_1588_time_stamp;
11892 + mac_dev->ptp_disable = fm_mac_disable_1588_time_stamp;
11893 + mac_dev->get_mac_handle = get_mac_handle;
11894 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11895 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11896 + mac_dev->fm_rtc_enable = fm_rtc_enable;
11897 + mac_dev->fm_rtc_disable = fm_rtc_disable;
11898 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
11899 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
11900 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
11901 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
11902 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
11903 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
11904 + mac_dev->set_wol = fm_mac_set_wol;
11905 + mac_dev->dump_mac_regs = dtsec_dump_regs;
11906 +}
11907 +
11908 +static void __cold setup_xgmac(struct mac_device *mac_dev)
11909 +{
11910 + mac_dev->init_phy = xgmac_init_phy;
11911 + mac_dev->init = init;
11912 + mac_dev->start = start;
11913 + mac_dev->stop = stop;
11914 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11915 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11916 + mac_dev->set_multi = set_multi;
11917 + mac_dev->uninit = uninit;
11918 + mac_dev->get_mac_handle = get_mac_handle;
11919 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11920 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11921 + mac_dev->set_wol = fm_mac_set_wol;
11922 + mac_dev->dump_mac_regs = xgmac_dump_regs;
11923 +}
11924 +
11925 +static void __cold setup_memac(struct mac_device *mac_dev)
11926 +{
11927 + mac_dev->init_phy = memac_init_phy;
11928 + mac_dev->init = memac_init;
11929 + mac_dev->start = start;
11930 + mac_dev->stop = stop;
11931 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11932 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11933 + mac_dev->set_multi = set_multi;
11934 + mac_dev->uninit = uninit;
11935 + mac_dev->get_mac_handle = get_mac_handle;
11936 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11937 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11938 + mac_dev->fm_rtc_enable = fm_rtc_enable;
11939 + mac_dev->fm_rtc_disable = fm_rtc_disable;
11940 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
11941 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
11942 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
11943 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
11944 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
11945 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
11946 + mac_dev->set_wol = fm_mac_set_wol;
11947 + mac_dev->dump_mac_regs = memac_dump_regs;
11948 + mac_dev->dump_mac_rx_stats = memac_dump_regs_rx;
11949 + mac_dev->dump_mac_tx_stats = memac_dump_regs_tx;
11950 +}
11951 +
11952 +void (*const mac_setup[])(struct mac_device *mac_dev) = {
11953 + [DTSEC] = setup_dtsec,
11954 + [XGMAC] = setup_xgmac,
11955 + [MEMAC] = setup_memac
11956 +};
11957 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/mac.c b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
11958 new file mode 100644
11959 index 00000000..60133b02
11960 --- /dev/null
11961 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
11962 @@ -0,0 +1,489 @@
11963 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11964 + *
11965 + * Redistribution and use in source and binary forms, with or without
11966 + * modification, are permitted provided that the following conditions are met:
11967 + * * Redistributions of source code must retain the above copyright
11968 + * notice, this list of conditions and the following disclaimer.
11969 + * * Redistributions in binary form must reproduce the above copyright
11970 + * notice, this list of conditions and the following disclaimer in the
11971 + * documentation and/or other materials provided with the distribution.
11972 + * * Neither the name of Freescale Semiconductor nor the
11973 + * names of its contributors may be used to endorse or promote products
11974 + * derived from this software without specific prior written permission.
11975 + *
11976 + *
11977 + * ALTERNATIVELY, this software may be distributed under the terms of the
11978 + * GNU General Public License ("GPL") as published by the Free Software
11979 + * Foundation, either version 2 of that License or (at your option) any
11980 + * later version.
11981 + *
11982 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11983 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11984 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11985 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11986 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11987 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11988 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11989 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11990 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11991 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11992 + */
11993 +
11994 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11995 +#define pr_fmt(fmt) \
11996 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11997 + KBUILD_BASENAME".c", __LINE__, __func__
11998 +#else
11999 +#define pr_fmt(fmt) \
12000 + KBUILD_MODNAME ": " fmt
12001 +#endif
12002 +
12003 +#include <linux/init.h>
12004 +#include <linux/module.h>
12005 +#include <linux/of_address.h>
12006 +#include <linux/of_platform.h>
12007 +#include <linux/of_net.h>
12008 +#include <linux/of_mdio.h>
12009 +#include <linux/phy_fixed.h>
12010 +#include <linux/device.h>
12011 +#include <linux/phy.h>
12012 +#include <linux/io.h>
12013 +
12014 +#include "lnxwrp_fm_ext.h"
12015 +
12016 +#include "mac.h"
12017 +
12018 +#define DTSEC_SUPPORTED \
12019 + (SUPPORTED_10baseT_Half \
12020 + | SUPPORTED_10baseT_Full \
12021 + | SUPPORTED_100baseT_Half \
12022 + | SUPPORTED_100baseT_Full \
12023 + | SUPPORTED_Autoneg \
12024 + | SUPPORTED_Pause \
12025 + | SUPPORTED_Asym_Pause \
12026 + | SUPPORTED_MII)
12027 +
12028 +static const char phy_str[][11] = {
12029 + [PHY_INTERFACE_MODE_MII] = "mii",
12030 + [PHY_INTERFACE_MODE_GMII] = "gmii",
12031 + [PHY_INTERFACE_MODE_SGMII] = "sgmii",
12032 + [PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
12033 + [PHY_INTERFACE_MODE_TBI] = "tbi",
12034 + [PHY_INTERFACE_MODE_RMII] = "rmii",
12035 + [PHY_INTERFACE_MODE_RGMII] = "rgmii",
12036 + [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
12037 + [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
12038 + [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
12039 + [PHY_INTERFACE_MODE_RTBI] = "rtbi",
12040 + [PHY_INTERFACE_MODE_XGMII] = "xgmii",
12041 + [PHY_INTERFACE_MODE_SGMII_2500] = "sgmii-2500",
12042 +};
12043 +
12044 +static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str)
12045 +{
12046 + int i;
12047 +
12048 + for (i = 0; i < ARRAY_SIZE(phy_str); i++)
12049 + if (strcmp(str, phy_str[i]) == 0)
12050 + return (phy_interface_t)i;
12051 +
12052 + return PHY_INTERFACE_MODE_MII;
12053 +}
12054 +
12055 +static const uint16_t phy2speed[] = {
12056 + [PHY_INTERFACE_MODE_MII] = SPEED_100,
12057 + [PHY_INTERFACE_MODE_GMII] = SPEED_1000,
12058 + [PHY_INTERFACE_MODE_SGMII] = SPEED_1000,
12059 + [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
12060 + [PHY_INTERFACE_MODE_TBI] = SPEED_1000,
12061 + [PHY_INTERFACE_MODE_RMII] = SPEED_100,
12062 + [PHY_INTERFACE_MODE_RGMII] = SPEED_1000,
12063 + [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000,
12064 + [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
12065 + [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
12066 + [PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
12067 + [PHY_INTERFACE_MODE_XGMII] = SPEED_10000,
12068 + [PHY_INTERFACE_MODE_SGMII_2500] = SPEED_2500,
12069 +};
12070 +
12071 +static struct mac_device * __cold
12072 +alloc_macdev(struct device *dev, size_t sizeof_priv,
12073 + void (*setup)(struct mac_device *mac_dev))
12074 +{
12075 + struct mac_device *mac_dev;
12076 +
12077 + mac_dev = devm_kzalloc(dev, sizeof(*mac_dev) + sizeof_priv, GFP_KERNEL);
12078 + if (unlikely(mac_dev == NULL))
12079 + mac_dev = ERR_PTR(-ENOMEM);
12080 + else {
12081 + mac_dev->dev = dev;
12082 + dev_set_drvdata(dev, mac_dev);
12083 + setup(mac_dev);
12084 + }
12085 +
12086 + return mac_dev;
12087 +}
12088 +
12089 +static int __cold free_macdev(struct mac_device *mac_dev)
12090 +{
12091 + dev_set_drvdata(mac_dev->dev, NULL);
12092 +
12093 + return mac_dev->uninit(mac_dev->get_mac_handle(mac_dev));
12094 +}
12095 +
12096 +static const struct of_device_id mac_match[] = {
12097 + [DTSEC] = {
12098 + .compatible = "fsl,fman-1g-mac"
12099 + },
12100 + [XGMAC] = {
12101 + .compatible = "fsl,fman-10g-mac"
12102 + },
12103 + [MEMAC] = {
12104 + .compatible = "fsl,fman-memac"
12105 + },
12106 + {}
12107 +};
12108 +MODULE_DEVICE_TABLE(of, mac_match);
12109 +
12110 +static int __cold mac_probe(struct platform_device *_of_dev)
12111 +{
12112 + int _errno, i;
12113 + struct device *dev;
12114 + struct device_node *mac_node, *dev_node;
12115 + struct mac_device *mac_dev;
12116 + struct platform_device *of_dev;
12117 + struct resource res;
12118 + const uint8_t *mac_addr;
12119 + const char *char_prop;
12120 + int nph;
12121 + u32 cell_index;
12122 + const struct of_device_id *match;
12123 +
12124 + dev = &_of_dev->dev;
12125 + mac_node = dev->of_node;
12126 +
12127 + match = of_match_device(mac_match, dev);
12128 + if (!match)
12129 + return -EINVAL;
12130 +
12131 + for (i = 0; i < ARRAY_SIZE(mac_match) - 1 && match != mac_match + i;
12132 + i++)
12133 + ;
12134 + BUG_ON(i >= ARRAY_SIZE(mac_match) - 1);
12135 +
12136 + mac_dev = alloc_macdev(dev, mac_sizeof_priv[i], mac_setup[i]);
12137 + if (IS_ERR(mac_dev)) {
12138 + _errno = PTR_ERR(mac_dev);
12139 + dev_err(dev, "alloc_macdev() = %d\n", _errno);
12140 + goto _return;
12141 + }
12142 +
12143 + INIT_LIST_HEAD(&mac_dev->mc_addr_list);
12144 +
12145 + /* Get the FM node */
12146 + dev_node = of_get_parent(mac_node);
12147 + if (unlikely(dev_node == NULL)) {
12148 + dev_err(dev, "of_get_parent(%s) failed\n",
12149 + mac_node->full_name);
12150 + _errno = -EINVAL;
12151 + goto _return_dev_set_drvdata;
12152 + }
12153 +
12154 + of_dev = of_find_device_by_node(dev_node);
12155 + if (unlikely(of_dev == NULL)) {
12156 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12157 + dev_node->full_name);
12158 + _errno = -EINVAL;
12159 + goto _return_of_node_put;
12160 + }
12161 +
12162 + mac_dev->fm_dev = fm_bind(&of_dev->dev);
12163 + if (unlikely(mac_dev->fm_dev == NULL)) {
12164 + dev_err(dev, "fm_bind(%s) failed\n", dev_node->full_name);
12165 + _errno = -ENODEV;
12166 + goto _return_of_node_put;
12167 + }
12168 +
12169 + mac_dev->fm = (void *)fm_get_handle(mac_dev->fm_dev);
12170 + of_node_put(dev_node);
12171 +
12172 + /* Get the address of the memory mapped registers */
12173 + _errno = of_address_to_resource(mac_node, 0, &res);
12174 + if (unlikely(_errno < 0)) {
12175 + dev_err(dev, "of_address_to_resource(%s) = %d\n",
12176 + mac_node->full_name, _errno);
12177 + goto _return_dev_set_drvdata;
12178 + }
12179 +
12180 + mac_dev->res = __devm_request_region(
12181 + dev,
12182 + fm_get_mem_region(mac_dev->fm_dev),
12183 + res.start, res.end + 1 - res.start, "mac");
12184 + if (unlikely(mac_dev->res == NULL)) {
12185 + dev_err(dev, "__devm_request_mem_region(mac) failed\n");
12186 + _errno = -EBUSY;
12187 + goto _return_dev_set_drvdata;
12188 + }
12189 +
12190 + mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
12191 + mac_dev->res->end + 1
12192 + - mac_dev->res->start);
12193 + if (unlikely(mac_dev->vaddr == NULL)) {
12194 + dev_err(dev, "devm_ioremap() failed\n");
12195 + _errno = -EIO;
12196 + goto _return_dev_set_drvdata;
12197 + }
12198 +
12199 +#define TBIPA_OFFSET 0x1c
12200 +#define TBIPA_DEFAULT_ADDR 5 /* override if used as external PHY addr. */
12201 + mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0);
12202 + if (mac_dev->tbi_node) {
12203 + u32 tbiaddr = TBIPA_DEFAULT_ADDR;
12204 + const __be32 *tbi_reg;
12205 + void __iomem *addr;
12206 +
12207 + tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL);
12208 + if (tbi_reg)
12209 + tbiaddr = be32_to_cpup(tbi_reg);
12210 + addr = mac_dev->vaddr + TBIPA_OFFSET;
12211 + /* TODO: out_be32 does not exist on ARM */
12212 + out_be32(addr, tbiaddr);
12213 + }
12214 +
12215 + if (!of_device_is_available(mac_node)) {
12216 + devm_iounmap(dev, mac_dev->vaddr);
12217 + __devm_release_region(dev, fm_get_mem_region(mac_dev->fm_dev),
12218 + res.start, res.end + 1 - res.start);
12219 + fm_unbind(mac_dev->fm_dev);
12220 + devm_kfree(dev, mac_dev);
12221 + dev_set_drvdata(dev, NULL);
12222 + return -ENODEV;
12223 + }
12224 +
12225 + /* Get the cell-index */
12226 + _errno = of_property_read_u32(mac_node, "cell-index", &cell_index);
12227 + if (unlikely(_errno)) {
12228 + dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n",
12229 + mac_node->full_name);
12230 + goto _return_dev_set_drvdata;
12231 + }
12232 + mac_dev->cell_index = (uint8_t)cell_index;
12233 + if (mac_dev->cell_index >= 8)
12234 + mac_dev->cell_index -= 8;
12235 +
12236 + /* Get the MAC address */
12237 + mac_addr = of_get_mac_address(mac_node);
12238 + if (unlikely(mac_addr == NULL)) {
12239 + dev_err(dev, "of_get_mac_address(%s) failed\n",
12240 + mac_node->full_name);
12241 + _errno = -EINVAL;
12242 + goto _return_dev_set_drvdata;
12243 + }
12244 + memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
12245 +
12246 + /* Verify the number of port handles */
12247 + nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
12248 + if (unlikely(nph < 0)) {
12249 + dev_err(dev, "Cannot read port handles of mac node %s from device tree\n",
12250 + mac_node->full_name);
12251 + _errno = nph;
12252 + goto _return_dev_set_drvdata;
12253 + }
12254 +
12255 + if (nph != ARRAY_SIZE(mac_dev->port_dev)) {
12256 + dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n",
12257 + mac_node->full_name);
12258 + _errno = -EINVAL;
12259 + goto _return_dev_set_drvdata;
12260 + }
12261 +
12262 + for_each_port_device(i, mac_dev->port_dev) {
12263 + dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
12264 + if (unlikely(dev_node == NULL)) {
12265 + dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n",
12266 + mac_node->full_name);
12267 + _errno = -EINVAL;
12268 + goto _return_of_node_put;
12269 + }
12270 +
12271 + of_dev = of_find_device_by_node(dev_node);
12272 + if (unlikely(of_dev == NULL)) {
12273 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12274 + dev_node->full_name);
12275 + _errno = -EINVAL;
12276 + goto _return_of_node_put;
12277 + }
12278 +
12279 + mac_dev->port_dev[i] = fm_port_bind(&of_dev->dev);
12280 + if (unlikely(mac_dev->port_dev[i] == NULL)) {
12281 + dev_err(dev, "dev_get_drvdata(%s) failed\n",
12282 + dev_node->full_name);
12283 + _errno = -EINVAL;
12284 + goto _return_of_node_put;
12285 + }
12286 + of_node_put(dev_node);
12287 + }
12288 +
12289 + /* Get the PHY connection type */
12290 + _errno = of_property_read_string(mac_node, "phy-connection-type",
12291 + &char_prop);
12292 + if (unlikely(_errno)) {
12293 + dev_warn(dev,
12294 + "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n",
12295 + mac_node->full_name);
12296 + mac_dev->phy_if = PHY_INTERFACE_MODE_MII;
12297 + } else
12298 + mac_dev->phy_if = str2phy(char_prop);
12299 +
12300 + mac_dev->link = false;
12301 + mac_dev->half_duplex = false;
12302 + mac_dev->speed = phy2speed[mac_dev->phy_if];
12303 + mac_dev->max_speed = mac_dev->speed;
12304 + mac_dev->if_support = DTSEC_SUPPORTED;
12305 + /* We don't support half-duplex in SGMII mode */
12306 + if (strstr(char_prop, "sgmii") || strstr(char_prop, "qsgmii") ||
12307 + strstr(char_prop, "sgmii-2500"))
12308 + mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
12309 + SUPPORTED_100baseT_Half);
12310 +
12311 + /* Gigabit support (no half-duplex) */
12312 + if (mac_dev->max_speed == SPEED_1000 ||
12313 + mac_dev->max_speed == SPEED_2500)
12314 + mac_dev->if_support |= SUPPORTED_1000baseT_Full;
12315 +
12316 + /* The 10G interface only supports one mode */
12317 + if (strstr(char_prop, "xgmii"))
12318 + mac_dev->if_support = SUPPORTED_10000baseT_Full;
12319 +
12320 + /* Get the rest of the PHY information */
12321 + mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
12322 + if (!mac_dev->phy_node) {
12323 + struct phy_device *phy;
12324 +
12325 + if (!of_phy_is_fixed_link(mac_node)) {
12326 + dev_err(dev, "Wrong PHY information of mac node %s\n",
12327 + mac_node->full_name);
12328 + goto _return_dev_set_drvdata;
12329 + }
12330 +
12331 + _errno = of_phy_register_fixed_link(mac_node);
12332 + if (_errno)
12333 + goto _return_dev_set_drvdata;
12334 +
12335 + mac_dev->fixed_link = devm_kzalloc(mac_dev->dev,
12336 + sizeof(*mac_dev->fixed_link),
12337 + GFP_KERNEL);
12338 + if (!mac_dev->fixed_link)
12339 + goto _return_dev_set_drvdata;
12340 +
12341 + mac_dev->phy_node = of_node_get(mac_node);
12342 + phy = of_phy_find_device(mac_dev->phy_node);
12343 + if (!phy)
12344 + goto _return_dev_set_drvdata;
12345 +
12346 + mac_dev->fixed_link->link = phy->link;
12347 + mac_dev->fixed_link->speed = phy->speed;
12348 + mac_dev->fixed_link->duplex = phy->duplex;
12349 + mac_dev->fixed_link->pause = phy->pause;
12350 + mac_dev->fixed_link->asym_pause = phy->asym_pause;
12351 + }
12352 +
12353 + _errno = mac_dev->init(mac_dev);
12354 + if (unlikely(_errno < 0)) {
12355 + dev_err(dev, "mac_dev->init() = %d\n", _errno);
12356 + goto _return_dev_set_drvdata;
12357 + }
12358 +
12359 + /* pause frame autonegotiation enabled*/
12360 + mac_dev->autoneg_pause = true;
12361 +
12362 + /* by intializing the values to false, force FMD to enable PAUSE frames
12363 + * on RX and TX
12364 + */
12365 + mac_dev->rx_pause_req = mac_dev->tx_pause_req = true;
12366 + mac_dev->rx_pause_active = mac_dev->tx_pause_active = false;
12367 + _errno = set_mac_active_pause(mac_dev, true, true);
12368 + if (unlikely(_errno < 0))
12369 + dev_err(dev, "set_mac_active_pause() = %d\n", _errno);
12370 +
12371 + dev_info(dev,
12372 + "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
12373 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
12374 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
12375 +
12376 + goto _return;
12377 +
12378 +_return_of_node_put:
12379 + of_node_put(dev_node);
12380 +_return_dev_set_drvdata:
12381 + dev_set_drvdata(dev, NULL);
12382 +_return:
12383 + return _errno;
12384 +}
12385 +
12386 +static int __cold mac_remove(struct platform_device *of_dev)
12387 +{
12388 + int i, _errno;
12389 + struct device *dev;
12390 + struct mac_device *mac_dev;
12391 +
12392 + dev = &of_dev->dev;
12393 + mac_dev = (struct mac_device *)dev_get_drvdata(dev);
12394 +
12395 + for_each_port_device(i, mac_dev->port_dev)
12396 + fm_port_unbind(mac_dev->port_dev[i]);
12397 +
12398 + fm_unbind(mac_dev->fm_dev);
12399 +
12400 + _errno = free_macdev(mac_dev);
12401 +
12402 + return _errno;
12403 +}
12404 +
12405 +static struct platform_driver mac_driver = {
12406 + .driver = {
12407 + .name = KBUILD_MODNAME,
12408 + .of_match_table = mac_match,
12409 + .owner = THIS_MODULE,
12410 + },
12411 + .probe = mac_probe,
12412 + .remove = mac_remove
12413 +};
12414 +
12415 +static int __init __cold mac_load(void)
12416 +{
12417 + int _errno;
12418 +
12419 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12420 + KBUILD_BASENAME".c", __func__);
12421 +
12422 + pr_info(KBUILD_MODNAME ": %s\n", mac_driver_description);
12423 +
12424 + _errno = platform_driver_register(&mac_driver);
12425 + if (unlikely(_errno < 0)) {
12426 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): platform_driver_register() = %d\n",
12427 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
12428 + goto _return;
12429 + }
12430 +
12431 + goto _return;
12432 +
12433 +_return:
12434 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12435 + KBUILD_BASENAME".c", __func__);
12436 +
12437 + return _errno;
12438 +}
12439 +module_init(mac_load);
12440 +
12441 +static void __exit __cold mac_unload(void)
12442 +{
12443 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12444 + KBUILD_BASENAME".c", __func__);
12445 +
12446 + platform_driver_unregister(&mac_driver);
12447 +
12448 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12449 + KBUILD_BASENAME".c", __func__);
12450 +}
12451 +module_exit(mac_unload);
12452 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/mac.h b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h
12453 new file mode 100644
12454 index 00000000..b5288f2a
12455 --- /dev/null
12456 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h
12457 @@ -0,0 +1,135 @@
12458 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
12459 + *
12460 + * Redistribution and use in source and binary forms, with or without
12461 + * modification, are permitted provided that the following conditions are met:
12462 + * * Redistributions of source code must retain the above copyright
12463 + * notice, this list of conditions and the following disclaimer.
12464 + * * Redistributions in binary form must reproduce the above copyright
12465 + * notice, this list of conditions and the following disclaimer in the
12466 + * documentation and/or other materials provided with the distribution.
12467 + * * Neither the name of Freescale Semiconductor nor the
12468 + * names of its contributors may be used to endorse or promote products
12469 + * derived from this software without specific prior written permission.
12470 + *
12471 + *
12472 + * ALTERNATIVELY, this software may be distributed under the terms of the
12473 + * GNU General Public License ("GPL") as published by the Free Software
12474 + * Foundation, either version 2 of that License or (at your option) any
12475 + * later version.
12476 + *
12477 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12478 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12479 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12480 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12481 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12482 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12483 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12484 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12485 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12486 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12487 + */
12488 +
12489 +#ifndef __MAC_H
12490 +#define __MAC_H
12491 +
12492 +#include <linux/device.h> /* struct device, BUS_ID_SIZE */
12493 +#include <linux/if_ether.h> /* ETH_ALEN */
12494 +#include <linux/phy.h> /* phy_interface_t, struct phy_device */
12495 +#include <linux/list.h>
12496 +
12497 +#include "lnxwrp_fsl_fman.h" /* struct port_device */
12498 +
12499 +enum {DTSEC, XGMAC, MEMAC};
12500 +
12501 +struct mac_device {
12502 + struct device *dev;
12503 + void *priv;
12504 + uint8_t cell_index;
12505 + struct resource *res;
12506 + void __iomem *vaddr;
12507 + uint8_t addr[ETH_ALEN];
12508 + bool promisc;
12509 +
12510 + struct fm *fm_dev;
12511 + struct fm_port *port_dev[2];
12512 +
12513 + phy_interface_t phy_if;
12514 + u32 if_support;
12515 + bool link;
12516 + bool half_duplex;
12517 + uint16_t speed;
12518 + uint16_t max_speed;
12519 + struct device_node *phy_node;
12520 + char fixed_bus_id[MII_BUS_ID_SIZE + 3];
12521 + struct device_node *tbi_node;
12522 + struct phy_device *phy_dev;
12523 + void *fm;
12524 + /* List of multicast addresses */
12525 + struct list_head mc_addr_list;
12526 + struct fixed_phy_status *fixed_link;
12527 +
12528 + bool autoneg_pause;
12529 + bool rx_pause_req;
12530 + bool tx_pause_req;
12531 + bool rx_pause_active;
12532 + bool tx_pause_active;
12533 +
12534 + struct fm_mac_dev *(*get_mac_handle)(struct mac_device *mac_dev);
12535 + int (*init_phy)(struct net_device *net_dev, struct mac_device *mac_dev);
12536 + int (*init)(struct mac_device *mac_dev);
12537 + int (*start)(struct mac_device *mac_dev);
12538 + int (*stop)(struct mac_device *mac_dev);
12539 + int (*set_promisc)(struct fm_mac_dev *fm_mac_dev, bool enable);
12540 + int (*change_addr)(struct fm_mac_dev *fm_mac_dev, uint8_t *addr);
12541 + int (*set_multi)(struct net_device *net_dev,
12542 + struct mac_device *mac_dev);
12543 + int (*uninit)(struct fm_mac_dev *fm_mac_dev);
12544 + int (*ptp_enable)(struct fm_mac_dev *fm_mac_dev);
12545 + int (*ptp_disable)(struct fm_mac_dev *fm_mac_dev);
12546 + int (*set_rx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12547 + int (*set_tx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12548 + int (*fm_rtc_enable)(struct fm *fm_dev);
12549 + int (*fm_rtc_disable)(struct fm *fm_dev);
12550 + int (*fm_rtc_get_cnt)(struct fm *fm_dev, uint64_t *ts);
12551 + int (*fm_rtc_set_cnt)(struct fm *fm_dev, uint64_t ts);
12552 + int (*fm_rtc_get_drift)(struct fm *fm_dev, uint32_t *drift);
12553 + int (*fm_rtc_set_drift)(struct fm *fm_dev, uint32_t drift);
12554 + int (*fm_rtc_set_alarm)(struct fm *fm_dev, uint32_t id, uint64_t time);
12555 + int (*fm_rtc_set_fiper)(struct fm *fm_dev, uint32_t id,
12556 + uint64_t fiper);
12557 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
12558 + int (*fm_rtc_enable_interrupt)(struct fm *fm_dev, uint32_t events);
12559 + int (*fm_rtc_disable_interrupt)(struct fm *fm_dev, uint32_t events);
12560 +#endif
12561 + int (*set_wol)(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
12562 + bool en);
12563 + int (*dump_mac_regs)(struct mac_device *h_mac, char *buf, int nn);
12564 + int (*dump_mac_rx_stats)(struct mac_device *h_mac, char *buf, int nn);
12565 + int (*dump_mac_tx_stats)(struct mac_device *h_mac, char *buf, int nn);
12566 +};
12567 +
12568 +struct mac_address {
12569 + uint8_t addr[ETH_ALEN];
12570 + struct list_head list;
12571 +};
12572 +
12573 +#define get_fm_handle(net_dev) \
12574 + (((struct dpa_priv_s *)netdev_priv(net_dev))->mac_dev->fm_dev)
12575 +
12576 +#define for_each_port_device(i, port_dev) \
12577 + for (i = 0; i < ARRAY_SIZE(port_dev); i++)
12578 +
12579 +static inline __attribute((nonnull)) void *macdev_priv(
12580 + const struct mac_device *mac_dev)
12581 +{
12582 + return (void *)mac_dev + sizeof(*mac_dev);
12583 +}
12584 +
12585 +extern const char *mac_driver_description;
12586 +extern const size_t mac_sizeof_priv[];
12587 +extern void (*const mac_setup[])(struct mac_device *mac_dev);
12588 +
12589 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx);
12590 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause);
12591 +
12592 +#endif /* __MAC_H */
12593 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
12594 new file mode 100644
12595 index 00000000..fb084af5
12596 --- /dev/null
12597 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
12598 @@ -0,0 +1,848 @@
12599 +/* Copyright 2011-2012 Freescale Semiconductor Inc.
12600 + *
12601 + * Redistribution and use in source and binary forms, with or without
12602 + * modification, are permitted provided that the following conditions are met:
12603 + * * Redistributions of source code must retain the above copyright
12604 + * notice, this list of conditions and the following disclaimer.
12605 + * * Redistributions in binary form must reproduce the above copyright
12606 + * notice, this list of conditions and the following disclaimer in the
12607 + * documentation and/or other materials provided with the distribution.
12608 + * * Neither the name of Freescale Semiconductor nor the
12609 + * names of its contributors may be used to endorse or promote products
12610 + * derived from this software without specific prior written permission.
12611 + *
12612 + *
12613 + * ALTERNATIVELY, this software may be distributed under the terms of the
12614 + * GNU General Public License ("GPL") as published by the Free Software
12615 + * Foundation, either version 2 of that License or (at your option) any
12616 + * later version.
12617 + *
12618 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12619 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12620 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12621 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12622 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12623 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12624 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12625 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12626 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12627 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12628 + */
12629 +
12630 +/* Offline Parsing / Host Command port driver for FSL QorIQ FMan.
12631 + * Validates device-tree configuration and sets up the offline ports.
12632 + */
12633 +
12634 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12635 +#define pr_fmt(fmt) \
12636 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12637 + KBUILD_BASENAME".c", __LINE__, __func__
12638 +#else
12639 +#define pr_fmt(fmt) \
12640 + KBUILD_MODNAME ": " fmt
12641 +#endif
12642 +
12643 +
12644 +#include <linux/init.h>
12645 +#include <linux/module.h>
12646 +#include <linux/of_platform.h>
12647 +#include <linux/fsl_qman.h>
12648 +
12649 +#include "offline_port.h"
12650 +#include "dpaa_eth.h"
12651 +#include "dpaa_eth_common.h"
12652 +
12653 +#define OH_MOD_DESCRIPTION "FSL FMan Offline Parsing port driver"
12654 +/* Manip extra space and data alignment for fragmentation */
12655 +#define FRAG_MANIP_SPACE 128
12656 +#define FRAG_DATA_ALIGN 64
12657 +
12658 +
12659 +MODULE_LICENSE("Dual BSD/GPL");
12660 +MODULE_AUTHOR("Bogdan Hamciuc <bogdan.hamciuc@freescale.com>");
12661 +MODULE_DESCRIPTION(OH_MOD_DESCRIPTION);
12662 +
12663 +
12664 +static const struct of_device_id oh_port_match_table[] = {
12665 + {
12666 + .compatible = "fsl,dpa-oh"
12667 + },
12668 + {
12669 + .compatible = "fsl,dpa-oh-shared"
12670 + },
12671 + {}
12672 +};
12673 +MODULE_DEVICE_TABLE(of, oh_port_match_table);
12674 +
12675 +#ifdef CONFIG_PM
12676 +
12677 +static int oh_suspend(struct device *dev)
12678 +{
12679 + struct dpa_oh_config_s *oh_config;
12680 +
12681 + oh_config = dev_get_drvdata(dev);
12682 + return fm_port_suspend(oh_config->oh_port);
12683 +}
12684 +
12685 +static int oh_resume(struct device *dev)
12686 +{
12687 + struct dpa_oh_config_s *oh_config;
12688 +
12689 + oh_config = dev_get_drvdata(dev);
12690 + return fm_port_resume(oh_config->oh_port);
12691 +}
12692 +
12693 +static const struct dev_pm_ops oh_pm_ops = {
12694 + .suspend = oh_suspend,
12695 + .resume = oh_resume,
12696 +};
12697 +
12698 +#define OH_PM_OPS (&oh_pm_ops)
12699 +
12700 +#else /* CONFIG_PM */
12701 +
12702 +#define OH_PM_OPS NULL
12703 +
12704 +#endif /* CONFIG_PM */
12705 +
12706 +/* Creates Frame Queues */
12707 +static uint32_t oh_fq_create(struct qman_fq *fq,
12708 + uint32_t fq_id, uint16_t channel,
12709 + uint16_t wq_id)
12710 +{
12711 + struct qm_mcc_initfq fq_opts;
12712 + uint32_t create_flags, init_flags;
12713 + uint32_t ret = 0;
12714 +
12715 + if (fq == NULL)
12716 + return 1;
12717 +
12718 + /* Set flags for FQ create */
12719 + create_flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_TO_DCPORTAL;
12720 +
12721 + /* Create frame queue */
12722 + ret = qman_create_fq(fq_id, create_flags, fq);
12723 + if (ret != 0)
12724 + return 1;
12725 +
12726 + /* Set flags for FQ init */
12727 + init_flags = QMAN_INITFQ_FLAG_SCHED;
12728 +
12729 + /* Set FQ init options. Specify destination WQ ID and channel */
12730 + fq_opts.we_mask = QM_INITFQ_WE_DESTWQ;
12731 + fq_opts.fqd.dest.wq = wq_id;
12732 + fq_opts.fqd.dest.channel = channel;
12733 +
12734 + /* Initialize frame queue */
12735 + ret = qman_init_fq(fq, init_flags, &fq_opts);
12736 + if (ret != 0) {
12737 + qman_destroy_fq(fq, 0);
12738 + return 1;
12739 + }
12740 +
12741 + return 0;
12742 +}
12743 +
12744 +static void dump_fq(struct device *dev, int fqid, uint16_t channel)
12745 +{
12746 + if (channel) {
12747 + /* display fqs with a valid (!= 0) destination channel */
12748 + dev_info(dev, "FQ ID:%d Channel ID:%d\n", fqid, channel);
12749 + }
12750 +}
12751 +
12752 +static void dump_fq_duple(struct device *dev, struct qman_fq *fqs,
12753 + int fqs_count, uint16_t channel_id)
12754 +{
12755 + int i;
12756 + for (i = 0; i < fqs_count; i++)
12757 + dump_fq(dev, (fqs + i)->fqid, channel_id);
12758 +}
12759 +
12760 +static void dump_oh_config(struct device *dev, struct dpa_oh_config_s *conf)
12761 +{
12762 + struct list_head *fq_list;
12763 + struct fq_duple *fqd;
12764 + int i;
12765 +
12766 + dev_info(dev, "Default egress frame queue: %d\n", conf->default_fqid);
12767 + dev_info(dev, "Default error frame queue: %d\n", conf->error_fqid);
12768 +
12769 + /* TX queues (old initialization) */
12770 + dev_info(dev, "Initialized queues:");
12771 + for (i = 0; i < conf->egress_cnt; i++)
12772 + dump_fq_duple(dev, conf->egress_fqs, conf->egress_cnt,
12773 + conf->channel);
12774 +
12775 + /* initialized ingress queues */
12776 + list_for_each(fq_list, &conf->fqs_ingress_list) {
12777 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12778 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12779 + }
12780 +
12781 + /* initialized egress queues */
12782 + list_for_each(fq_list, &conf->fqs_egress_list) {
12783 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12784 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12785 + }
12786 +}
12787 +
12788 +/* Destroys Frame Queues */
12789 +static void oh_fq_destroy(struct qman_fq *fq)
12790 +{
12791 + int _errno = 0;
12792 +
12793 + _errno = qman_retire_fq(fq, NULL);
12794 + if (unlikely(_errno < 0))
12795 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_retire_fq(%u)=%d\n",
12796 + KBUILD_BASENAME".c", __LINE__, __func__,
12797 + qman_fq_fqid(fq), _errno);
12798 +
12799 + _errno = qman_oos_fq(fq);
12800 + if (unlikely(_errno < 0)) {
12801 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_oos_fq(%u)=%d\n",
12802 + KBUILD_BASENAME".c", __LINE__, __func__,
12803 + qman_fq_fqid(fq), _errno);
12804 + }
12805 +
12806 + qman_destroy_fq(fq, 0);
12807 +}
12808 +
12809 +/* Allocation code for the OH port's PCD frame queues */
12810 +static int __cold oh_alloc_pcd_fqids(struct device *dev,
12811 + uint32_t num,
12812 + uint8_t alignment,
12813 + uint32_t *base_fqid)
12814 +{
12815 + dev_crit(dev, "callback not implemented!\n");
12816 + BUG();
12817 +
12818 + return 0;
12819 +}
12820 +
12821 +static int __cold oh_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
12822 +{
12823 + dev_crit(dev, "callback not implemented!\n");
12824 + BUG();
12825 +
12826 + return 0;
12827 +}
12828 +
12829 +static void oh_set_buffer_layout(struct fm_port *port,
12830 + struct dpa_buffer_layout_s *layout)
12831 +{
12832 + struct fm_port_params params;
12833 +
12834 + layout->priv_data_size = DPA_TX_PRIV_DATA_SIZE;
12835 + layout->parse_results = true;
12836 + layout->hash_results = true;
12837 + layout->time_stamp = false;
12838 +
12839 + fm_port_get_buff_layout_ext_params(port, &params);
12840 + layout->manip_extra_space = params.manip_extra_space;
12841 + layout->data_align = params.data_align;
12842 +}
12843 +
12844 +static int
12845 +oh_port_probe(struct platform_device *_of_dev)
12846 +{
12847 + struct device *dpa_oh_dev;
12848 + struct device_node *dpa_oh_node;
12849 + int lenp, _errno = 0, fq_idx, duple_idx;
12850 + int n_size, i, j, ret, duples_count;
12851 + struct platform_device *oh_of_dev;
12852 + struct device_node *oh_node, *bpool_node = NULL, *root_node;
12853 + struct device *oh_dev;
12854 + struct dpa_oh_config_s *oh_config = NULL;
12855 + const __be32 *oh_all_queues;
12856 + const __be32 *channel_ids;
12857 + const __be32 *oh_tx_queues;
12858 + uint32_t queues_count;
12859 + uint32_t crt_fqid_base;
12860 + uint32_t crt_fq_count;
12861 + bool frag_enabled = false;
12862 + struct fm_port_params oh_port_tx_params;
12863 + struct fm_port_pcd_param oh_port_pcd_params;
12864 + struct dpa_buffer_layout_s buf_layout;
12865 +
12866 + /* True if the current partition owns the OH port. */
12867 + bool init_oh_port;
12868 +
12869 + const struct of_device_id *match;
12870 + int crt_ext_pools_count;
12871 + u32 ext_pool_size;
12872 + u32 port_id;
12873 + u32 channel_id;
12874 +
12875 + int channel_ids_count;
12876 + int channel_idx;
12877 + struct fq_duple *fqd;
12878 + struct list_head *fq_list, *fq_list_tmp;
12879 +
12880 + const __be32 *bpool_cfg;
12881 + uint32_t bpid;
12882 +
12883 + memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
12884 + dpa_oh_dev = &_of_dev->dev;
12885 + dpa_oh_node = dpa_oh_dev->of_node;
12886 + BUG_ON(dpa_oh_node == NULL);
12887 +
12888 + match = of_match_device(oh_port_match_table, dpa_oh_dev);
12889 + if (!match)
12890 + return -EINVAL;
12891 +
12892 + dev_dbg(dpa_oh_dev, "Probing OH port...\n");
12893 +
12894 + /* Find the referenced OH node */
12895 + oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0);
12896 + if (oh_node == NULL) {
12897 + dev_err(dpa_oh_dev,
12898 + "Can't find OH node referenced from node %s\n",
12899 + dpa_oh_node->full_name);
12900 + return -EINVAL;
12901 + }
12902 + dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n",
12903 + match->compatible);
12904 +
12905 + _errno = of_property_read_u32(oh_node, "cell-index", &port_id);
12906 + if (_errno) {
12907 + dev_err(dpa_oh_dev, "No port id found in node %s\n",
12908 + dpa_oh_node->full_name);
12909 + goto return_kfree;
12910 + }
12911 +
12912 + _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id",
12913 + &channel_id);
12914 + if (_errno) {
12915 + dev_err(dpa_oh_dev, "No channel id found in node %s\n",
12916 + dpa_oh_node->full_name);
12917 + goto return_kfree;
12918 + }
12919 +
12920 + oh_of_dev = of_find_device_by_node(oh_node);
12921 + BUG_ON(oh_of_dev == NULL);
12922 + oh_dev = &oh_of_dev->dev;
12923 +
12924 + /* The OH port must be initialized exactly once.
12925 + * The following scenarios are of interest:
12926 + * - the node is Linux-private (will always initialize it);
12927 + * - the node is shared between two Linux partitions
12928 + * (only one of them will initialize it);
12929 + * - the node is shared between a Linux and a LWE partition
12930 + * (Linux will initialize it) - "fsl,dpa-oh-shared"
12931 + */
12932 +
12933 + /* Check if the current partition owns the OH port
12934 + * and ought to initialize it. It may be the case that we leave this
12935 + * to another (also Linux) partition.
12936 + */
12937 + init_oh_port = strcmp(match->compatible, "fsl,dpa-oh-shared");
12938 +
12939 + /* If we aren't the "owner" of the OH node, we're done here. */
12940 + if (!init_oh_port) {
12941 + dev_dbg(dpa_oh_dev,
12942 + "Not owning the shared OH port %s, will not initialize it.\n",
12943 + oh_node->full_name);
12944 + of_node_put(oh_node);
12945 + return 0;
12946 + }
12947 +
12948 + /* Allocate OH dev private data */
12949 + oh_config = devm_kzalloc(dpa_oh_dev, sizeof(*oh_config), GFP_KERNEL);
12950 + if (oh_config == NULL) {
12951 + dev_err(dpa_oh_dev,
12952 + "Can't allocate private data for OH node %s referenced from node %s!\n",
12953 + oh_node->full_name, dpa_oh_node->full_name);
12954 + _errno = -ENOMEM;
12955 + goto return_kfree;
12956 + }
12957 +
12958 + INIT_LIST_HEAD(&oh_config->fqs_ingress_list);
12959 + INIT_LIST_HEAD(&oh_config->fqs_egress_list);
12960 +
12961 + /* FQs that enter OH port */
12962 + lenp = 0;
12963 + oh_all_queues = of_get_property(dpa_oh_node,
12964 + "fsl,qman-frame-queues-ingress", &lenp);
12965 + if (lenp % (2 * sizeof(*oh_all_queues))) {
12966 + dev_warn(dpa_oh_dev,
12967 + "Wrong ingress queues format for OH node %s referenced from node %s!\n",
12968 + oh_node->full_name, dpa_oh_node->full_name);
12969 + /* just ignore the last unpaired value */
12970 + }
12971 +
12972 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
12973 + dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n",
12974 + duples_count);
12975 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
12976 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
12977 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
12978 +
12979 + fqd = devm_kzalloc(dpa_oh_dev,
12980 + sizeof(struct fq_duple), GFP_KERNEL);
12981 + if (!fqd) {
12982 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
12983 + oh_node->full_name,
12984 + dpa_oh_node->full_name);
12985 + _errno = -ENOMEM;
12986 + goto return_kfree;
12987 + }
12988 +
12989 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
12990 + crt_fq_count * sizeof(struct qman_fq),
12991 + GFP_KERNEL);
12992 + if (!fqd->fqs) {
12993 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
12994 + oh_node->full_name,
12995 + dpa_oh_node->full_name);
12996 + _errno = -ENOMEM;
12997 + goto return_kfree;
12998 + }
12999 +
13000 + for (j = 0; j < crt_fq_count; j++)
13001 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
13002 + fqd->fqs_count = crt_fq_count;
13003 + fqd->channel_id = (uint16_t)channel_id;
13004 + list_add(&fqd->fq_list, &oh_config->fqs_ingress_list);
13005 + }
13006 +
13007 + /* create the ingress queues */
13008 + list_for_each(fq_list, &oh_config->fqs_ingress_list) {
13009 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13010 +
13011 + for (j = 0; j < fqd->fqs_count; j++) {
13012 + ret = oh_fq_create(fqd->fqs + j,
13013 + (fqd->fqs + j)->fqid,
13014 + fqd->channel_id, 3);
13015 + if (ret != 0) {
13016 + dev_err(dpa_oh_dev, "Unable to create ingress frame queue %d for OH node %s referenced from node %s!\n",
13017 + (fqd->fqs + j)->fqid,
13018 + oh_node->full_name,
13019 + dpa_oh_node->full_name);
13020 + _errno = -EINVAL;
13021 + goto return_kfree;
13022 + }
13023 + }
13024 + }
13025 +
13026 + /* FQs that exit OH port */
13027 + lenp = 0;
13028 + oh_all_queues = of_get_property(dpa_oh_node,
13029 + "fsl,qman-frame-queues-egress", &lenp);
13030 + if (lenp % (2 * sizeof(*oh_all_queues))) {
13031 + dev_warn(dpa_oh_dev,
13032 + "Wrong egress queues format for OH node %s referenced from node %s!\n",
13033 + oh_node->full_name, dpa_oh_node->full_name);
13034 + /* just ignore the last unpaired value */
13035 + }
13036 +
13037 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
13038 + dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n",
13039 + duples_count);
13040 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
13041 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
13042 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
13043 +
13044 + fqd = devm_kzalloc(dpa_oh_dev,
13045 + sizeof(struct fq_duple), GFP_KERNEL);
13046 + if (!fqd) {
13047 + dev_err(dpa_oh_dev, "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
13048 + oh_node->full_name,
13049 + dpa_oh_node->full_name);
13050 + _errno = -ENOMEM;
13051 + goto return_kfree;
13052 + }
13053 +
13054 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
13055 + crt_fq_count * sizeof(struct qman_fq),
13056 + GFP_KERNEL);
13057 + if (!fqd->fqs) {
13058 + dev_err(dpa_oh_dev,
13059 + "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
13060 + oh_node->full_name,
13061 + dpa_oh_node->full_name);
13062 + _errno = -ENOMEM;
13063 + goto return_kfree;
13064 + }
13065 +
13066 + for (j = 0; j < crt_fq_count; j++)
13067 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
13068 + fqd->fqs_count = crt_fq_count;
13069 + /* channel ID is specified in another attribute */
13070 + fqd->channel_id = 0;
13071 + list_add_tail(&fqd->fq_list, &oh_config->fqs_egress_list);
13072 +
13073 + /* allocate the queue */
13074 +
13075 + }
13076 +
13077 + /* channel_ids for FQs that exit OH port */
13078 + lenp = 0;
13079 + channel_ids = of_get_property(dpa_oh_node,
13080 + "fsl,qman-channel-ids-egress", &lenp);
13081 +
13082 + channel_ids_count = lenp / (sizeof(*channel_ids));
13083 + if (channel_ids_count != duples_count) {
13084 + dev_warn(dpa_oh_dev,
13085 + "Not all egress queues have a channel id for OH node %s referenced from node %s!\n",
13086 + oh_node->full_name, dpa_oh_node->full_name);
13087 + /* just ignore the queues that do not have a Channel ID */
13088 + }
13089 +
13090 + channel_idx = 0;
13091 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13092 + if (channel_idx + 1 > channel_ids_count)
13093 + break;
13094 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13095 + fqd->channel_id =
13096 + (uint16_t)be32_to_cpu(channel_ids[channel_idx++]);
13097 + }
13098 +
13099 + /* create egress queues */
13100 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13101 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13102 +
13103 + if (fqd->channel_id == 0) {
13104 + /* missing channel id in dts */
13105 + continue;
13106 + }
13107 +
13108 + for (j = 0; j < fqd->fqs_count; j++) {
13109 + ret = oh_fq_create(fqd->fqs + j,
13110 + (fqd->fqs + j)->fqid,
13111 + fqd->channel_id, 3);
13112 + if (ret != 0) {
13113 + dev_err(dpa_oh_dev, "Unable to create egress frame queue %d for OH node %s referenced from node %s!\n",
13114 + (fqd->fqs + j)->fqid,
13115 + oh_node->full_name,
13116 + dpa_oh_node->full_name);
13117 + _errno = -EINVAL;
13118 + goto return_kfree;
13119 + }
13120 + }
13121 + }
13122 +
13123 + /* Read FQ ids/nums for the DPA OH node */
13124 + oh_all_queues = of_get_property(dpa_oh_node,
13125 + "fsl,qman-frame-queues-oh", &lenp);
13126 + if (oh_all_queues == NULL) {
13127 + dev_err(dpa_oh_dev,
13128 + "No frame queues have been defined for OH node %s referenced from node %s\n",
13129 + oh_node->full_name, dpa_oh_node->full_name);
13130 + _errno = -EINVAL;
13131 + goto return_kfree;
13132 + }
13133 +
13134 + /* Check that the OH error and default FQs are there */
13135 + BUG_ON(lenp % (2 * sizeof(*oh_all_queues)));
13136 + queues_count = lenp / (2 * sizeof(*oh_all_queues));
13137 + if (queues_count != 2) {
13138 + dev_err(dpa_oh_dev,
13139 + "Error and Default queues must be defined for OH node %s referenced from node %s\n",
13140 + oh_node->full_name, dpa_oh_node->full_name);
13141 + _errno = -EINVAL;
13142 + goto return_kfree;
13143 + }
13144 +
13145 + /* Read the FQIDs defined for this OH port */
13146 + dev_dbg(dpa_oh_dev, "Reading %d queues...\n", queues_count);
13147 + fq_idx = 0;
13148 +
13149 + /* Error FQID - must be present */
13150 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13151 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13152 + if (crt_fq_count != 1) {
13153 + dev_err(dpa_oh_dev,
13154 + "Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n",
13155 + oh_node->full_name, dpa_oh_node->full_name,
13156 + crt_fq_count);
13157 + _errno = -EINVAL;
13158 + goto return_kfree;
13159 + }
13160 + oh_config->error_fqid = crt_fqid_base;
13161 + dev_dbg(dpa_oh_dev, "Read Error FQID 0x%x for OH port %s.\n",
13162 + oh_config->error_fqid, oh_node->full_name);
13163 +
13164 + /* Default FQID - must be present */
13165 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13166 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13167 + if (crt_fq_count != 1) {
13168 + dev_err(dpa_oh_dev,
13169 + "Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n",
13170 + oh_node->full_name, dpa_oh_node->full_name,
13171 + crt_fq_count);
13172 + _errno = -EINVAL;
13173 + goto return_kfree;
13174 + }
13175 + oh_config->default_fqid = crt_fqid_base;
13176 + dev_dbg(dpa_oh_dev, "Read Default FQID 0x%x for OH port %s.\n",
13177 + oh_config->default_fqid, oh_node->full_name);
13178 +
13179 + /* TX FQID - presence is optional */
13180 + oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx",
13181 + &lenp);
13182 + if (oh_tx_queues == NULL) {
13183 + dev_dbg(dpa_oh_dev,
13184 + "No tx queues have been defined for OH node %s referenced from node %s\n",
13185 + oh_node->full_name, dpa_oh_node->full_name);
13186 + goto config_port;
13187 + }
13188 +
13189 + /* Check that queues-tx has only a base and a count defined */
13190 + BUG_ON(lenp % (2 * sizeof(*oh_tx_queues)));
13191 + queues_count = lenp / (2 * sizeof(*oh_tx_queues));
13192 + if (queues_count != 1) {
13193 + dev_err(dpa_oh_dev,
13194 + "TX queues must be defined in only one <base count> tuple for OH node %s referenced from node %s\n",
13195 + oh_node->full_name, dpa_oh_node->full_name);
13196 + _errno = -EINVAL;
13197 + goto return_kfree;
13198 + }
13199 +
13200 + fq_idx = 0;
13201 + crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]);
13202 + crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]);
13203 + oh_config->egress_cnt = crt_fq_count;
13204 +
13205 + /* Allocate TX queues */
13206 + dev_dbg(dpa_oh_dev, "Allocating %d queues for TX...\n", crt_fq_count);
13207 + oh_config->egress_fqs = devm_kzalloc(dpa_oh_dev,
13208 + crt_fq_count * sizeof(struct qman_fq), GFP_KERNEL);
13209 + if (oh_config->egress_fqs == NULL) {
13210 + dev_err(dpa_oh_dev,
13211 + "Can't allocate private data for TX queues for OH node %s referenced from node %s!\n",
13212 + oh_node->full_name, dpa_oh_node->full_name);
13213 + _errno = -ENOMEM;
13214 + goto return_kfree;
13215 + }
13216 +
13217 + /* Create TX queues */
13218 + for (i = 0; i < crt_fq_count; i++) {
13219 + ret = oh_fq_create(oh_config->egress_fqs + i,
13220 + crt_fqid_base + i, (uint16_t)channel_id, 3);
13221 + if (ret != 0) {
13222 + dev_err(dpa_oh_dev,
13223 + "Unable to create TX frame queue %d for OH node %s referenced from node %s!\n",
13224 + crt_fqid_base + i, oh_node->full_name,
13225 + dpa_oh_node->full_name);
13226 + _errno = -EINVAL;
13227 + goto return_kfree;
13228 + }
13229 + }
13230 +
13231 +config_port:
13232 + /* Get a handle to the fm_port so we can set
13233 + * its configuration params
13234 + */
13235 + oh_config->oh_port = fm_port_bind(oh_dev);
13236 + if (oh_config->oh_port == NULL) {
13237 + dev_err(dpa_oh_dev, "NULL drvdata from fm port dev %s!\n",
13238 + oh_node->full_name);
13239 + _errno = -EINVAL;
13240 + goto return_kfree;
13241 + }
13242 +
13243 + oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
13244 +
13245 + /* read the pool handlers */
13246 + crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node,
13247 + "fsl,bman-buffer-pools", NULL);
13248 + if (crt_ext_pools_count <= 0) {
13249 + dev_info(dpa_oh_dev,
13250 + "OH port %s has no buffer pool. Fragmentation will not be enabled\n",
13251 + oh_node->full_name);
13252 + goto init_port;
13253 + }
13254 +
13255 + /* used for reading ext_pool_size*/
13256 + root_node = of_find_node_by_path("/");
13257 + if (root_node == NULL) {
13258 + dev_err(dpa_oh_dev, "of_find_node_by_path(/) failed\n");
13259 + _errno = -EINVAL;
13260 + goto return_kfree;
13261 + }
13262 +
13263 + n_size = of_n_size_cells(root_node);
13264 + of_node_put(root_node);
13265 +
13266 + dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n",
13267 + crt_ext_pools_count);
13268 +
13269 + oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count;
13270 +
13271 + for (i = 0; i < crt_ext_pools_count; i++) {
13272 + bpool_node = of_parse_phandle(dpa_oh_node,
13273 + "fsl,bman-buffer-pools", i);
13274 + if (bpool_node == NULL) {
13275 + dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
13276 + _errno = -EINVAL;
13277 + goto return_kfree;
13278 + }
13279 +
13280 + _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid);
13281 + if (_errno) {
13282 + dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n");
13283 + _errno = -EINVAL;
13284 + goto return_kfree;
13285 + }
13286 +
13287 + oh_port_tx_params.pool_param[i].id = (uint8_t)bpid;
13288 + dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid);
13289 +
13290 + bpool_cfg = of_get_property(bpool_node,
13291 + "fsl,bpool-ethernet-cfg", &lenp);
13292 + if (bpool_cfg == NULL) {
13293 + dev_err(dpa_oh_dev, "Invalid Buffer pool config params\n");
13294 + _errno = -EINVAL;
13295 + goto return_kfree;
13296 + }
13297 +
13298 + ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
13299 + oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size;
13300 + dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
13301 + ext_pool_size);
13302 + of_node_put(bpool_node);
13303 +
13304 + }
13305 +
13306 + if (buf_layout.data_align != FRAG_DATA_ALIGN ||
13307 + buf_layout.manip_extra_space != FRAG_MANIP_SPACE)
13308 + goto init_port;
13309 +
13310 + frag_enabled = true;
13311 + dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
13312 + port_id);
13313 +
13314 +init_port:
13315 + of_node_put(oh_node);
13316 + /* Set Tx params */
13317 + dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params,
13318 + oh_config->error_fqid, oh_config->default_fqid, (&buf_layout),
13319 + frag_enabled);
13320 + /* Set PCD params */
13321 + oh_port_pcd_params.cba = oh_alloc_pcd_fqids;
13322 + oh_port_pcd_params.cbf = oh_free_pcd_fqids;
13323 + oh_port_pcd_params.dev = dpa_oh_dev;
13324 + fm_port_pcd_bind(oh_config->oh_port, &oh_port_pcd_params);
13325 +
13326 + dev_set_drvdata(dpa_oh_dev, oh_config);
13327 +
13328 + /* Enable the OH port */
13329 + _errno = fm_port_enable(oh_config->oh_port);
13330 + if (_errno)
13331 + goto return_kfree;
13332 +
13333 + dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name);
13334 +
13335 + /* print of all referenced & created queues */
13336 + dump_oh_config(dpa_oh_dev, oh_config);
13337 +
13338 + return 0;
13339 +
13340 +return_kfree:
13341 + if (bpool_node)
13342 + of_node_put(bpool_node);
13343 + if (oh_node)
13344 + of_node_put(oh_node);
13345 + if (oh_config && oh_config->egress_fqs)
13346 + devm_kfree(dpa_oh_dev, oh_config->egress_fqs);
13347 +
13348 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_ingress_list) {
13349 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13350 + list_del(fq_list);
13351 + devm_kfree(dpa_oh_dev, fqd->fqs);
13352 + devm_kfree(dpa_oh_dev, fqd);
13353 + }
13354 +
13355 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_egress_list) {
13356 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13357 + list_del(fq_list);
13358 + devm_kfree(dpa_oh_dev, fqd->fqs);
13359 + devm_kfree(dpa_oh_dev, fqd);
13360 + }
13361 +
13362 + devm_kfree(dpa_oh_dev, oh_config);
13363 + return _errno;
13364 +}
13365 +
13366 +static int __cold oh_port_remove(struct platform_device *_of_dev)
13367 +{
13368 + int _errno = 0, i;
13369 + struct dpa_oh_config_s *oh_config;
13370 +
13371 + pr_info("Removing OH port...\n");
13372 +
13373 + oh_config = dev_get_drvdata(&_of_dev->dev);
13374 + if (oh_config == NULL) {
13375 + pr_err(KBUILD_MODNAME
13376 + ": %s:%hu:%s(): No OH config in device private data!\n",
13377 + KBUILD_BASENAME".c", __LINE__, __func__);
13378 + _errno = -ENODEV;
13379 + goto return_error;
13380 + }
13381 +
13382 + if (oh_config->egress_fqs)
13383 + for (i = 0; i < oh_config->egress_cnt; i++)
13384 + oh_fq_destroy(oh_config->egress_fqs + i);
13385 +
13386 + if (oh_config->oh_port == NULL) {
13387 + pr_err(KBUILD_MODNAME
13388 + ": %s:%hu:%s(): No fm port in device private data!\n",
13389 + KBUILD_BASENAME".c", __LINE__, __func__);
13390 + _errno = -EINVAL;
13391 + goto free_egress_fqs;
13392 + }
13393 +
13394 + _errno = fm_port_disable(oh_config->oh_port);
13395 +
13396 +free_egress_fqs:
13397 + if (oh_config->egress_fqs)
13398 + devm_kfree(&_of_dev->dev, oh_config->egress_fqs);
13399 + devm_kfree(&_of_dev->dev, oh_config);
13400 + dev_set_drvdata(&_of_dev->dev, NULL);
13401 +
13402 +return_error:
13403 + return _errno;
13404 +}
13405 +
13406 +static struct platform_driver oh_port_driver = {
13407 + .driver = {
13408 + .name = KBUILD_MODNAME,
13409 + .of_match_table = oh_port_match_table,
13410 + .owner = THIS_MODULE,
13411 + .pm = OH_PM_OPS,
13412 + },
13413 + .probe = oh_port_probe,
13414 + .remove = oh_port_remove
13415 +};
13416 +
13417 +static int __init __cold oh_port_load(void)
13418 +{
13419 + int _errno;
13420 +
13421 + pr_info(OH_MOD_DESCRIPTION "\n");
13422 +
13423 + _errno = platform_driver_register(&oh_port_driver);
13424 + if (_errno < 0) {
13425 + pr_err(KBUILD_MODNAME
13426 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
13427 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
13428 + }
13429 +
13430 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13431 + KBUILD_BASENAME".c", __func__);
13432 + return _errno;
13433 +}
13434 +module_init(oh_port_load);
13435 +
13436 +static void __exit __cold oh_port_unload(void)
13437 +{
13438 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
13439 + KBUILD_BASENAME".c", __func__);
13440 +
13441 + platform_driver_unregister(&oh_port_driver);
13442 +
13443 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13444 + KBUILD_BASENAME".c", __func__);
13445 +}
13446 +module_exit(oh_port_unload);
13447 diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
13448 new file mode 100644
13449 index 00000000..432ee88d
13450 --- /dev/null
13451 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
13452 @@ -0,0 +1,59 @@
13453 +/* Copyright 2011 Freescale Semiconductor Inc.
13454 + *
13455 + * Redistribution and use in source and binary forms, with or without
13456 + * modification, are permitted provided that the following conditions are met:
13457 + * * Redistributions of source code must retain the above copyright
13458 + * notice, this list of conditions and the following disclaimer.
13459 + * * Redistributions in binary form must reproduce the above copyright
13460 + * notice, this list of conditions and the following disclaimer in the
13461 + * documentation and/or other materials provided with the distribution.
13462 + * * Neither the name of Freescale Semiconductor nor the
13463 + * names of its contributors may be used to endorse or promote products
13464 + * derived from this software without specific prior written permission.
13465 + *
13466 + *
13467 + * ALTERNATIVELY, this software may be distributed under the terms of the
13468 + * GNU General Public License ("GPL") as published by the Free Software
13469 + * Foundation, either version 2 of that License or (at your option) any
13470 + * later version.
13471 + *
13472 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13473 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13474 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13475 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13476 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13477 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13478 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13479 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13480 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13481 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13482 + */
13483 +
13484 +#ifndef __OFFLINE_PORT_H
13485 +#define __OFFLINE_PORT_H
13486 +
13487 +struct fm_port;
13488 +struct qman_fq;
13489 +
13490 +/* fqs are defined in duples (base_fq, fq_count) */
13491 +struct fq_duple {
13492 + struct qman_fq *fqs;
13493 + int fqs_count;
13494 + uint16_t channel_id;
13495 + struct list_head fq_list;
13496 +};
13497 +
13498 +/* OH port configuration */
13499 +struct dpa_oh_config_s {
13500 + uint32_t error_fqid;
13501 + uint32_t default_fqid;
13502 + struct fm_port *oh_port;
13503 + uint32_t egress_cnt;
13504 + struct qman_fq *egress_fqs;
13505 + uint16_t channel;
13506 +
13507 + struct list_head fqs_ingress_list;
13508 + struct list_head fqs_egress_list;
13509 +};
13510 +
13511 +#endif /* __OFFLINE_PORT_H */
13512 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Kconfig b/drivers/net/ethernet/freescale/sdk_fman/Kconfig
13513 new file mode 100644
13514 index 00000000..d98c0989
13515 --- /dev/null
13516 +++ b/drivers/net/ethernet/freescale/sdk_fman/Kconfig
13517 @@ -0,0 +1,153 @@
13518 +menu "Frame Manager support"
13519 +
13520 +menuconfig FSL_SDK_FMAN
13521 + bool "Freescale Frame Manager (datapath) support - SDK driver"
13522 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && !FSL_FMAN
13523 + default y
13524 + ---help---
13525 + If unsure, say Y.
13526 +
13527 +if FSL_SDK_FMAN
13528 +
13529 +config FSL_SDK_FMAN_TEST
13530 + bool "FMan test module"
13531 + default n
13532 + select FSL_DPAA_HOOKS
13533 + ---help---
13534 + This option compiles test code for FMan.
13535 +
13536 +menu "FMAN Processor support"
13537 +choice
13538 + depends on FSL_SDK_FMAN
13539 + prompt "Processor Type"
13540 +
13541 +config FMAN_ARM
13542 + bool "LS1043"
13543 + depends on ARM64 || ARM
13544 + ---help---
13545 + Choose "LS1043" for the ARM platforms:
13546 + LS1043
13547 +
13548 +config FMAN_P3040_P4080_P5020
13549 + bool "P3040 P4080 5020"
13550 +
13551 +config FMAN_P1023
13552 + bool "P1023"
13553 +
13554 +config FMAN_V3H
13555 + bool "FmanV3H"
13556 + ---help---
13557 + Choose "FmanV3H" for Fman rev3H:
13558 + B4860, T4240, T4160, etc
13559 +
13560 +config FMAN_V3L
13561 + bool "FmanV3L"
13562 + ---help---
13563 + Choose "FmanV3L" for Fman rev3L:
13564 + T1040, T1042, T1020, T1022, T1023, T1024, etc
13565 +
13566 +endchoice
13567 +endmenu
13568 +
13569 +config FMAN_MIB_CNT_OVF_IRQ_EN
13570 + bool "Enable the dTSEC MIB counters overflow interrupt"
13571 + default n
13572 + ---help---
13573 + Enable the dTSEC MIB counters overflow interrupt to get
13574 + accurate MIB counters values. Enabled it compensates
13575 + for the counters overflow but reduces performance and
13576 + triggers error messages in HV setups.
13577 +
13578 +config FSL_FM_MAX_FRAME_SIZE
13579 + int "Maximum L2 frame size"
13580 + depends on FSL_SDK_FMAN
13581 + range 64 9600
13582 + default "1522"
13583 + help
13584 + Configure this in relation to the maximum possible MTU of your
13585 + network configuration. In particular, one would need to
13586 + increase this value in order to use jumbo frames.
13587 + FSL_FM_MAX_FRAME_SIZE must accommodate the Ethernet FCS (4 bytes)
13588 + and one ETH+VLAN header (18 bytes), to a total of 22 bytes in
13589 + excess of the desired L3 MTU.
13590 +
13591 + Note that having too large a FSL_FM_MAX_FRAME_SIZE (much larger
13592 + than the actual MTU) may lead to buffer exhaustion, especially
13593 + in the case of badly fragmented datagrams on the Rx path.
13594 + Conversely, having a FSL_FM_MAX_FRAME_SIZE smaller than the actual
13595 + MTU will lead to frames being dropped.
13596 +
13597 + This can be overridden by specifying "fsl_fm_max_frm" in
13598 + the kernel bootargs:
13599 + * in Hypervisor-based scenarios, by adding a "chosen" node
13600 + with the "bootargs" property specifying
13601 + "fsl_fm_max_frm=<YourValue>";
13602 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13603 + modifying the "bootargs" env variable.
13604 +
13605 +config FSL_FM_RX_EXTRA_HEADROOM
13606 + int "Add extra headroom at beginning of data buffers"
13607 + depends on FSL_SDK_FMAN
13608 + range 16 384
13609 + default "64"
13610 + help
13611 + Configure this to tell the Frame Manager to reserve some extra
13612 + space at the beginning of a data buffer on the receive path,
13613 + before Internal Context fields are copied. This is in addition
13614 + to the private data area already reserved for driver internal
13615 + use. The provided value must be a multiple of 16.
13616 +
13617 + This setting can be overridden by specifying
13618 + "fsl_fm_rx_extra_headroom" in the kernel bootargs:
13619 + * in Hypervisor-based scenarios, by adding a "chosen" node
13620 + with the "bootargs" property specifying
13621 + "fsl_fm_rx_extra_headroom=<YourValue>";
13622 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13623 + modifying the "bootargs" env variable.
13624 +
13625 +config FMAN_PFC
13626 + bool "FMan PFC support (EXPERIMENTAL)"
13627 + depends on ( FMAN_V3H || FMAN_V3L || FMAN_ARM) && FSL_SDK_FMAN
13628 + default n
13629 + help
13630 + This option enables PFC support on FMan v3 ports.
13631 + Data Center Bridging defines Classes of Service that are
13632 + flow-controlled using PFC pause frames.
13633 +
13634 +if FMAN_PFC
13635 +config FMAN_PFC_COS_COUNT
13636 + int "Number of PFC Classes of Service"
13637 + depends on FMAN_PFC && FSL_SDK_FMAN
13638 + range 1 4
13639 + default "3"
13640 + help
13641 + The number of Classes of Service controlled by PFC.
13642 +
13643 +config FMAN_PFC_QUANTA_0
13644 + int "The pause quanta for PFC CoS 0"
13645 + depends on FMAN_PFC && FSL_SDK_FMAN
13646 + range 0 65535
13647 + default "65535"
13648 +
13649 +config FMAN_PFC_QUANTA_1
13650 + int "The pause quanta for PFC CoS 1"
13651 + depends on FMAN_PFC && FSL_SDK_FMAN
13652 + range 0 65535
13653 + default "65535"
13654 +
13655 +config FMAN_PFC_QUANTA_2
13656 + int "The pause quanta for PFC CoS 2"
13657 + depends on FMAN_PFC && FSL_SDK_FMAN
13658 + range 0 65535
13659 + default "65535"
13660 +
13661 +config FMAN_PFC_QUANTA_3
13662 + int "The pause quanta for PFC CoS 3"
13663 + depends on FMAN_PFC && FSL_SDK_FMAN
13664 + range 0 65535
13665 + default "65535"
13666 +endif
13667 +
13668 +endif # FSL_SDK_FMAN
13669 +
13670 +endmenu
13671 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Makefile
13672 new file mode 100644
13673 index 00000000..25ce7e6a
13674 --- /dev/null
13675 +++ b/drivers/net/ethernet/freescale/sdk_fman/Makefile
13676 @@ -0,0 +1,11 @@
13677 +#
13678 +# Makefile for the Freescale Ethernet controllers
13679 +#
13680 +ccflags-y += -DVERSION=\"\"
13681 +#
13682 +#Include netcomm SW specific definitions
13683 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13684 +#
13685 +obj-y += etc/
13686 +obj-y += Peripherals/FM/
13687 +obj-y += src/
13688 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
13689 new file mode 100644
13690 index 00000000..d0e76727
13691 --- /dev/null
13692 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
13693 @@ -0,0 +1,15 @@
13694 +#
13695 +# Makefile for the Freescale Ethernet controllers
13696 +#
13697 +ccflags-y += -DVERSION=\"\"
13698 +#
13699 +#Include netcomm SW specific definitions
13700 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13701 +
13702 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
13703 +
13704 +ccflags-y += -I$(NCSW_FM_INC)
13705 +
13706 +obj-y += fsl-ncsw-Hc.o
13707 +
13708 +fsl-ncsw-Hc-objs := hc.o
13709 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
13710 new file mode 100644
13711 index 00000000..363c8f95
13712 --- /dev/null
13713 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
13714 @@ -0,0 +1,1232 @@
13715 +/*
13716 + * Copyright 2008-2012 Freescale Semiconductor Inc.
13717 + *
13718 + * Redistribution and use in source and binary forms, with or without
13719 + * modification, are permitted provided that the following conditions are met:
13720 + * * Redistributions of source code must retain the above copyright
13721 + * notice, this list of conditions and the following disclaimer.
13722 + * * Redistributions in binary form must reproduce the above copyright
13723 + * notice, this list of conditions and the following disclaimer in the
13724 + * documentation and/or other materials provided with the distribution.
13725 + * * Neither the name of Freescale Semiconductor nor the
13726 + * names of its contributors may be used to endorse or promote products
13727 + * derived from this software without specific prior written permission.
13728 + *
13729 + *
13730 + * ALTERNATIVELY, this software may be distributed under the terms of the
13731 + * GNU General Public License ("GPL") as published by the Free Software
13732 + * Foundation, either version 2 of that License or (at your option) any
13733 + * later version.
13734 + *
13735 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13736 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13737 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13738 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13739 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13740 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13741 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13742 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13743 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13744 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13745 + */
13746 +
13747 +
13748 +#include "std_ext.h"
13749 +#include "error_ext.h"
13750 +#include "sprint_ext.h"
13751 +#include "string_ext.h"
13752 +
13753 +#include "fm_common.h"
13754 +#include "fm_hc.h"
13755 +
13756 +
13757 +/**************************************************************************//**
13758 + @Description defaults
13759 +*//***************************************************************************/
13760 +#define DEFAULT_dataMemId 0
13761 +
13762 +#define HC_HCOR_OPCODE_PLCR_PRFL 0x0
13763 +#define HC_HCOR_OPCODE_KG_SCM 0x1
13764 +#define HC_HCOR_OPCODE_SYNC 0x2
13765 +#define HC_HCOR_OPCODE_CC 0x3
13766 +#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4
13767 +#define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5
13768 +#define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10
13769 +#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11
13770 +#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13
13771 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24
13772 +#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24
13773 +#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000
13774 +#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000
13775 +#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000
13776 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24
13777 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000
13778 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16
13779 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF
13780 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24
13781 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16
13782 +
13783 +#define HC_HCOR_GBL 0x20000000
13784 +
13785 +#define HC_HCOR_KG_SCHEME_COUNTER 0x00000400
13786 +
13787 +#if (DPAA_VERSION == 10)
13788 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFF800
13789 +#else
13790 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFFE00
13791 +#endif /* (DPAA_VERSION == 10) */
13792 +
13793 +#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdKgPortRegs))
13794 +#define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame)
13795 +#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdPlcrProfileRegs))
13796 +#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrProfileRegs)+sizeof(uint32_t))
13797 +#define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16
13798 +
13799 +#define HC_CMD_POOL_SIZE (INTG_MAX_NUM_OF_CORES)
13800 +
13801 +#define BUILD_FD(len) \
13802 +do { \
13803 + memset(&fmFd, 0, sizeof(t_DpaaFD)); \
13804 + DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \
13805 + DPAA_FD_SET_OFFSET(&fmFd, 0); \
13806 + DPAA_FD_SET_LENGTH(&fmFd, len); \
13807 +} while (0)
13808 +
13809 +
13810 +#if defined(__MWERKS__) && !defined(__GNUC__)
13811 +#pragma pack(push,1)
13812 +#endif /* defined(__MWERKS__) && ... */
13813 +
13814 +typedef struct t_FmPcdKgPortRegs {
13815 + volatile uint32_t spReg;
13816 + volatile uint32_t cppReg;
13817 +} t_FmPcdKgPortRegs;
13818 +
13819 +typedef struct t_HcFrame {
13820 + volatile uint32_t opcode;
13821 + volatile uint32_t actionReg;
13822 + volatile uint32_t extraReg;
13823 + volatile uint32_t commandSequence;
13824 + union {
13825 + struct fman_kg_scheme_regs schemeRegs;
13826 + struct fman_kg_scheme_regs schemeRegsWithoutCounter;
13827 + t_FmPcdPlcrProfileRegs profileRegs;
13828 + volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */
13829 + t_FmPcdKgPortRegs portRegsForRead;
13830 + volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP];
13831 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout;
13832 + t_FmPcdCcReassmTimeoutParams ccReassmTimeout;
13833 + } hcSpecificData;
13834 +} t_HcFrame;
13835 +
13836 +#if defined(__MWERKS__) && !defined(__GNUC__)
13837 +#pragma pack(pop)
13838 +#endif /* defined(__MWERKS__) && ... */
13839 +
13840 +
13841 +typedef struct t_FmHc {
13842 + t_Handle h_FmPcd;
13843 + t_Handle h_HcPortDev;
13844 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */
13845 + t_Handle h_QmArg; /**< A handle to the QM module */
13846 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
13847 +
13848 + uint32_t seqNum[HC_CMD_POOL_SIZE]; /* FIFO of seqNum to use when
13849 + taking buffer */
13850 + uint32_t nextSeqNumLocation; /* seqNum location in seqNum[] for next buffer */
13851 + volatile bool enqueued[HC_CMD_POOL_SIZE]; /* HC is active - frame is enqueued
13852 + and not confirmed yet */
13853 + t_HcFrame *p_Frm[HC_CMD_POOL_SIZE];
13854 +} t_FmHc;
13855 +
13856 +
13857 +static t_Error FillBufPool(t_FmHc *p_FmHc)
13858 +{
13859 + uint32_t i;
13860 +
13861 + ASSERT_COND(p_FmHc);
13862 +
13863 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13864 + {
13865 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
13866 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + (16 - (sizeof(t_FmHc) % 16))),
13867 + p_FmHc->dataMemId,
13868 + 16);
13869 +#else
13870 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart(sizeof(t_HcFrame),
13871 + p_FmHc->dataMemId,
13872 + 16);
13873 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
13874 + if (!p_FmHc->p_Frm[i])
13875 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM HC frames!"));
13876 + }
13877 +
13878 + /* Initialize FIFO of seqNum to use during GetBuf */
13879 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13880 + {
13881 + p_FmHc->seqNum[i] = i;
13882 + }
13883 + p_FmHc->nextSeqNumLocation = 0;
13884 +
13885 + return E_OK;
13886 +}
13887 +
13888 +static __inline__ t_HcFrame * GetBuf(t_FmHc *p_FmHc, uint32_t *p_SeqNum)
13889 +{
13890 + uint32_t intFlags;
13891 +
13892 + ASSERT_COND(p_FmHc);
13893 +
13894 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13895 +
13896 + if (p_FmHc->nextSeqNumLocation == HC_CMD_POOL_SIZE)
13897 + {
13898 + /* No more buffers */
13899 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13900 + return NULL;
13901 + }
13902 +
13903 + *p_SeqNum = p_FmHc->seqNum[p_FmHc->nextSeqNumLocation];
13904 + p_FmHc->nextSeqNumLocation++;
13905 +
13906 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13907 + return p_FmHc->p_Frm[*p_SeqNum];
13908 +}
13909 +
13910 +static __inline__ void PutBuf(t_FmHc *p_FmHc, t_HcFrame *p_Buf, uint32_t seqNum)
13911 +{
13912 + uint32_t intFlags;
13913 +
13914 + UNUSED(p_Buf);
13915 +
13916 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13917 + ASSERT_COND(p_FmHc->nextSeqNumLocation);
13918 + p_FmHc->nextSeqNumLocation--;
13919 + p_FmHc->seqNum[p_FmHc->nextSeqNumLocation] = seqNum;
13920 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13921 +}
13922 +
13923 +static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, uint32_t seqNum)
13924 +{
13925 + t_Error err = E_OK;
13926 + uint32_t intFlags;
13927 + uint32_t timeout=100;
13928 +
13929 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13930 + ASSERT_COND(!p_FmHc->enqueued[seqNum]);
13931 + p_FmHc->enqueued[seqNum] = TRUE;
13932 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13933 + DBG(TRACE, ("Send Hc, SeqNum %d, buff@0x%x, fd offset 0x%x",
13934 + seqNum,
13935 + DPAA_FD_GET_ADDR(p_FmFd),
13936 + DPAA_FD_GET_OFFSET(p_FmFd)));
13937 + err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd);
13938 + if (err)
13939 + RETURN_ERROR(MINOR, err, ("HC enqueue failed"));
13940 +
13941 + while (p_FmHc->enqueued[seqNum] && --timeout)
13942 + XX_UDelay(100);
13943 +
13944 + if (!timeout)
13945 + RETURN_ERROR(MINOR, E_TIMEOUT, ("HC Callback, timeout exceeded"));
13946 +
13947 + return err;
13948 +}
13949 +
13950 +
13951 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams)
13952 +{
13953 + t_FmHc *p_FmHc;
13954 + t_FmPortParams fmPortParam;
13955 + t_Error err;
13956 +
13957 + p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc));
13958 + if (!p_FmHc)
13959 + {
13960 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC obj"));
13961 + return NULL;
13962 + }
13963 + memset(p_FmHc,0,sizeof(t_FmHc));
13964 +
13965 + p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd;
13966 + p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue;
13967 + p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg;
13968 + p_FmHc->dataMemId = DEFAULT_dataMemId;
13969 +
13970 + err = FillBufPool(p_FmHc);
13971 + if (err != E_OK)
13972 + {
13973 + REPORT_ERROR(MAJOR, err, NO_MSG);
13974 + FmHcFree(p_FmHc);
13975 + return NULL;
13976 + }
13977 +
13978 + if (!FmIsMaster(p_FmHcParams->h_Fm))
13979 + return (t_Handle)p_FmHc;
13980 +
13981 + memset(&fmPortParam, 0, sizeof(fmPortParam));
13982 + fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr;
13983 + fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND;
13984 + fmPortParam.portId = p_FmHcParams->params.portId;
13985 + fmPortParam.liodnBase = p_FmHcParams->params.liodnBase;
13986 + fmPortParam.h_Fm = p_FmHcParams->h_Fm;
13987 +
13988 + fmPortParam.specificParams.nonRxParams.errFqid = p_FmHcParams->params.errFqid;
13989 + fmPortParam.specificParams.nonRxParams.dfltFqid = p_FmHcParams->params.confFqid;
13990 + fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel;
13991 +
13992 + p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam);
13993 + if (!p_FmHc->h_HcPortDev)
13994 + {
13995 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!"));
13996 + XX_Free(p_FmHc);
13997 + return NULL;
13998 + }
13999 +
14000 + err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev,
14001 + (uint16_t)sizeof(t_HcFrame));
14002 +
14003 + if (err != E_OK)
14004 + {
14005 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
14006 + FmHcFree(p_FmHc);
14007 + return NULL;
14008 + }
14009 +
14010 + /* final init */
14011 + err = FM_PORT_Init(p_FmHc->h_HcPortDev);
14012 + if (err != E_OK)
14013 + {
14014 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
14015 + FmHcFree(p_FmHc);
14016 + return NULL;
14017 + }
14018 +
14019 + err = FM_PORT_Enable(p_FmHc->h_HcPortDev);
14020 + if (err != E_OK)
14021 + {
14022 + REPORT_ERROR(MAJOR, err, ("FM HC port enable!"));
14023 + FmHcFree(p_FmHc);
14024 + return NULL;
14025 + }
14026 +
14027 + return (t_Handle)p_FmHc;
14028 +}
14029 +
14030 +void FmHcFree(t_Handle h_FmHc)
14031 +{
14032 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14033 + int i;
14034 +
14035 + if (!p_FmHc)
14036 + return;
14037 +
14038 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
14039 + if (p_FmHc->p_Frm[i])
14040 + XX_FreeSmart(p_FmHc->p_Frm[i]);
14041 + else
14042 + break;
14043 +
14044 + if (p_FmHc->h_HcPortDev)
14045 + FM_PORT_Free(p_FmHc->h_HcPortDev);
14046 +
14047 + XX_Free(p_FmHc);
14048 +}
14049 +
14050 +/*****************************************************************************/
14051 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
14052 + uint8_t memId)
14053 +{
14054 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14055 + int i;
14056 +
14057 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
14058 +
14059 + p_FmHc->dataMemId = memId;
14060 +
14061 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
14062 + if (p_FmHc->p_Frm[i])
14063 + XX_FreeSmart(p_FmHc->p_Frm[i]);
14064 +
14065 + return FillBufPool(p_FmHc);
14066 +}
14067 +
14068 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd)
14069 +{
14070 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14071 + t_HcFrame *p_HcFrame;
14072 + uint32_t intFlags;
14073 +
14074 + ASSERT_COND(p_FmHc);
14075 +
14076 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
14077 + p_HcFrame = (t_HcFrame *)PTR_MOVE(DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd));
14078 +
14079 + DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x",
14080 + p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd)));
14081 +
14082 + if (!(p_FmHc->enqueued[p_HcFrame->commandSequence]))
14083 + REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!"));
14084 + else
14085 + p_FmHc->enqueued[p_HcFrame->commandSequence] = FALSE;
14086 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
14087 +}
14088 +
14089 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
14090 + t_Handle h_Scheme,
14091 + struct fman_kg_scheme_regs *p_SchemeRegs,
14092 + bool updateCounter)
14093 +{
14094 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14095 + t_Error err = E_OK;
14096 + t_HcFrame *p_HcFrame;
14097 + t_DpaaFD fmFd;
14098 + uint8_t physicalSchemeId;
14099 + uint32_t seqNum;
14100 +
14101 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14102 + if (!p_HcFrame)
14103 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14104 +
14105 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14106 +
14107 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14108 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14109 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, updateCounter);
14110 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14111 + memcpy(&p_HcFrame->hcSpecificData.schemeRegs, p_SchemeRegs, sizeof(struct fman_kg_scheme_regs));
14112 + if (!updateCounter)
14113 + {
14114 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = p_SchemeRegs->kgse_dv0;
14115 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = p_SchemeRegs->kgse_dv1;
14116 + p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = p_SchemeRegs->kgse_ccbs;
14117 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = p_SchemeRegs->kgse_mv;
14118 + }
14119 + p_HcFrame->commandSequence = seqNum;
14120 +
14121 + BUILD_FD(sizeof(t_HcFrame));
14122 +
14123 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14124 +
14125 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14126 +
14127 + if (err != E_OK)
14128 + RETURN_ERROR(MINOR, err, NO_MSG);
14129 +
14130 + return E_OK;
14131 +}
14132 +
14133 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme)
14134 +{
14135 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14136 + t_Error err = E_OK;
14137 + t_HcFrame *p_HcFrame;
14138 + t_DpaaFD fmFd;
14139 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14140 + uint32_t seqNum;
14141 +
14142 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14143 + if (!p_HcFrame)
14144 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14145 +
14146 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14147 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14148 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14149 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14150 + memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
14151 + p_HcFrame->commandSequence = seqNum;
14152 +
14153 + BUILD_FD(sizeof(t_HcFrame));
14154 +
14155 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14156 +
14157 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14158 +
14159 + if (err != E_OK)
14160 + RETURN_ERROR(MINOR, err, NO_MSG);
14161 +
14162 + return E_OK;
14163 +}
14164 +
14165 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
14166 +{
14167 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14168 + t_Error err = E_OK;
14169 + t_HcFrame *p_HcFrame;
14170 + t_DpaaFD fmFd;
14171 + uint8_t relativeSchemeId;
14172 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14173 + uint32_t tmpReg32 = 0;
14174 + uint32_t seqNum;
14175 +
14176 + /* Scheme is locked by calling routine */
14177 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14178 + * "kgse_mode" or "kgse_om" without locking scheme !
14179 + */
14180 +
14181 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14182 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14183 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14184 +
14185 + if (!FmPcdKgGetRequiredActionFlag(p_FmHc->h_FmPcd, relativeSchemeId) ||
14186 + !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction))
14187 + {
14188 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14189 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR))
14190 + {
14191 + if ((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) ||
14192 + (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE))
14193 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
14194 + err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction);
14195 + if (err)
14196 + RETURN_ERROR(MAJOR, err, NO_MSG);
14197 + }
14198 + else /* From here we deal with KG-Schemes only */
14199 + {
14200 + /* Pre change general code */
14201 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14202 + if (!p_HcFrame)
14203 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14204 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14205 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14206 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14207 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14208 + p_HcFrame->commandSequence = seqNum;
14209 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14210 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14211 + {
14212 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14213 + RETURN_ERROR(MINOR, err, NO_MSG);
14214 + }
14215 +
14216 + /* specific change */
14217 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14218 + ((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) &&
14219 + (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME)))
14220 + {
14221 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14222 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
14223 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14224 + }
14225 +
14226 + if ((requiredAction & UPDATE_KG_NIA_CC_WA) &&
14227 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_CC))
14228 + {
14229 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14230 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
14231 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
14232 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_FM_CTL_AC_PRE_CC;
14233 + }
14234 +
14235 + if (requiredAction & UPDATE_KG_OPT_MODE)
14236 + p_HcFrame->hcSpecificData.schemeRegs.kgse_om = value;
14237 +
14238 + if (requiredAction & UPDATE_KG_NIA)
14239 + {
14240 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14241 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
14242 + tmpReg32 |= value;
14243 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32;
14244 + }
14245 +
14246 + /* Post change general code */
14247 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14248 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
14249 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14250 +
14251 + BUILD_FD(sizeof(t_HcFrame));
14252 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14253 +
14254 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14255 +
14256 + if (err != E_OK)
14257 + RETURN_ERROR(MINOR, err, NO_MSG);
14258 + }
14259 + }
14260 +
14261 + return E_OK;
14262 +}
14263 +
14264 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme)
14265 +{
14266 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14267 + t_Error err;
14268 + t_HcFrame *p_HcFrame;
14269 + t_DpaaFD fmFd;
14270 + uint32_t retVal;
14271 + uint8_t relativeSchemeId;
14272 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14273 + uint32_t seqNum;
14274 +
14275 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14276 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14277 + {
14278 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14279 + return 0;
14280 + }
14281 +
14282 + /* first read scheme and check that it is valid */
14283 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14284 + if (!p_HcFrame)
14285 + {
14286 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14287 + return 0;
14288 + }
14289 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14290 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14291 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14292 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14293 + p_HcFrame->commandSequence = seqNum;
14294 +
14295 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14296 +
14297 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14298 + if (err != E_OK)
14299 + {
14300 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14301 + REPORT_ERROR(MINOR, err, NO_MSG);
14302 + return 0;
14303 + }
14304 +
14305 + if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
14306 + {
14307 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14308 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid"));
14309 + return 0;
14310 + }
14311 +
14312 + retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc;
14313 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14314 +
14315 + return retVal;
14316 +}
14317 +
14318 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value)
14319 +{
14320 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14321 + t_Error err = E_OK;
14322 + t_HcFrame *p_HcFrame;
14323 + t_DpaaFD fmFd;
14324 + uint8_t relativeSchemeId, physicalSchemeId;
14325 + uint32_t seqNum;
14326 +
14327 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14328 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14329 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14330 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14331 +
14332 + /* first read scheme and check that it is valid */
14333 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14334 + if (!p_HcFrame)
14335 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14336 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14337 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14338 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14339 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_COUNTER;
14340 + /* write counter */
14341 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14342 + p_HcFrame->commandSequence = seqNum;
14343 +
14344 + BUILD_FD(sizeof(t_HcFrame));
14345 +
14346 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14347 +
14348 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14349 + return err;
14350 +}
14351 +
14352 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set)
14353 +{
14354 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14355 + t_HcFrame *p_HcFrame;
14356 + t_DpaaFD fmFd;
14357 + uint8_t i, idx;
14358 + uint32_t seqNum;
14359 + t_Error err = E_OK;
14360 +
14361 + ASSERT_COND(p_FmHc);
14362 +
14363 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14364 + if (!p_HcFrame)
14365 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14366 +
14367 + for (i = p_Set->baseEntry; i < (p_Set->baseEntry+p_Set->numOfClsPlanEntries); i+=8)
14368 + {
14369 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14370 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14371 + p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
14372 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14373 +
14374 + idx = (uint8_t)(i - p_Set->baseEntry);
14375 + ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS);
14376 + memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t));
14377 + p_HcFrame->commandSequence = seqNum;
14378 +
14379 + BUILD_FD(sizeof(t_HcFrame));
14380 +
14381 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14382 + {
14383 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14384 + RETURN_ERROR(MINOR, err, NO_MSG);
14385 + }
14386 + }
14387 +
14388 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14389 + return err;
14390 +}
14391 +
14392 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId)
14393 +{
14394 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14395 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
14396 +
14397 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
14398 + if (!p_ClsPlanSet)
14399 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
14400 +
14401 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
14402 +
14403 + p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId);
14404 + p_ClsPlanSet->numOfClsPlanEntries = FmPcdKgGetClsPlanGrpSize(p_FmHc->h_FmPcd, grpId);
14405 + ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS);
14406 +
14407 + if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK)
14408 + {
14409 + XX_Free(p_ClsPlanSet);
14410 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
14411 + }
14412 +
14413 + XX_Free(p_ClsPlanSet);
14414 + FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId);
14415 +
14416 + return E_OK;
14417 +}
14418 +
14419 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams )
14420 +{
14421 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14422 + t_HcFrame *p_HcFrame;
14423 + t_DpaaFD fmFd;
14424 + t_Error err;
14425 + uint32_t seqNum;
14426 +
14427 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14428 +
14429 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14430 + if (!p_HcFrame)
14431 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14432 +
14433 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14434 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT);
14435 + memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams));
14436 + p_HcFrame->commandSequence = seqNum;
14437 + BUILD_FD(sizeof(t_HcFrame));
14438 +
14439 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14440 +
14441 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14442 + return err;
14443 +}
14444 +
14445 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams)
14446 +{
14447 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14448 + t_HcFrame *p_HcFrame;
14449 + t_DpaaFD fmFd;
14450 + t_Error err;
14451 + uint32_t seqNum;
14452 +
14453 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14454 +
14455 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14456 + if (!p_HcFrame)
14457 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14458 +
14459 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14460 +
14461 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION);
14462 + p_HcFrame->actionReg = (uint32_t)(((fill == TRUE) ? 0 : 1) << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT);
14463 + p_HcFrame->actionReg |= p_FmPcdCcFragScratchPoolCmdParams->bufferPoolId << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID;
14464 + if (fill == TRUE)
14465 + {
14466 + p_HcFrame->extraReg = p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers;
14467 + }
14468 + p_HcFrame->commandSequence = seqNum;
14469 +
14470 + BUILD_FD(sizeof(t_HcFrame));
14471 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14472 + {
14473 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14474 + RETURN_ERROR(MINOR, err, NO_MSG);
14475 + }
14476 +
14477 + p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers = p_HcFrame->extraReg;
14478 +
14479 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14480 + return E_OK;
14481 +}
14482 +
14483 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result)
14484 +{
14485 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14486 + t_HcFrame *p_HcFrame;
14487 + t_DpaaFD fmFd;
14488 + t_Error err;
14489 + uint32_t seqNum;
14490 +
14491 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14492 +
14493 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14494 + if (!p_HcFrame)
14495 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14496 +
14497 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14498 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_REASSM_TIMEOUT);
14499 + p_HcFrame->actionReg = (uint32_t)((p_CcReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT);
14500 + p_HcFrame->extraReg = (p_CcReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcReassmTimeoutParams->iprcpt;
14501 + p_HcFrame->commandSequence = seqNum;
14502 +
14503 + BUILD_FD(sizeof(t_HcFrame));
14504 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14505 + {
14506 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14507 + RETURN_ERROR(MINOR, err, NO_MSG);
14508 + }
14509 +
14510 + *p_Result = (uint8_t)
14511 + ((p_HcFrame->actionReg >> HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK);
14512 +
14513 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14514 + return E_OK;
14515 +}
14516 +
14517 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction)
14518 +{
14519 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14520 + t_HcFrame *p_HcFrame;
14521 + t_DpaaFD fmFd;
14522 + t_Error err;
14523 + uint32_t tmpReg32 = 0;
14524 + uint32_t requiredActionTmp, requiredActionFlag;
14525 + uint32_t seqNum;
14526 +
14527 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14528 +
14529 + /* Profile is locked by calling routine */
14530 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14531 + * "fmpl_pegnia" "fmpl_peynia" or "fmpl_pernia" without locking Profile !
14532 + */
14533 +
14534 + requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId);
14535 + requiredActionFlag = FmPcdPlcrGetRequiredActionFlag(p_FmHc->h_FmPcd, absoluteProfileId);
14536 +
14537 + if (!requiredActionFlag || !(requiredActionTmp & requiredAction))
14538 + {
14539 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
14540 + {
14541 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14542 + if (!p_HcFrame)
14543 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14544 + /* first read scheme and check that it is valid */
14545 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14546 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14547 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14548 + p_HcFrame->extraReg = 0x00008000;
14549 + p_HcFrame->commandSequence = seqNum;
14550 +
14551 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14552 +
14553 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14554 + {
14555 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14556 + RETURN_ERROR(MINOR, err, NO_MSG);
14557 + }
14558 +
14559 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia;
14560 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14561 + {
14562 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14563 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
14564 + ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14565 + }
14566 +
14567 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14568 +
14569 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14570 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14571 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(TRUE, FALSE, FALSE);
14572 + p_HcFrame->extraReg = 0x00008000;
14573 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14574 +
14575 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14576 +
14577 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14578 + {
14579 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14580 + RETURN_ERROR(MINOR, err, NO_MSG);
14581 + }
14582 +
14583 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia;
14584 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14585 + {
14586 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14587 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14588 + }
14589 +
14590 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14591 +
14592 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14593 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14594 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, TRUE, FALSE);
14595 + p_HcFrame->extraReg = 0x00008000;
14596 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14597 +
14598 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14599 +
14600 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14601 + {
14602 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14603 + RETURN_ERROR(MINOR, err, NO_MSG);
14604 + }
14605 +
14606 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia;
14607 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14608 + {
14609 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14610 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14611 + }
14612 +
14613 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14614 +
14615 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14616 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14617 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, FALSE, TRUE);
14618 + p_HcFrame->extraReg = 0x00008000;
14619 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14620 +
14621 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14622 +
14623 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14624 + {
14625 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14626 + RETURN_ERROR(MINOR, err, NO_MSG);
14627 + }
14628 +
14629 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14630 + }
14631 + }
14632 +
14633 + return E_OK;
14634 +}
14635 +
14636 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs)
14637 +{
14638 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14639 + t_Error err = E_OK;
14640 + uint16_t profileIndx;
14641 + t_HcFrame *p_HcFrame;
14642 + t_DpaaFD fmFd;
14643 + uint32_t seqNum;
14644 +
14645 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14646 + if (!p_HcFrame)
14647 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14648 +
14649 + profileIndx = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14650 +
14651 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14652 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14653 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
14654 + p_HcFrame->extraReg = 0x00008000;
14655 + memcpy(&p_HcFrame->hcSpecificData.profileRegs, p_PlcrRegs, sizeof(t_FmPcdPlcrProfileRegs));
14656 + p_HcFrame->commandSequence = seqNum;
14657 +
14658 + BUILD_FD(sizeof(t_HcFrame));
14659 +
14660 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14661 +
14662 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14663 +
14664 + if (err != E_OK)
14665 + RETURN_ERROR(MINOR, err, NO_MSG);
14666 +
14667 + return E_OK;
14668 +}
14669 +
14670 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile)
14671 +{
14672 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14673 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14674 + t_Error err = E_OK;
14675 + t_HcFrame *p_HcFrame;
14676 + t_DpaaFD fmFd;
14677 + uint32_t seqNum;
14678 +
14679 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14680 + if (!p_HcFrame)
14681 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14682 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14683 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14684 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14685 + p_HcFrame->actionReg |= 0x00008000;
14686 + p_HcFrame->extraReg = 0x00008000;
14687 + memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrProfileRegs));
14688 + p_HcFrame->commandSequence = seqNum;
14689 +
14690 + BUILD_FD(sizeof(t_HcFrame));
14691 +
14692 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14693 +
14694 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14695 +
14696 + if (err != E_OK)
14697 + RETURN_ERROR(MINOR, err, NO_MSG);
14698 +
14699 + return E_OK;
14700 +}
14701 +
14702 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
14703 +{
14704 +
14705 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14706 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14707 + t_Error err = E_OK;
14708 + t_HcFrame *p_HcFrame;
14709 + t_DpaaFD fmFd;
14710 + uint32_t seqNum;
14711 +
14712 + /* first read scheme and check that it is valid */
14713 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14714 + if (!p_HcFrame)
14715 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14716 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14717 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14718 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14719 + p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter);
14720 + p_HcFrame->extraReg = 0x00008000;
14721 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14722 + p_HcFrame->commandSequence = seqNum;
14723 +
14724 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14725 +
14726 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14727 +
14728 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14729 +
14730 + if (err != E_OK)
14731 + RETURN_ERROR(MINOR, err, NO_MSG);
14732 +
14733 + return E_OK;
14734 +}
14735 +
14736 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
14737 +{
14738 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14739 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14740 + t_Error err;
14741 + t_HcFrame *p_HcFrame;
14742 + t_DpaaFD fmFd;
14743 + uint32_t retVal = 0;
14744 + uint32_t seqNum;
14745 +
14746 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14747 +
14748 + /* first read scheme and check that it is valid */
14749 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14750 + if (!p_HcFrame)
14751 + {
14752 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14753 + return 0;
14754 + }
14755 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14756 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14757 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14758 + p_HcFrame->extraReg = 0x00008000;
14759 + p_HcFrame->commandSequence = seqNum;
14760 +
14761 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14762 +
14763 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14764 + if (err != E_OK)
14765 + {
14766 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14767 + REPORT_ERROR(MINOR, err, NO_MSG);
14768 + return 0;
14769 + }
14770 +
14771 + switch (counter)
14772 + {
14773 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
14774 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegpc;
14775 + break;
14776 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
14777 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_peypc;
14778 + break;
14779 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
14780 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perpc;
14781 + break;
14782 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
14783 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perypc;
14784 + break;
14785 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
14786 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perrpc;
14787 + break;
14788 + default:
14789 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
14790 + }
14791 +
14792 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14793 + return retVal;
14794 +}
14795 +
14796 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add)
14797 +{
14798 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14799 + t_HcFrame *p_HcFrame;
14800 + t_DpaaFD fmFd;
14801 + t_Error err = E_OK;
14802 + uint32_t seqNum;
14803 +
14804 + ASSERT_COND(p_FmHc);
14805 +
14806 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14807 + if (!p_HcFrame)
14808 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14809 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14810 + /* first read SP register */
14811 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14812 + p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
14813 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14814 + p_HcFrame->commandSequence = seqNum;
14815 +
14816 + BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS);
14817 +
14818 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14819 + {
14820 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14821 + RETURN_ERROR(MINOR, err, NO_MSG);
14822 + }
14823 +
14824 + /* spReg is the first reg, so we can use it both for read and for write */
14825 + if (add)
14826 + p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg;
14827 + else
14828 + p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg;
14829 +
14830 + p_HcFrame->actionReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
14831 +
14832 + BUILD_FD(sizeof(t_HcFrame));
14833 +
14834 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14835 +
14836 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14837 +
14838 + if (err != E_OK)
14839 + RETURN_ERROR(MINOR, err, NO_MSG);
14840 +
14841 + return E_OK;
14842 +}
14843 +
14844 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg)
14845 +{
14846 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14847 + t_HcFrame *p_HcFrame;
14848 + t_DpaaFD fmFd;
14849 + t_Error err = E_OK;
14850 + uint32_t seqNum;
14851 +
14852 + ASSERT_COND(p_FmHc);
14853 +
14854 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14855 + if (!p_HcFrame)
14856 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14857 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14858 + /* first read SP register */
14859 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14860 + p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
14861 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14862 + p_HcFrame->hcSpecificData.singleRegForWrite = cppReg;
14863 + p_HcFrame->commandSequence = seqNum;
14864 +
14865 + BUILD_FD(sizeof(t_HcFrame));
14866 +
14867 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14868 +
14869 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14870 +
14871 + if (err != E_OK)
14872 + RETURN_ERROR(MINOR, err, NO_MSG);
14873 +
14874 + return E_OK;
14875 +}
14876 +
14877 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset)
14878 +{
14879 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14880 + t_HcFrame *p_HcFrame;
14881 + t_DpaaFD fmFd;
14882 + t_Error err = E_OK;
14883 + uint32_t seqNum;
14884 +
14885 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
14886 +
14887 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14888 + if (!p_HcFrame)
14889 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14890 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14891 +
14892 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC);
14893 + p_HcFrame->actionReg = newAdAddrOffset;
14894 + p_HcFrame->actionReg |= 0xc0000000;
14895 + p_HcFrame->extraReg = oldAdAddrOffset;
14896 + p_HcFrame->commandSequence = seqNum;
14897 +
14898 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14899 +
14900 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14901 +
14902 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14903 +
14904 + if (err != E_OK)
14905 + RETURN_ERROR(MAJOR, err, NO_MSG);
14906 +
14907 + return E_OK;
14908 +}
14909 +
14910 +t_Error FmHcPcdSync(t_Handle h_FmHc)
14911 +{
14912 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14913 + t_HcFrame *p_HcFrame;
14914 + t_DpaaFD fmFd;
14915 + t_Error err = E_OK;
14916 + uint32_t seqNum;
14917 +
14918 + ASSERT_COND(p_FmHc);
14919 +
14920 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14921 + if (!p_HcFrame)
14922 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14923 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14924 + /* first read SP register */
14925 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_SYNC);
14926 + p_HcFrame->actionReg = 0;
14927 + p_HcFrame->extraReg = 0;
14928 + p_HcFrame->commandSequence = seqNum;
14929 +
14930 + BUILD_FD(sizeof(t_HcFrame));
14931 +
14932 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14933 +
14934 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14935 +
14936 + if (err != E_OK)
14937 + RETURN_ERROR(MINOR, err, NO_MSG);
14938 +
14939 + return E_OK;
14940 +}
14941 +
14942 +t_Handle FmHcGetPort(t_Handle h_FmHc)
14943 +{
14944 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14945 + return p_FmHc->h_HcPortDev;
14946 +}
14947 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
14948 new file mode 100644
14949 index 00000000..f6b090da
14950 --- /dev/null
14951 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
14952 @@ -0,0 +1,28 @@
14953 +#
14954 +# Makefile for the Freescale Ethernet controllers
14955 +#
14956 +ccflags-y += -DVERSION=\"\"
14957 +#
14958 +#Include netcomm SW specific definitions
14959 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
14960 +
14961 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
14962 +
14963 +ccflags-y += -I$(NCSW_FM_INC)
14964 +
14965 +obj-y += fsl-ncsw-MAC.o
14966 +
14967 +fsl-ncsw-MAC-objs := dtsec.o dtsec_mii_acc.o fm_mac.o tgec.o tgec_mii_acc.o \
14968 + fman_dtsec.o fman_dtsec_mii_acc.o fman_memac.o \
14969 + fman_tgec.o fman_crc32.o
14970 +
14971 +ifeq ($(CONFIG_FMAN_V3H),y)
14972 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14973 +endif
14974 +ifeq ($(CONFIG_FMAN_V3L),y)
14975 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14976 +endif
14977 +ifeq ($(CONFIG_FMAN_ARM),y)
14978 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14979 +endif
14980 +
14981 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
14982 new file mode 100644
14983 index 00000000..38948f97
14984 --- /dev/null
14985 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
14986 @@ -0,0 +1,1465 @@
14987 +/*
14988 + * Copyright 2008-2013 Freescale Semiconductor Inc.
14989 + *
14990 + * Redistribution and use in source and binary forms, with or without
14991 + * modification, are permitted provided that the following conditions are met:
14992 + * * Redistributions of source code must retain the above copyright
14993 + * notice, this list of conditions and the following disclaimer.
14994 + * * Redistributions in binary form must reproduce the above copyright
14995 + * notice, this list of conditions and the following disclaimer in the
14996 + * documentation and/or other materials provided with the distribution.
14997 + * * Neither the name of Freescale Semiconductor nor the
14998 + * names of its contributors may be used to endorse or promote products
14999 + * derived from this software without specific prior written permission.
15000 + *
15001 + *
15002 + * ALTERNATIVELY, this software may be distributed under the terms of the
15003 + * GNU General Public License ("GPL") as published by the Free Software
15004 + * Foundation, either version 2 of that License or (at your option) any
15005 + * later version.
15006 + *
15007 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
15008 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15009 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15010 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
15011 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15012 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
15013 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
15014 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15015 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15016 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15017 + */
15018 +
15019 +/******************************************************************************
15020 + @File dtsec.c
15021 +
15022 + @Description FMan dTSEC driver
15023 +*//***************************************************************************/
15024 +
15025 +#include "std_ext.h"
15026 +#include "error_ext.h"
15027 +#include "string_ext.h"
15028 +#include "xx_ext.h"
15029 +#include "endian_ext.h"
15030 +#include "debug_ext.h"
15031 +#include "crc_mac_addr_ext.h"
15032 +
15033 +#include "fm_common.h"
15034 +#include "dtsec.h"
15035 +#include "fsl_fman_dtsec.h"
15036 +#include "fsl_fman_dtsec_mii_acc.h"
15037 +
15038 +/*****************************************************************************/
15039 +/* Internal routines */
15040 +/*****************************************************************************/
15041 +
15042 +static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
15043 +{
15044 + if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
15045 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
15046 + if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
15047 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
15048 + if (p_Dtsec->addr == 0)
15049 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
15050 + if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) &&
15051 + p_Dtsec->p_DtsecDriverParam->halfdup_on)
15052 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
15053 + if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback)
15054 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
15055 +#ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001
15056 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */
15057 + if (p_Dtsec->p_DtsecDriverParam->rx_preamble)
15058 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
15059 +#endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */
15060 + if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7))
15061 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
15062 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on &&
15063 + (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en))
15064 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
15065 + if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc )
15066 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
15067 + if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend > MAX_PACKET_ALIGNMENT)
15068 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
15069 + if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1 > MAX_INTER_PACKET_GAP) ||
15070 + ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) ||
15071 + ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP))
15072 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
15073 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB)
15074 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
15075 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION)
15076 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
15077 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW)
15078 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
15079 +
15080 + /* If Auto negotiation process is disabled, need to */
15081 + /* Set up the PHY using the MII Management Interface */
15082 + if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS)
15083 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
15084 + if (!p_Dtsec->f_Exception)
15085 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
15086 + if (!p_Dtsec->f_Event)
15087 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
15088 +
15089 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
15090 + if (p_Dtsec->p_DtsecDriverParam->rx_len_check)
15091 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
15092 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
15093 +
15094 + return E_OK;
15095 +}
15096 +
15097 +/* ......................................................................... */
15098 +
15099 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
15100 +{
15101 + uint32_t crc;
15102 +
15103 + /* CRC calculation */
15104 + GET_MAC_ADDR_CRC(ethAddr, crc);
15105 +
15106 + crc = GetMirror32(crc);
15107 +
15108 + return crc;
15109 +}
15110 +
15111 +/* ......................................................................... */
15112 +
15113 +static void UpdateStatistics(t_Dtsec *p_Dtsec)
15114 +{
15115 + uint32_t car1, car2;
15116 +
15117 + fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2);
15118 +
15119 + if (car1)
15120 + {
15121 + if (car1 & CAR1_TR64)
15122 + p_Dtsec->internalStatistics.tr64 += VAL22BIT;
15123 + if (car1 & CAR1_TR127)
15124 + p_Dtsec->internalStatistics.tr127 += VAL22BIT;
15125 + if (car1 & CAR1_TR255)
15126 + p_Dtsec->internalStatistics.tr255 += VAL22BIT;
15127 + if (car1 & CAR1_TR511)
15128 + p_Dtsec->internalStatistics.tr511 += VAL22BIT;
15129 + if (car1 & CAR1_TRK1)
15130 + p_Dtsec->internalStatistics.tr1k += VAL22BIT;
15131 + if (car1 & CAR1_TRMAX)
15132 + p_Dtsec->internalStatistics.trmax += VAL22BIT;
15133 + if (car1 & CAR1_TRMGV)
15134 + p_Dtsec->internalStatistics.trmgv += VAL22BIT;
15135 + if (car1 & CAR1_RBYT)
15136 + p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
15137 + if (car1 & CAR1_RPKT)
15138 + p_Dtsec->internalStatistics.rpkt += VAL22BIT;
15139 + if (car1 & CAR1_RMCA)
15140 + p_Dtsec->internalStatistics.rmca += VAL22BIT;
15141 + if (car1 & CAR1_RBCA)
15142 + p_Dtsec->internalStatistics.rbca += VAL22BIT;
15143 + if (car1 & CAR1_RXPF)
15144 + p_Dtsec->internalStatistics.rxpf += VAL16BIT;
15145 + if (car1 & CAR1_RALN)
15146 + p_Dtsec->internalStatistics.raln += VAL16BIT;
15147 + if (car1 & CAR1_RFLR)
15148 + p_Dtsec->internalStatistics.rflr += VAL16BIT;
15149 + if (car1 & CAR1_RCDE)
15150 + p_Dtsec->internalStatistics.rcde += VAL16BIT;
15151 + if (car1 & CAR1_RCSE)
15152 + p_Dtsec->internalStatistics.rcse += VAL16BIT;
15153 + if (car1 & CAR1_RUND)
15154 + p_Dtsec->internalStatistics.rund += VAL16BIT;
15155 + if (car1 & CAR1_ROVR)
15156 + p_Dtsec->internalStatistics.rovr += VAL16BIT;
15157 + if (car1 & CAR1_RFRG)
15158 + p_Dtsec->internalStatistics.rfrg += VAL16BIT;
15159 + if (car1 & CAR1_RJBR)
15160 + p_Dtsec->internalStatistics.rjbr += VAL16BIT;
15161 + if (car1 & CAR1_RDRP)
15162 + p_Dtsec->internalStatistics.rdrp += VAL16BIT;
15163 + }
15164 + if (car2)
15165 + {
15166 + if (car2 & CAR2_TFCS)
15167 + p_Dtsec->internalStatistics.tfcs += VAL12BIT;
15168 + if (car2 & CAR2_TBYT)
15169 + p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
15170 + if (car2 & CAR2_TPKT)
15171 + p_Dtsec->internalStatistics.tpkt += VAL22BIT;
15172 + if (car2 & CAR2_TMCA)
15173 + p_Dtsec->internalStatistics.tmca += VAL22BIT;
15174 + if (car2 & CAR2_TBCA)
15175 + p_Dtsec->internalStatistics.tbca += VAL22BIT;
15176 + if (car2 & CAR2_TXPF)
15177 + p_Dtsec->internalStatistics.txpf += VAL16BIT;
15178 + if (car2 & CAR2_TDRP)
15179 + p_Dtsec->internalStatistics.tdrp += VAL16BIT;
15180 + }
15181 +}
15182 +
15183 +/* .............................................................................. */
15184 +
15185 +static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
15186 +{
15187 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15188 +
15189 + SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
15190 + SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0);
15191 +
15192 + return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
15193 +}
15194 +
15195 +/* .............................................................................. */
15196 +
15197 +static void DtsecIsr(t_Handle h_Dtsec)
15198 +{
15199 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15200 + uint32_t event;
15201 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15202 +
15203 + /* do not handle MDIO events */
15204 + event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN)));
15205 +
15206 + event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap);
15207 +
15208 + fman_dtsec_ack_event(p_DtsecMemMap, event);
15209 +
15210 + if (event & DTSEC_IMASK_BREN)
15211 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
15212 + if (event & DTSEC_IMASK_RXCEN)
15213 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
15214 + if (event & DTSEC_IMASK_MSROEN)
15215 + UpdateStatistics(p_Dtsec);
15216 + if (event & DTSEC_IMASK_GTSCEN)
15217 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
15218 + if (event & DTSEC_IMASK_BTEN)
15219 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
15220 + if (event & DTSEC_IMASK_TXCEN)
15221 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
15222 + if (event & DTSEC_IMASK_TXEEN)
15223 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
15224 + if (event & DTSEC_IMASK_LCEN)
15225 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
15226 + if (event & DTSEC_IMASK_CRLEN)
15227 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
15228 + if (event & DTSEC_IMASK_XFUNEN)
15229 + {
15230 +#ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
15231 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15232 + {
15233 + uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i;
15234 + /* a. Write 0x00E0_0C00 to DTSEC_ID */
15235 + /* This is a read only regidter */
15236 +
15237 + /* b. Read and save the value of TPKT */
15238 + tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
15239 +
15240 + /* c. Read the register at dTSEC address offset 0x32C */
15241 + tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15242 +
15243 + /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
15244 + if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
15245 + {
15246 + /* If they are not equal, save the value of this register and wait for at least
15247 + * MAXFRM*16 ns */
15248 + XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
15249 + }
15250 +
15251 + /* e. Read and save TPKT again and read the register at dTSEC address offset
15252 + 0x32C again*/
15253 + tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
15254 + tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15255 +
15256 + /* f. Compare the value of TPKT saved in step b to value read in step e. Also
15257 + compare bits [9:15] of the register at offset 0x32C saved in step d to the value
15258 + of bits [9:15] saved in step e. If the two registers values are unchanged, then
15259 + the transmit portion of the dTSEC controller is locked up and the user should
15260 + proceed to the recover sequence. */
15261 + if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
15262 + {
15263 + /* recover sequence */
15264 +
15265 + /* a.Write a 1 to RCTRL[GRS]*/
15266 +
15267 + WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
15268 +
15269 + /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
15270 + for (i = 0 ; i < 100 ; i++ )
15271 + {
15272 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15273 + break;
15274 + XX_UDelay(1);
15275 + }
15276 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15277 + WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN);
15278 + else
15279 + DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
15280 +
15281 + /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
15282 + FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
15283 +
15284 + /* d.Wait 4 Tx clocks (32 ns) */
15285 + XX_UDelay(1);
15286 +
15287 + /* e.Write a 0 to bit n of FM_RSTC. */
15288 + /* cleared by FMAN */
15289 + }
15290 + }
15291 +#endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
15292 +
15293 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
15294 + }
15295 + if (event & DTSEC_IMASK_MAGEN)
15296 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
15297 + if (event & DTSEC_IMASK_GRSCEN)
15298 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
15299 + if (event & DTSEC_IMASK_TDPEEN)
15300 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
15301 + if (event & DTSEC_IMASK_RDPEEN)
15302 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
15303 +
15304 + /* - masked interrupts */
15305 + ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN));
15306 + ASSERT_COND(!(event & DTSEC_IMASK_IFERREN));
15307 +}
15308 +
15309 +static void DtsecMdioIsr(t_Handle h_Dtsec)
15310 +{
15311 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15312 + uint32_t event;
15313 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15314 +
15315 + event = GET_UINT32(p_DtsecMemMap->ievent);
15316 + /* handle only MDIO events */
15317 + event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN);
15318 + if (event)
15319 + {
15320 + event &= GET_UINT32(p_DtsecMemMap->imask);
15321 +
15322 + WRITE_UINT32(p_DtsecMemMap->ievent, event);
15323 +
15324 + if (event & DTSEC_IMASK_MMRDEN)
15325 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
15326 + if (event & DTSEC_IMASK_MMWREN)
15327 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
15328 + }
15329 +}
15330 +
15331 +static void Dtsec1588Isr(t_Handle h_Dtsec)
15332 +{
15333 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15334 + uint32_t event;
15335 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15336 +
15337 + if (p_Dtsec->ptpTsuEnabled)
15338 + {
15339 + event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap);
15340 +
15341 + if (event)
15342 + {
15343 + ASSERT_COND(event & TMR_PEVENT_TSRE);
15344 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
15345 + }
15346 + }
15347 +}
15348 +
15349 +/* ........................................................................... */
15350 +
15351 +static void FreeInitResources(t_Dtsec *p_Dtsec)
15352 +{
15353 + if (p_Dtsec->mdioIrq != NO_IRQ)
15354 + {
15355 + XX_DisableIntr(p_Dtsec->mdioIrq);
15356 + XX_FreeIntr(p_Dtsec->mdioIrq);
15357 + }
15358 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
15359 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
15360 +
15361 + /* release the driver's group hash table */
15362 + FreeHashTable(p_Dtsec->p_MulticastAddrHash);
15363 + p_Dtsec->p_MulticastAddrHash = NULL;
15364 +
15365 + /* release the driver's individual hash table */
15366 + FreeHashTable(p_Dtsec->p_UnicastAddrHash);
15367 + p_Dtsec->p_UnicastAddrHash = NULL;
15368 +}
15369 +
15370 +/* ........................................................................... */
15371 +
15372 +static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
15373 +{
15374 + struct dtsec_regs *p_MemMap;
15375 +
15376 + ASSERT_COND(p_Dtsec);
15377 +
15378 + p_MemMap = p_Dtsec->p_MemMap;
15379 + ASSERT_COND(p_MemMap);
15380 +
15381 + /* Assert the graceful transmit stop bit */
15382 + if (mode & e_COMM_MODE_RX)
15383 + {
15384 + fman_dtsec_stop_rx(p_MemMap);
15385 +
15386 +#ifdef FM_GRS_ERRATA_DTSEC_A002
15387 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15388 + XX_UDelay(100);
15389 +#else /* FM_GRS_ERRATA_DTSEC_A002 */
15390 +#ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
15391 + XX_UDelay(10);
15392 +#endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */
15393 +#endif /* FM_GRS_ERRATA_DTSEC_A002 */
15394 + }
15395 +
15396 + if (mode & e_COMM_MODE_TX)
15397 +#if defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012)
15398 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15399 + DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
15400 +#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
15401 +#ifdef FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
15402 + DBG(INFO, ("GTS not supported due to DTSEC_A0014 errata."));
15403 +#else /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
15404 + fman_dtsec_stop_tx(p_MemMap);
15405 +#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
15406 +#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
15407 +
15408 + return E_OK;
15409 +}
15410 +
15411 +/* .............................................................................. */
15412 +
15413 +static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
15414 +{
15415 + struct dtsec_regs *p_MemMap;
15416 +
15417 + ASSERT_COND(p_Dtsec);
15418 + p_MemMap = p_Dtsec->p_MemMap;
15419 + ASSERT_COND(p_MemMap);
15420 +
15421 + /* clear the graceful receive stop bit */
15422 + if (mode & e_COMM_MODE_TX)
15423 + fman_dtsec_start_tx(p_MemMap);
15424 +
15425 + if (mode & e_COMM_MODE_RX)
15426 + fman_dtsec_start_rx(p_MemMap);
15427 +
15428 + return E_OK;
15429 +}
15430 +
15431 +
15432 +/*****************************************************************************/
15433 +/* dTSEC Configs modification functions */
15434 +/*****************************************************************************/
15435 +
15436 +/* .............................................................................. */
15437 +
15438 +static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
15439 +{
15440 +
15441 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15442 +
15443 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15444 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15445 +
15446 + p_Dtsec->p_DtsecDriverParam->loopback = newVal;
15447 +
15448 + return E_OK;
15449 +}
15450 +
15451 +/* .............................................................................. */
15452 +
15453 +static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
15454 +{
15455 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15456 +
15457 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15458 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15459 +
15460 + p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal;
15461 +
15462 + return E_OK;
15463 +}
15464 +
15465 +/* .............................................................................. */
15466 +
15467 +static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
15468 +{
15469 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15470 +
15471 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15472 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15473 +
15474 + p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal;
15475 +
15476 + return E_OK;
15477 +}
15478 +
15479 +/* .............................................................................. */
15480 +
15481 +static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
15482 +{
15483 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15484 +
15485 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15486 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15487 +
15488 + p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal;
15489 +
15490 + return E_OK;
15491 +}
15492 +
15493 +/* .............................................................................. */
15494 +
15495 +static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal)
15496 +{
15497 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15498 +
15499 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15500 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15501 +
15502 + p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal;
15503 +
15504 + return E_OK;
15505 +}
15506 +
15507 +/* .............................................................................. */
15508 +
15509 +static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
15510 +{
15511 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15512 +
15513 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15514 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15515 +
15516 + p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal;
15517 +
15518 + return E_OK;
15519 +}
15520 +
15521 +/* .............................................................................. */
15522 +
15523 +static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
15524 +{
15525 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15526 + uint32_t bitMask = 0;
15527 +
15528 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15529 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15530 +
15531 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
15532 + {
15533 + GET_EXCEPTION_FLAG(bitMask, exception);
15534 + if (bitMask)
15535 + {
15536 + if (enable)
15537 + p_Dtsec->exceptions |= bitMask;
15538 + else
15539 + p_Dtsec->exceptions &= ~bitMask;
15540 + }
15541 + else
15542 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
15543 + }
15544 + else
15545 + {
15546 + if (!p_Dtsec->ptpTsuEnabled)
15547 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
15548 +
15549 + if (enable)
15550 + p_Dtsec->enTsuErrExeption = TRUE;
15551 + else
15552 + p_Dtsec->enTsuErrExeption = FALSE;
15553 + }
15554 +
15555 + return E_OK;
15556 +}
15557 +
15558 +
15559 +/*****************************************************************************/
15560 +/* dTSEC Run Time API functions */
15561 +/*****************************************************************************/
15562 +
15563 +/* .............................................................................. */
15564 +
15565 +static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode)
15566 +{
15567 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15568 +
15569 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15570 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15571 +
15572 + fman_dtsec_enable(p_Dtsec->p_MemMap,
15573 + (bool)!!(mode & e_COMM_MODE_RX),
15574 + (bool)!!(mode & e_COMM_MODE_TX));
15575 +
15576 + GracefulRestart(p_Dtsec, mode);
15577 +
15578 + return E_OK;
15579 +}
15580 +
15581 +/* .............................................................................. */
15582 +
15583 +static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
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 + GracefulStop(p_Dtsec, mode);
15591 +
15592 + fman_dtsec_disable(p_Dtsec->p_MemMap,
15593 + (bool)!!(mode & e_COMM_MODE_RX),
15594 + (bool)!!(mode & e_COMM_MODE_TX));
15595 +
15596 + return E_OK;
15597 +}
15598 +
15599 +/* .............................................................................. */
15600 +
15601 +static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec,
15602 + uint8_t priority,
15603 + uint16_t pauseTime,
15604 + uint16_t threshTime)
15605 +{
15606 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15607 +
15608 + UNUSED(priority);UNUSED(threshTime);
15609 +
15610 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15611 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15612 +
15613 +#ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
15614 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15615 + if (0 < pauseTime && pauseTime <= 320)
15616 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
15617 + ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
15618 + " value should be greater than 320."));
15619 +#endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
15620 +
15621 + fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime);
15622 + return E_OK;
15623 +}
15624 +
15625 +/* .............................................................................. */
15626 +/* backward compatibility. will be removed in the future. */
15627 +static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
15628 +{
15629 + return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0);
15630 +}
15631 +
15632 +/* .............................................................................. */
15633 +
15634 +static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
15635 +{
15636 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15637 + bool accept_pause = !en;
15638 +
15639 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15640 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15641 +
15642 + fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause);
15643 +
15644 + return E_OK;
15645 +}
15646 +
15647 +/* .............................................................................. */
15648 +
15649 +static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
15650 +{
15651 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15652 +
15653 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15654 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15655 +
15656 + p_Dtsec->ptpTsuEnabled = TRUE;
15657 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE);
15658 +
15659 + return E_OK;
15660 +}
15661 +
15662 +/* .............................................................................. */
15663 +
15664 +static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
15665 +{
15666 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15667 +
15668 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15669 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15670 +
15671 + p_Dtsec->ptpTsuEnabled = FALSE;
15672 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE);
15673 +
15674 + return E_OK;
15675 +}
15676 +
15677 +/* .............................................................................. */
15678 +
15679 +static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
15680 +{
15681 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15682 + struct dtsec_regs *p_DtsecMemMap;
15683 +
15684 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15685 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15686 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
15687 +
15688 + p_DtsecMemMap = p_Dtsec->p_MemMap;
15689 +
15690 + if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
15691 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
15692 +
15693 + memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
15694 +
15695 + if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
15696 + {
15697 + p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64)
15698 + + p_Dtsec->internalStatistics.tr64;
15699 + p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127)
15700 + + p_Dtsec->internalStatistics.tr127;
15701 + p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255)
15702 + + p_Dtsec->internalStatistics.tr255;
15703 + p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511)
15704 + + p_Dtsec->internalStatistics.tr511;
15705 + p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K)
15706 + + p_Dtsec->internalStatistics.tr1k;
15707 + p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX)
15708 + + p_Dtsec->internalStatistics.trmax;
15709 + p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV)
15710 + + p_Dtsec->internalStatistics.trmgv;
15711 +
15712 + /* MIB II */
15713 + p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT)
15714 + + p_Dtsec->internalStatistics.rbyt;
15715 + p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT)
15716 + + p_Dtsec->internalStatistics.rpkt;
15717 + p_Statistics->ifInUcastPkts = 0;
15718 + p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA)
15719 + + p_Dtsec->internalStatistics.rmca;
15720 + p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA)
15721 + + p_Dtsec->internalStatistics.rbca;
15722 + p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT)
15723 + + p_Dtsec->internalStatistics.tbyt;
15724 + p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT)
15725 + + p_Dtsec->internalStatistics.tpkt;
15726 + p_Statistics->ifOutUcastPkts = 0;
15727 + p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA)
15728 + + p_Dtsec->internalStatistics.tmca;
15729 + p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA)
15730 + + p_Dtsec->internalStatistics.tbca;
15731 + }
15732 +
15733 + p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG)
15734 + + p_Dtsec->internalStatistics.rfrg;
15735 + p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR)
15736 + + p_Dtsec->internalStatistics.rjbr;
15737 + p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP)
15738 + + p_Dtsec->internalStatistics.rdrp;
15739 + p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN)
15740 + + p_Dtsec->internalStatistics.raln;
15741 + p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND)
15742 + + p_Dtsec->internalStatistics.rund;
15743 + p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR)
15744 + + p_Dtsec->internalStatistics.rovr;
15745 + p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF)
15746 + + p_Dtsec->internalStatistics.rxpf;
15747 + p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF)
15748 + + p_Dtsec->internalStatistics.txpf;
15749 + p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents;
15750 + p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors
15751 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr
15752 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde
15753 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse;
15754 +
15755 + p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP)
15756 + + p_Dtsec->internalStatistics.tdrp;
15757 + p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */
15758 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS)
15759 + + p_Dtsec->internalStatistics.tfcs;
15760 +
15761 + return E_OK;
15762 +}
15763 +
15764 +/* .............................................................................. */
15765 +
15766 +static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
15767 +{
15768 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15769 +
15770 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15771 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15772 +
15773 + /* Initialize MAC Station Address registers (1 & 2) */
15774 + /* Station address have to be swapped (big endian to little endian */
15775 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
15776 + fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr));
15777 +
15778 + return E_OK;
15779 +}
15780 +
15781 +/* .............................................................................. */
15782 +
15783 +static t_Error DtsecResetCounters (t_Handle h_Dtsec)
15784 +{
15785 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15786 +
15787 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15788 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15789 +
15790 + /* clear HW counters */
15791 + fman_dtsec_reset_stat(p_Dtsec->p_MemMap);
15792 +
15793 + /* clear SW counters holding carries */
15794 + memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics));
15795 +
15796 + return E_OK;
15797 +}
15798 +
15799 +/* .............................................................................. */
15800 +
15801 +static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15802 +{
15803 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15804 + uint64_t ethAddr;
15805 + uint8_t paddrNum;
15806 +
15807 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15808 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15809 +
15810 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15811 +
15812 + if (ethAddr & GROUP_ADDRESS)
15813 + /* Multicast address has no effect in PADDR */
15814 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
15815 +
15816 + /* Make sure no PADDR contains this address */
15817 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15818 + if (p_Dtsec->indAddrRegUsed[paddrNum])
15819 + if (p_Dtsec->paddr[paddrNum] == ethAddr)
15820 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
15821 +
15822 + /* Find first unused PADDR */
15823 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15824 + if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
15825 + {
15826 + /* mark this PADDR as used */
15827 + p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
15828 + /* store address */
15829 + p_Dtsec->paddr[paddrNum] = ethAddr;
15830 +
15831 + /* put in hardware */
15832 + fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(&ethAddr), paddrNum);
15833 + p_Dtsec->numOfIndAddrInRegs++;
15834 +
15835 + return E_OK;
15836 + }
15837 +
15838 + /* No free PADDR */
15839 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
15840 +}
15841 +
15842 +/* .............................................................................. */
15843 +
15844 +static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15845 +{
15846 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15847 + uint64_t ethAddr;
15848 + uint8_t paddrNum;
15849 +
15850 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15851 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15852 +
15853 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15854 +
15855 + /* Find used PADDR containing this address */
15856 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15857 + {
15858 + if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
15859 + (p_Dtsec->paddr[paddrNum] == ethAddr))
15860 + {
15861 + /* mark this PADDR as not used */
15862 + p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
15863 + /* clear in hardware */
15864 + fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum);
15865 + p_Dtsec->numOfIndAddrInRegs--;
15866 +
15867 + return E_OK;
15868 + }
15869 + }
15870 +
15871 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
15872 +}
15873 +
15874 +/* .............................................................................. */
15875 +
15876 +static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15877 +{
15878 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15879 + t_EthHashEntry *p_HashEntry;
15880 + uint64_t ethAddr;
15881 + int32_t bucket;
15882 + uint32_t crc;
15883 + bool mcast, ghtx;
15884 +
15885 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15886 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15887 +
15888 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15889 +
15890 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
15891 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
15892 +
15893 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
15894 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
15895 +
15896 + crc = GetMacAddrHashCode(ethAddr);
15897 +
15898 + /* considering the 9 highest order bits in crc H[8:0]:
15899 + * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
15900 + * and H[5:1] (next 5 bits) identify the hash bit
15901 + * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
15902 + * and H[4:0] (next 5 bits) identify the hash bit.
15903 + *
15904 + * In bucket index output the low 5 bits identify the hash register bit,
15905 + * while the higher 4 bits identify the hash register
15906 + */
15907 +
15908 + if (ghtx)
15909 + bucket = (int32_t)((crc >> 23) & 0x1ff);
15910 + else {
15911 + bucket = (int32_t)((crc >> 24) & 0xff);
15912 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
15913 + if (mcast)
15914 + bucket += 0x100;
15915 + }
15916 +
15917 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE);
15918 +
15919 + /* Create element to be added to the driver hash table */
15920 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
15921 + p_HashEntry->addr = ethAddr;
15922 + INIT_LIST(&p_HashEntry->node);
15923 +
15924 + if (ethAddr & MAC_GROUP_ADDRESS)
15925 + /* Group Address */
15926 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]));
15927 + else
15928 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]));
15929 +
15930 + return E_OK;
15931 +}
15932 +
15933 +/* .............................................................................. */
15934 +
15935 +static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15936 +{
15937 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15938 + t_List *p_Pos;
15939 + t_EthHashEntry *p_HashEntry = NULL;
15940 + uint64_t ethAddr;
15941 + int32_t bucket;
15942 + uint32_t crc;
15943 + bool mcast, ghtx;
15944 +
15945 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15946 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15947 +
15948 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15949 +
15950 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
15951 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
15952 +
15953 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
15954 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
15955 +
15956 + crc = GetMacAddrHashCode(ethAddr);
15957 +
15958 + if (ghtx)
15959 + bucket = (int32_t)((crc >> 23) & 0x1ff);
15960 + else {
15961 + bucket = (int32_t)((crc >> 24) & 0xff);
15962 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
15963 + if (mcast)
15964 + bucket += 0x100;
15965 + }
15966 +
15967 + if (ethAddr & MAC_GROUP_ADDRESS)
15968 + {
15969 + /* Group Address */
15970 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
15971 + {
15972 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
15973 + if (p_HashEntry->addr == ethAddr)
15974 + {
15975 + LIST_DelAndInit(&p_HashEntry->node);
15976 + XX_Free(p_HashEntry);
15977 + break;
15978 + }
15979 + }
15980 + if (LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
15981 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
15982 + }
15983 + else
15984 + {
15985 + /* Individual Address */
15986 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
15987 + {
15988 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
15989 + if (p_HashEntry->addr == ethAddr)
15990 + {
15991 + LIST_DelAndInit(&p_HashEntry->node);
15992 + XX_Free(p_HashEntry);
15993 + break;
15994 + }
15995 + }
15996 + if (LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
15997 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
15998 + }
15999 +
16000 + /* address does not exist */
16001 + ASSERT_COND(p_HashEntry != NULL);
16002 +
16003 + return E_OK;
16004 +}
16005 +
16006 +/* .............................................................................. */
16007 +
16008 +static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
16009 +{
16010 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16011 +
16012 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16013 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16014 +
16015 + fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal);
16016 + fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal);
16017 +
16018 + return E_OK;
16019 +}
16020 +
16021 +/* .............................................................................. */
16022 +
16023 +static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
16024 +{
16025 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16026 + t_Error err;
16027 +
16028 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16029 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16030 +
16031 + p_Dtsec->statisticsLevel = statisticsLevel;
16032 +
16033 + err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap,
16034 + (enum dtsec_stat_level)statisticsLevel);
16035 + if (err != E_OK)
16036 + return err;
16037 +
16038 + switch (statisticsLevel)
16039 + {
16040 + case (e_FM_MAC_NONE_STATISTICS):
16041 + p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN;
16042 + break;
16043 + case (e_FM_MAC_PARTIAL_STATISTICS):
16044 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
16045 + break;
16046 + case (e_FM_MAC_FULL_STATISTICS):
16047 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
16048 + break;
16049 + default:
16050 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
16051 + }
16052 +
16053 + return E_OK;
16054 +}
16055 +
16056 +/* .............................................................................. */
16057 +
16058 +static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en)
16059 +{
16060 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16061 +
16062 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
16063 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16064 +
16065 + fman_dtsec_set_wol(p_Dtsec->p_MemMap, en);
16066 +
16067 + return E_OK;
16068 +}
16069 +
16070 +/* .............................................................................. */
16071 +
16072 +static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
16073 +{
16074 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16075 + int err;
16076 + enum enet_interface enet_interface;
16077 + enum enet_speed enet_speed;
16078 +
16079 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16080 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16081 +
16082 + p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
16083 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16084 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16085 + p_Dtsec->halfDuplex = !fullDuplex;
16086 +
16087 + err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex);
16088 +
16089 + if (err == -EINVAL)
16090 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
16091 +
16092 + return (t_Error)err;
16093 +}
16094 +
16095 +/* .............................................................................. */
16096 +
16097 +static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec)
16098 +{
16099 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16100 + uint16_t tmpReg16;
16101 +
16102 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16103 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16104 +
16105 + DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16);
16106 +
16107 + tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 );
16108 + tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16109 +
16110 + DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16);
16111 +
16112 + return E_OK;
16113 +}
16114 +
16115 +/* .............................................................................. */
16116 +
16117 +static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
16118 +{
16119 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16120 +
16121 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16122 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16123 +
16124 + *macId = p_Dtsec->macId;
16125 +
16126 + return E_OK;
16127 +}
16128 +
16129 +/* .............................................................................. */
16130 +
16131 +static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
16132 +{
16133 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16134 +
16135 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16136 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16137 +
16138 + *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap);
16139 +
16140 + return E_OK;
16141 +}
16142 +
16143 +/* .............................................................................. */
16144 +
16145 +static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
16146 +{
16147 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16148 + uint32_t bitMask = 0;
16149 +
16150 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16151 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16152 +
16153 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
16154 + {
16155 + GET_EXCEPTION_FLAG(bitMask, exception);
16156 + if (bitMask)
16157 + {
16158 + if (enable)
16159 + p_Dtsec->exceptions |= bitMask;
16160 + else
16161 + p_Dtsec->exceptions &= ~bitMask;
16162 + }
16163 + else
16164 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
16165 +
16166 + if (enable)
16167 + fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask);
16168 + else
16169 + fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask);
16170 + }
16171 + else
16172 + {
16173 + if (!p_Dtsec->ptpTsuEnabled)
16174 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
16175 +
16176 + if (enable)
16177 + {
16178 + p_Dtsec->enTsuErrExeption = TRUE;
16179 + fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap);
16180 + }
16181 + else
16182 + {
16183 + p_Dtsec->enTsuErrExeption = FALSE;
16184 + fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap);
16185 + }
16186 + }
16187 +
16188 + return E_OK;
16189 +}
16190 +
16191 +
16192 +/*****************************************************************************/
16193 +/* dTSEC Init & Free API */
16194 +/*****************************************************************************/
16195 +
16196 +/* .............................................................................. */
16197 +
16198 +static t_Error DtsecInit(t_Handle h_Dtsec)
16199 +{
16200 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16201 + struct dtsec_cfg *p_DtsecDriverParam;
16202 + t_Error err;
16203 + uint16_t maxFrmLn;
16204 + enum enet_interface enet_interface;
16205 + enum enet_speed enet_speed;
16206 + t_EnetAddr ethAddr;
16207 +
16208 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16209 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16210 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
16211 +
16212 + FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo);
16213 + CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
16214 +
16215 + p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam;
16216 + p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on;
16217 +
16218 + enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16219 + enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16220 + MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr);
16221 +
16222 + err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap,
16223 + p_DtsecDriverParam,
16224 + enet_interface,
16225 + enet_speed,
16226 + (uint8_t*)ethAddr,
16227 + p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev,
16228 + p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev,
16229 + p_Dtsec->exceptions);
16230 + if (err)
16231 + {
16232 + FreeInitResources(p_Dtsec);
16233 + RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode"));
16234 + }
16235 +
16236 + if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII)
16237 + {
16238 + uint16_t tmpReg16;
16239 +
16240 + /* Configure the TBI PHY Control Register */
16241 + tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET;
16242 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16243 +
16244 + tmpReg16 = PHY_TBICON_CLK_SEL;
16245 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16246 +
16247 + tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16248 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16249 +
16250 + if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX)
16251 + tmpReg16 = PHY_TBIANA_1000X;
16252 + else
16253 + tmpReg16 = PHY_TBIANA_SGMII;
16254 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16);
16255 +
16256 + tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16257 +
16258 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16259 + }
16260 +
16261 + /* Max Frame Length */
16262 + maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
16263 + err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G,
16264 + p_Dtsec->fmMacControllerDriver.macId, maxFrmLn);
16265 + if (err)
16266 + RETURN_ERROR(MINOR,err, NO_MSG);
16267 +
16268 + p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE);
16269 + if (!p_Dtsec->p_MulticastAddrHash) {
16270 + FreeInitResources(p_Dtsec);
16271 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
16272 + }
16273 +
16274 + p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
16275 + if (!p_Dtsec->p_UnicastAddrHash)
16276 + {
16277 + FreeInitResources(p_Dtsec);
16278 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
16279 + }
16280 +
16281 + /* register err intr handler for dtsec to FPM (err)*/
16282 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16283 + e_FM_MOD_1G_MAC,
16284 + p_Dtsec->macId,
16285 + e_FM_INTR_TYPE_ERR,
16286 + DtsecIsr,
16287 + p_Dtsec);
16288 + /* register 1588 intr handler for TMR to FPM (normal)*/
16289 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16290 + e_FM_MOD_1G_MAC,
16291 + p_Dtsec->macId,
16292 + e_FM_INTR_TYPE_NORMAL,
16293 + Dtsec1588Isr,
16294 + p_Dtsec);
16295 + /* register normal intr handler for dtsec to main interrupt controller. */
16296 + if (p_Dtsec->mdioIrq != NO_IRQ)
16297 + {
16298 + XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec);
16299 + XX_EnableIntr(p_Dtsec->mdioIrq);
16300 + }
16301 +
16302 + XX_Free(p_DtsecDriverParam);
16303 + p_Dtsec->p_DtsecDriverParam = NULL;
16304 +
16305 + err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS);
16306 + if (err)
16307 + {
16308 + FreeInitResources(p_Dtsec);
16309 + RETURN_ERROR(MAJOR, err, ("Undefined statistics level"));
16310 + }
16311 +
16312 + return E_OK;
16313 +}
16314 +
16315 +/* ........................................................................... */
16316 +
16317 +static t_Error DtsecFree(t_Handle h_Dtsec)
16318 +{
16319 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16320 +
16321 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16322 +
16323 + if (p_Dtsec->p_DtsecDriverParam)
16324 + {
16325 + /* Called after config */
16326 + XX_Free(p_Dtsec->p_DtsecDriverParam);
16327 + p_Dtsec->p_DtsecDriverParam = NULL;
16328 + }
16329 + else
16330 + /* Called after init */
16331 + FreeInitResources(p_Dtsec);
16332 +
16333 + XX_Free(p_Dtsec);
16334 +
16335 + return E_OK;
16336 +}
16337 +
16338 +/* .............................................................................. */
16339 +
16340 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
16341 +{
16342 + p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit;
16343 + p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree;
16344 +
16345 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics;
16346 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback;
16347 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength;
16348 +
16349 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */
16350 +
16351 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc;
16352 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex;
16353 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck;
16354 + p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr = DtsecConfigTbiPhyAddr;
16355 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException;
16356 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
16357 +
16358 + p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable;
16359 + p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable;
16360 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
16361 +
16362 + p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException;
16363 +
16364 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous;
16365 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink;
16366 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = DtsecSetWakeOnLan;
16367 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = DtsecRestartAutoneg;
16368 +
16369 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp;
16370 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp;
16371 +
16372 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause;
16373 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = DtsecSetTxPauseFrames;
16374 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause;
16375 +
16376 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters;
16377 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics;
16378 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = NULL;
16379 +
16380 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress;
16381 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress;
16382 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress;
16383 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress;
16384 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress;
16385 + p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId;
16386 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion;
16387 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength;
16388 +
16389 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg;
16390 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg;
16391 +
16392 +}
16393 +
16394 +
16395 +/*****************************************************************************/
16396 +/* dTSEC Config Main Entry */
16397 +/*****************************************************************************/
16398 +
16399 +/* .............................................................................. */
16400 +
16401 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam)
16402 +{
16403 + t_Dtsec *p_Dtsec;
16404 + struct dtsec_cfg *p_DtsecDriverParam;
16405 + uintptr_t baseAddr;
16406 +
16407 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
16408 +
16409 + baseAddr = p_FmMacParam->baseAddr;
16410 +
16411 + /* allocate memory for the UCC GETH data structure. */
16412 + p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec));
16413 + if (!p_Dtsec)
16414 + {
16415 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
16416 + return NULL;
16417 + }
16418 + memset(p_Dtsec, 0, sizeof(t_Dtsec));
16419 + InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
16420 +
16421 + /* allocate memory for the dTSEC driver parameters data structure. */
16422 + p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg));
16423 + if (!p_DtsecDriverParam)
16424 + {
16425 + XX_Free(p_Dtsec);
16426 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
16427 + return NULL;
16428 + }
16429 + memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg));
16430 +
16431 + /* Plant parameter structure pointer */
16432 + p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
16433 +
16434 + fman_dtsec_defconfig(p_DtsecDriverParam);
16435 +
16436 + p_Dtsec->p_MemMap = (struct dtsec_regs *)UINT_TO_PTR(baseAddr);
16437 + p_Dtsec->p_MiiMemMap = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
16438 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
16439 + p_Dtsec->enetMode = p_FmMacParam->enetMode;
16440 + p_Dtsec->macId = p_FmMacParam->macId;
16441 + p_Dtsec->exceptions = DEFAULT_exceptions;
16442 + p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq;
16443 + p_Dtsec->f_Exception = p_FmMacParam->f_Exception;
16444 + p_Dtsec->f_Event = p_FmMacParam->f_Event;
16445 + p_Dtsec->h_App = p_FmMacParam->h_App;
16446 + p_Dtsec->ptpTsuEnabled = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en;
16447 + p_Dtsec->enTsuErrExeption = p_Dtsec->p_DtsecDriverParam->ptp_exception_en;
16448 + p_Dtsec->tbi_phy_addr = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr;
16449 +
16450 + return p_Dtsec;
16451 +}
16452 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
16453 new file mode 100644
16454 index 00000000..c26f40cc
16455 --- /dev/null
16456 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
16457 @@ -0,0 +1,228 @@
16458 +/*
16459 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16460 + *
16461 + * Redistribution and use in source and binary forms, with or without
16462 + * modification, are permitted provided that the following conditions are met:
16463 + * * Redistributions of source code must retain the above copyright
16464 + * notice, this list of conditions and the following disclaimer.
16465 + * * Redistributions in binary form must reproduce the above copyright
16466 + * notice, this list of conditions and the following disclaimer in the
16467 + * documentation and/or other materials provided with the distribution.
16468 + * * Neither the name of Freescale Semiconductor nor the
16469 + * names of its contributors may be used to endorse or promote products
16470 + * derived from this software without specific prior written permission.
16471 + *
16472 + *
16473 + * ALTERNATIVELY, this software may be distributed under the terms of the
16474 + * GNU General Public License ("GPL") as published by the Free Software
16475 + * Foundation, either version 2 of that License or (at your option) any
16476 + * later version.
16477 + *
16478 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16479 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16480 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16481 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16482 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16483 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16484 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16485 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16486 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16487 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16488 + */
16489 +
16490 +/******************************************************************************
16491 + @File dtsec.h
16492 +
16493 + @Description FM dTSEC ...
16494 +*//***************************************************************************/
16495 +#ifndef __DTSEC_H
16496 +#define __DTSEC_H
16497 +
16498 +#include "std_ext.h"
16499 +#include "error_ext.h"
16500 +#include "list_ext.h"
16501 +#include "enet_ext.h"
16502 +
16503 +#include "dtsec_mii_acc.h"
16504 +#include "fm_mac.h"
16505 +
16506 +
16507 +#define DEFAULT_exceptions \
16508 + ((uint32_t)(DTSEC_IMASK_BREN | \
16509 + DTSEC_IMASK_RXCEN | \
16510 + DTSEC_IMASK_BTEN | \
16511 + DTSEC_IMASK_TXCEN | \
16512 + DTSEC_IMASK_TXEEN | \
16513 + DTSEC_IMASK_ABRTEN | \
16514 + DTSEC_IMASK_LCEN | \
16515 + DTSEC_IMASK_CRLEN | \
16516 + DTSEC_IMASK_XFUNEN | \
16517 + DTSEC_IMASK_IFERREN | \
16518 + DTSEC_IMASK_MAGEN | \
16519 + DTSEC_IMASK_TDPEEN | \
16520 + DTSEC_IMASK_RDPEEN))
16521 +
16522 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
16523 + case e_FM_MAC_EX_1G_BAB_RX: \
16524 + bitMask = DTSEC_IMASK_BREN; break; \
16525 + case e_FM_MAC_EX_1G_RX_CTL: \
16526 + bitMask = DTSEC_IMASK_RXCEN; break; \
16527 + case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \
16528 + bitMask = DTSEC_IMASK_GTSCEN ; break; \
16529 + case e_FM_MAC_EX_1G_BAB_TX: \
16530 + bitMask = DTSEC_IMASK_BTEN ; break; \
16531 + case e_FM_MAC_EX_1G_TX_CTL: \
16532 + bitMask = DTSEC_IMASK_TXCEN ; break; \
16533 + case e_FM_MAC_EX_1G_TX_ERR: \
16534 + bitMask = DTSEC_IMASK_TXEEN ; break; \
16535 + case e_FM_MAC_EX_1G_LATE_COL: \
16536 + bitMask = DTSEC_IMASK_LCEN ; break; \
16537 + case e_FM_MAC_EX_1G_COL_RET_LMT: \
16538 + bitMask = DTSEC_IMASK_CRLEN ; break; \
16539 + case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \
16540 + bitMask = DTSEC_IMASK_XFUNEN ; break; \
16541 + case e_FM_MAC_EX_1G_MAG_PCKT: \
16542 + bitMask = DTSEC_IMASK_MAGEN ; break; \
16543 + case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \
16544 + bitMask = DTSEC_IMASK_MMRDEN; break; \
16545 + case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \
16546 + bitMask = DTSEC_IMASK_MMWREN ; break; \
16547 + case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \
16548 + bitMask = DTSEC_IMASK_GRSCEN; break; \
16549 + case e_FM_MAC_EX_1G_TX_DATA_ERR: \
16550 + bitMask = DTSEC_IMASK_TDPEEN; break; \
16551 + case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \
16552 + bitMask = DTSEC_IMASK_MSROEN ; break; \
16553 + default: bitMask = 0;break;}
16554 +
16555 +
16556 +#define MAX_PACKET_ALIGNMENT 31
16557 +#define MAX_INTER_PACKET_GAP 0x7f
16558 +#define MAX_INTER_PALTERNATE_BEB 0x0f
16559 +#define MAX_RETRANSMISSION 0x0f
16560 +#define MAX_COLLISION_WINDOW 0x03ff
16561 +
16562 +
16563 +/********************* From mac ext ******************************************/
16564 +typedef uint32_t t_ErrorDisable;
16565 +
16566 +#define ERROR_DISABLE_TRANSMIT 0x00400000
16567 +#define ERROR_DISABLE_LATE_COLLISION 0x00040000
16568 +#define ERROR_DISABLE_COLLISION_RETRY_LIMIT 0x00020000
16569 +#define ERROR_DISABLE_TxFIFO_UNDERRUN 0x00010000
16570 +#define ERROR_DISABLE_TxABORT 0x00008000
16571 +#define ERROR_DISABLE_INTERFACE 0x00004000
16572 +#define ERROR_DISABLE_TxDATA_PARITY 0x00000002
16573 +#define ERROR_DISABLE_RxDATA_PARITY 0x00000001
16574 +
16575 +/*****************************************************************************/
16576 +#define DTSEC_NUM_OF_PADDRS 15 /* number of pattern match registers (entries) */
16577 +
16578 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
16579 +
16580 +#define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */
16581 +
16582 +#define HASH_TABLE_SIZE 256 /* Hash table size (32 bits * 8 regs) */
16583 +#define EXTENDED_HASH_TABLE_SIZE 512 /* Extended Hash table size (32 bits * 16 regs) */
16584 +
16585 +#define DTSEC_TO_MII_OFFSET 0x1000 /* number of pattern match registers (entries) */
16586 +
16587 +#define MAX_PHYS 32 /* maximum number of phys */
16588 +
16589 +#define VAL32BIT 0x100000000LL
16590 +#define VAL22BIT 0x00400000
16591 +#define VAL16BIT 0x00010000
16592 +#define VAL12BIT 0x00001000
16593 +
16594 +/* CAR1/2 bits */
16595 +#define CAR1_TR64 0x80000000
16596 +#define CAR1_TR127 0x40000000
16597 +#define CAR1_TR255 0x20000000
16598 +#define CAR1_TR511 0x10000000
16599 +#define CAR1_TRK1 0x08000000
16600 +#define CAR1_TRMAX 0x04000000
16601 +#define CAR1_TRMGV 0x02000000
16602 +
16603 +#define CAR1_RBYT 0x00010000
16604 +#define CAR1_RPKT 0x00008000
16605 +#define CAR1_RMCA 0x00002000
16606 +#define CAR1_RBCA 0x00001000
16607 +#define CAR1_RXPF 0x00000400
16608 +#define CAR1_RALN 0x00000100
16609 +#define CAR1_RFLR 0x00000080
16610 +#define CAR1_RCDE 0x00000040
16611 +#define CAR1_RCSE 0x00000020
16612 +#define CAR1_RUND 0x00000010
16613 +#define CAR1_ROVR 0x00000008
16614 +#define CAR1_RFRG 0x00000004
16615 +#define CAR1_RJBR 0x00000002
16616 +#define CAR1_RDRP 0x00000001
16617 +
16618 +#define CAR2_TFCS 0x00040000
16619 +#define CAR2_TBYT 0x00002000
16620 +#define CAR2_TPKT 0x00001000
16621 +#define CAR2_TMCA 0x00000800
16622 +#define CAR2_TBCA 0x00000400
16623 +#define CAR2_TXPF 0x00000200
16624 +#define CAR2_TDRP 0x00000001
16625 +
16626 +typedef struct t_InternalStatistics
16627 +{
16628 + uint64_t tr64;
16629 + uint64_t tr127;
16630 + uint64_t tr255;
16631 + uint64_t tr511;
16632 + uint64_t tr1k;
16633 + uint64_t trmax;
16634 + uint64_t trmgv;
16635 + uint64_t rfrg;
16636 + uint64_t rjbr;
16637 + uint64_t rdrp;
16638 + uint64_t raln;
16639 + uint64_t rund;
16640 + uint64_t rovr;
16641 + uint64_t rxpf;
16642 + uint64_t txpf;
16643 + uint64_t rbyt;
16644 + uint64_t rpkt;
16645 + uint64_t rmca;
16646 + uint64_t rbca;
16647 + uint64_t rflr;
16648 + uint64_t rcde;
16649 + uint64_t rcse;
16650 + uint64_t tbyt;
16651 + uint64_t tpkt;
16652 + uint64_t tmca;
16653 + uint64_t tbca;
16654 + uint64_t tdrp;
16655 + uint64_t tfcs;
16656 +} t_InternalStatistics;
16657 +
16658 +typedef struct {
16659 + t_FmMacControllerDriver fmMacControllerDriver;
16660 + t_Handle h_App; /**< Handle to the upper layer application */
16661 + struct dtsec_regs *p_MemMap; /**< pointer to dTSEC memory mapped registers. */
16662 + struct dtsec_mii_reg *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */
16663 + uint64_t addr; /**< MAC address of device; */
16664 + e_EnetMode enetMode; /**< Ethernet physical interface */
16665 + t_FmMacExceptionCallback *f_Exception;
16666 + int mdioIrq;
16667 + t_FmMacExceptionCallback *f_Event;
16668 + bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
16669 + uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
16670 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
16671 + bool halfDuplex;
16672 + t_InternalStatistics internalStatistics;
16673 + t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */
16674 + t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */
16675 + uint8_t macId;
16676 + uint8_t tbi_phy_addr;
16677 + uint32_t exceptions;
16678 + bool ptpTsuEnabled;
16679 + bool enTsuErrExeption;
16680 + e_FmMacStatisticsLevel statisticsLevel;
16681 + struct dtsec_cfg *p_DtsecDriverParam;
16682 +} t_Dtsec;
16683 +
16684 +
16685 +#endif /* __DTSEC_H */
16686 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
16687 new file mode 100644
16688 index 00000000..87da25ff
16689 --- /dev/null
16690 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
16691 @@ -0,0 +1,97 @@
16692 +/*
16693 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16694 + *
16695 + * Redistribution and use in source and binary forms, with or without
16696 + * modification, are permitted provided that the following conditions are met:
16697 + * * Redistributions of source code must retain the above copyright
16698 + * notice, this list of conditions and the following disclaimer.
16699 + * * Redistributions in binary form must reproduce the above copyright
16700 + * notice, this list of conditions and the following disclaimer in the
16701 + * documentation and/or other materials provided with the distribution.
16702 + * * Neither the name of Freescale Semiconductor nor the
16703 + * names of its contributors may be used to endorse or promote products
16704 + * derived from this software without specific prior written permission.
16705 + *
16706 + *
16707 + * ALTERNATIVELY, this software may be distributed under the terms of the
16708 + * GNU General Public License ("GPL") as published by the Free Software
16709 + * Foundation, either version 2 of that License or (at your option) any
16710 + * later version.
16711 + *
16712 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16713 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16714 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16715 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16716 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16717 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16718 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16719 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16720 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16721 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16722 + */
16723 +
16724 +
16725 +/******************************************************************************
16726 + @File dtsec_mii_acc.c
16727 +
16728 + @Description FM dtsec MII register access MAC ...
16729 +*//***************************************************************************/
16730 +
16731 +#include "error_ext.h"
16732 +#include "std_ext.h"
16733 +#include "fm_mac.h"
16734 +#include "dtsec.h"
16735 +#include "fsl_fman_dtsec_mii_acc.h"
16736 +
16737 +
16738 +/*****************************************************************************/
16739 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec,
16740 + uint8_t phyAddr,
16741 + uint8_t reg,
16742 + uint16_t data)
16743 +{
16744 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16745 + struct dtsec_mii_reg *miiregs;
16746 + uint16_t dtsec_freq;
16747 + t_Error err;
16748 +
16749 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16750 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16751 +
16752 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16753 + miiregs = p_Dtsec->p_MiiMemMap;
16754 +
16755 + err = (t_Error)fman_dtsec_mii_write_reg(miiregs, phyAddr, reg, data, dtsec_freq);
16756 +
16757 + return err;
16758 +}
16759 +
16760 +/*****************************************************************************/
16761 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec,
16762 + uint8_t phyAddr,
16763 + uint8_t reg,
16764 + uint16_t *p_Data)
16765 +{
16766 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16767 + struct dtsec_mii_reg *miiregs;
16768 + uint16_t dtsec_freq;
16769 + t_Error err;
16770 +
16771 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16772 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16773 +
16774 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16775 + miiregs = p_Dtsec->p_MiiMemMap;
16776 +
16777 + err = fman_dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data, dtsec_freq);
16778 +
16779 + if (*p_Data == 0xffff)
16780 + RETURN_ERROR(MINOR, E_NO_DEVICE,
16781 + ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x",
16782 + phyAddr, reg));
16783 + if (err)
16784 + RETURN_ERROR(MINOR, (t_Error)err, NO_MSG);
16785 +
16786 + return E_OK;
16787 +}
16788 +
16789 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
16790 new file mode 100644
16791 index 00000000..75cc658a
16792 --- /dev/null
16793 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
16794 @@ -0,0 +1,42 @@
16795 +/*
16796 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16797 + *
16798 + * Redistribution and use in source and binary forms, with or without
16799 + * modification, are permitted provided that the following conditions are met:
16800 + * * Redistributions of source code must retain the above copyright
16801 + * notice, this list of conditions and the following disclaimer.
16802 + * * Redistributions in binary form must reproduce the above copyright
16803 + * notice, this list of conditions and the following disclaimer in the
16804 + * documentation and/or other materials provided with the distribution.
16805 + * * Neither the name of Freescale Semiconductor nor the
16806 + * names of its contributors may be used to endorse or promote products
16807 + * derived from this software without specific prior written permission.
16808 + *
16809 + *
16810 + * ALTERNATIVELY, this software may be distributed under the terms of the
16811 + * GNU General Public License ("GPL") as published by the Free Software
16812 + * Foundation, either version 2 of that License or (at your option) any
16813 + * later version.
16814 + *
16815 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16816 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16817 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16818 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16819 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16820 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16821 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16822 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16823 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16824 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16825 + */
16826 +
16827 +#ifndef __DTSEC_MII_ACC_H
16828 +#define __DTSEC_MII_ACC_H
16829 +
16830 +#include "std_ext.h"
16831 +
16832 +
16833 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data);
16834 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
16835 +
16836 +#endif /* __DTSEC_MII_ACC_H */
16837 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
16838 new file mode 100644
16839 index 00000000..caf3940a
16840 --- /dev/null
16841 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
16842 @@ -0,0 +1,674 @@
16843 +/*
16844 + * Copyright 2008-2012 Freescale Semiconductor Inc.
16845 + *
16846 + * Redistribution and use in source and binary forms, with or without
16847 + * modification, are permitted provided that the following conditions are met:
16848 + * * Redistributions of source code must retain the above copyright
16849 + * notice, this list of conditions and the following disclaimer.
16850 + * * Redistributions in binary form must reproduce the above copyright
16851 + * notice, this list of conditions and the following disclaimer in the
16852 + * documentation and/or other materials provided with the distribution.
16853 + * * Neither the name of Freescale Semiconductor nor the
16854 + * names of its contributors may be used to endorse or promote products
16855 + * derived from this software without specific prior written permission.
16856 + *
16857 + *
16858 + * ALTERNATIVELY, this software may be distributed under the terms of the
16859 + * GNU General Public License ("GPL") as published by the Free Software
16860 + * Foundation, either version 2 of that License or (at your option) any
16861 + * later version.
16862 + *
16863 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16864 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16865 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16866 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16867 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16868 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16869 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16870 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16871 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16872 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16873 + */
16874 +
16875 +
16876 +/******************************************************************************
16877 + @File fm_mac.c
16878 +
16879 + @Description FM MAC ...
16880 +*//***************************************************************************/
16881 +#include "std_ext.h"
16882 +#include "string_ext.h"
16883 +#include "sprint_ext.h"
16884 +#include "error_ext.h"
16885 +#include "fm_ext.h"
16886 +
16887 +#include "fm_common.h"
16888 +#include "fm_mac.h"
16889 +
16890 +
16891 +/* ......................................................................... */
16892 +
16893 +t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam)
16894 +{
16895 + t_FmMacControllerDriver *p_FmMacControllerDriver;
16896 + uint16_t fmClkFreq;
16897 +
16898 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL);
16899 +
16900 + fmClkFreq = FmGetClockFreq(p_FmMacParam->h_Fm);
16901 + if (fmClkFreq == 0)
16902 + {
16903 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!"));
16904 + return NULL;
16905 + }
16906 +
16907 +#if (DPAA_VERSION == 10)
16908 + if (ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000)
16909 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam);
16910 + else
16911 +#if FM_MAX_NUM_OF_10G_MACS > 0
16912 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam);
16913 +#else
16914 + p_FmMacControllerDriver = NULL;
16915 +#endif /* FM_MAX_NUM_OF_10G_MACS > 0 */
16916 +#else
16917 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)MEMAC_Config(p_FmMacParam);
16918 +#endif /* (DPAA_VERSION == 10) */
16919 +
16920 + if (!p_FmMacControllerDriver)
16921 + return NULL;
16922 +
16923 + p_FmMacControllerDriver->h_Fm = p_FmMacParam->h_Fm;
16924 + p_FmMacControllerDriver->enetMode = p_FmMacParam->enetMode;
16925 + p_FmMacControllerDriver->macId = p_FmMacParam->macId;
16926 + p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit;
16927 +
16928 + p_FmMacControllerDriver->clkFreq = fmClkFreq;
16929 +
16930 + return (t_Handle)p_FmMacControllerDriver;
16931 +}
16932 +
16933 +/* ......................................................................... */
16934 +
16935 +t_Error FM_MAC_Init (t_Handle h_FmMac)
16936 +{
16937 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16938 +
16939 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16940 +
16941 + if (p_FmMacControllerDriver->resetOnInit &&
16942 + !p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit &&
16943 + (FmResetMac(p_FmMacControllerDriver->h_Fm,
16944 + ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ?
16945 + e_FM_MAC_10G : e_FM_MAC_1G),
16946 + p_FmMacControllerDriver->macId) != E_OK))
16947 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!"));
16948 +
16949 + if (p_FmMacControllerDriver->f_FM_MAC_Init)
16950 + return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac);
16951 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16952 +}
16953 +
16954 +/* ......................................................................... */
16955 +
16956 +t_Error FM_MAC_Free (t_Handle h_FmMac)
16957 +{
16958 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16959 +
16960 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16961 +
16962 + if (p_FmMacControllerDriver->f_FM_MAC_Free)
16963 + return p_FmMacControllerDriver->f_FM_MAC_Free(h_FmMac);
16964 +
16965 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16966 +}
16967 +
16968 +/* ......................................................................... */
16969 +
16970 +t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable)
16971 +{
16972 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16973 +
16974 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16975 +
16976 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit)
16977 + return p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit(h_FmMac, enable);
16978 +
16979 + p_FmMacControllerDriver->resetOnInit = enable;
16980 +
16981 + return E_OK;
16982 +}
16983 +
16984 +/* ......................................................................... */
16985 +
16986 +t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal)
16987 +{
16988 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16989 +
16990 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16991 +
16992 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback)
16993 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback(h_FmMac, newVal);
16994 +
16995 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16996 +}
16997 +
16998 +/* ......................................................................... */
16999 +
17000 +t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal)
17001 +{
17002 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17003 +
17004 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17005 +
17006 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength)
17007 + return p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength(h_FmMac, newVal);
17008 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17009 +}
17010 +
17011 +/* ......................................................................... */
17012 +
17013 +t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag)
17014 +{
17015 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17016 +
17017 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17018 +
17019 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigWan)
17020 + return p_FmMacControllerDriver->f_FM_MAC_ConfigWan(h_FmMac, flag);
17021 +
17022 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17023 +}
17024 +
17025 +/* ......................................................................... */
17026 +
17027 +t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal)
17028 +{
17029 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17030 +
17031 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17032 +
17033 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc)
17034 + return p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc(h_FmMac, newVal);
17035 +
17036 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17037 +}
17038 +
17039 +/* ......................................................................... */
17040 +
17041 +t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal)
17042 +{
17043 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17044 +
17045 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17046 +
17047 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex)
17048 + return p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex(h_FmMac,newVal);
17049 +
17050 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17051 +}
17052 +
17053 +/* ......................................................................... */
17054 +
17055 +t_Error FM_MAC_ConfigTbiPhyAddr (t_Handle h_FmMac, uint8_t newVal)
17056 +{
17057 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17058 +
17059 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17060 +
17061 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr)
17062 + return p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr(h_FmMac,newVal);
17063 +
17064 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17065 +}
17066 +
17067 +/* ......................................................................... */
17068 +
17069 +t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal)
17070 +{
17071 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17072 +
17073 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17074 +
17075 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck)
17076 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck(h_FmMac,newVal);
17077 +
17078 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17079 +}
17080 +
17081 +/* ......................................................................... */
17082 +
17083 +t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
17084 +{
17085 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17086 +
17087 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17088 +
17089 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigException)
17090 + return p_FmMacControllerDriver->f_FM_MAC_ConfigException(h_FmMac, ex, enable);
17091 +
17092 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17093 +}
17094 +
17095 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17096 +/* ......................................................................... */
17097 +
17098 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac)
17099 +{
17100 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17101 +
17102 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17103 +
17104 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround)
17105 + return p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround(h_FmMac);
17106 +
17107 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17108 +}
17109 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17110 +
17111 +
17112 +/*****************************************************************************/
17113 +/* Run Time Control */
17114 +/*****************************************************************************/
17115 +
17116 +/* ......................................................................... */
17117 +
17118 +t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode)
17119 +{
17120 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17121 +
17122 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17123 +
17124 + if (p_FmMacControllerDriver->f_FM_MAC_Enable)
17125 + return p_FmMacControllerDriver->f_FM_MAC_Enable(h_FmMac, mode);
17126 +
17127 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17128 +}
17129 +
17130 +/* ......................................................................... */
17131 +
17132 +t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode)
17133 +{
17134 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17135 +
17136 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17137 +
17138 + if (p_FmMacControllerDriver->f_FM_MAC_Disable)
17139 + return p_FmMacControllerDriver->f_FM_MAC_Disable(h_FmMac, mode);
17140 +
17141 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17142 +}
17143 +
17144 +t_Error FM_MAC_Resume (t_Handle h_FmMac)
17145 +{
17146 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17147 +
17148 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17149 +
17150 + if (p_FmMacControllerDriver->f_FM_MAC_Resume)
17151 + return p_FmMacControllerDriver->f_FM_MAC_Resume(h_FmMac);
17152 +
17153 + return E_OK;
17154 +}
17155 +
17156 +/* ......................................................................... */
17157 +
17158 +t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac)
17159 +{
17160 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17161 +
17162 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17163 +
17164 + if (p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp)
17165 + return p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp(h_FmMac);
17166 +
17167 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17168 +}
17169 +
17170 +/* ......................................................................... */
17171 +
17172 +t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac)
17173 +{
17174 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17175 +
17176 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17177 +
17178 + if (p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp)
17179 + return p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp(h_FmMac);
17180 +
17181 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17182 +}
17183 +
17184 +/* ......................................................................... */
17185 +
17186 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
17187 + uint16_t pauseTime)
17188 +{
17189 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17190 +
17191 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17192 +
17193 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames)
17194 + return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac,
17195 + pauseTime);
17196 +
17197 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17198 +}
17199 +
17200 +/* ......................................................................... */
17201 +
17202 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
17203 + uint8_t priority,
17204 + uint16_t pauseTime,
17205 + uint16_t threshTime)
17206 +{
17207 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17208 +
17209 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17210 +
17211 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames)
17212 + return p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames(h_FmMac,
17213 + priority,
17214 + pauseTime,
17215 + threshTime);
17216 +
17217 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
17218 +}
17219 +
17220 +/* ......................................................................... */
17221 +
17222 +t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en)
17223 +{
17224 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17225 +
17226 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17227 +
17228 + if (p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames)
17229 + return p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames(h_FmMac, en);
17230 +
17231 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17232 +}
17233 +
17234 +/* ......................................................................... */
17235 +
17236 +t_Error FM_MAC_SetWakeOnLan (t_Handle h_FmMac, bool en)
17237 +{
17238 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17239 +
17240 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17241 +
17242 + if (p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan)
17243 + return p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan(h_FmMac, en);
17244 +
17245 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17246 +}
17247 +
17248 +/* ......................................................................... */
17249 +
17250 +t_Error FM_MAC_ResetCounters (t_Handle h_FmMac)
17251 +{
17252 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17253 +
17254 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17255 +
17256 + if (p_FmMacControllerDriver->f_FM_MAC_ResetCounters)
17257 + return p_FmMacControllerDriver->f_FM_MAC_ResetCounters(h_FmMac);
17258 +
17259 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17260 +}
17261 +
17262 +/* ......................................................................... */
17263 +
17264 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
17265 +{
17266 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17267 +
17268 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17269 +
17270 + if (p_FmMacControllerDriver->f_FM_MAC_SetException)
17271 + return p_FmMacControllerDriver->f_FM_MAC_SetException(h_FmMac, ex, enable);
17272 +
17273 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17274 +}
17275 +
17276 +/* ......................................................................... */
17277 +
17278 +t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel)
17279 +{
17280 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17281 +
17282 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17283 +
17284 + if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics)
17285 + return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel);
17286 +
17287 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17288 +}
17289 +
17290 +/* ......................................................................... */
17291 +
17292 +t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics)
17293 +{
17294 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17295 +
17296 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17297 +
17298 + if (p_FmMacControllerDriver->f_FM_MAC_GetStatistics)
17299 + return p_FmMacControllerDriver->f_FM_MAC_GetStatistics(h_FmMac, p_Statistics);
17300 +
17301 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17302 +}
17303 +
17304 +/* ......................................................................... */
17305 +
17306 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
17307 +{
17308 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17309 +
17310 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17311 +
17312 + memset(p_FrameSizeCounters, 0, sizeof(t_FmMacFrameSizeCounters));
17313 +
17314 + if (p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters)
17315 + return p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters(h_FmMac, p_FrameSizeCounters, type);
17316 +
17317 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17318 +}
17319 +
17320 +/* ......................................................................... */
17321 +
17322 +t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17323 +{
17324 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17325 +
17326 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17327 +
17328 + if (p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr)
17329 + return p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr(h_FmMac, p_EnetAddr);
17330 +
17331 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17332 +}
17333 +
17334 +/* ......................................................................... */
17335 +
17336 +t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17337 +{
17338 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17339 +
17340 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17341 +
17342 + if (p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr)
17343 + return p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr(h_FmMac, p_EnetAddr);
17344 +
17345 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17346 +}
17347 +
17348 +/* ......................................................................... */
17349 +
17350 +t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17351 +{
17352 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17353 +
17354 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17355 +
17356 + if (p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr)
17357 + return p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr(h_FmMac, p_EnetAddr);
17358 +
17359 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17360 +}
17361 +
17362 +/* ......................................................................... */
17363 +
17364 +t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17365 +{
17366 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17367 +
17368 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17369 +
17370 + if (p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr)
17371 + return p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr(h_FmMac, p_EnetAddr);
17372 +
17373 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17374 +}
17375 +
17376 +/* ......................................................................... */
17377 +
17378 +t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17379 +{
17380 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17381 +
17382 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17383 +
17384 + if (p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr)
17385 + return p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr(h_FmMac, p_EnetAddr);
17386 +
17387 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17388 +}
17389 +
17390 +/* ......................................................................... */
17391 +
17392 +t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion)
17393 +{
17394 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17395 +
17396 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17397 +
17398 + if (p_FmMacControllerDriver->f_FM_MAC_GetVersion)
17399 + return p_FmMacControllerDriver->f_FM_MAC_GetVersion(h_FmMac, macVresion);
17400 +
17401 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17402 +
17403 +}
17404 +
17405 +/* ......................................................................... */
17406 +
17407 +t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId)
17408 +{
17409 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17410 +
17411 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17412 +
17413 + if (p_FmMacControllerDriver->f_FM_MAC_GetId)
17414 + return p_FmMacControllerDriver->f_FM_MAC_GetId(h_FmMac, macId);
17415 +
17416 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17417 +}
17418 +
17419 +/* ......................................................................... */
17420 +
17421 +t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal)
17422 +{
17423 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17424 +
17425 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17426 +
17427 + if (p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous)
17428 + return p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous(h_FmMac, newVal);
17429 +
17430 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17431 +}
17432 +
17433 +/* ......................................................................... */
17434 +
17435 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex)
17436 +{
17437 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17438 +
17439 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17440 +
17441 + if (p_FmMacControllerDriver->f_FM_MAC_AdjustLink)
17442 + return p_FmMacControllerDriver->f_FM_MAC_AdjustLink(h_FmMac, speed, fullDuplex);
17443 +
17444 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17445 +}
17446 +
17447 +/* ......................................................................... */
17448 +
17449 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac)
17450 +{
17451 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17452 +
17453 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17454 +
17455 + if (p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg)
17456 + return p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg(h_FmMac);
17457 +
17458 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17459 +}
17460 +
17461 +/* ......................................................................... */
17462 +
17463 +t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data)
17464 +{
17465 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17466 +
17467 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17468 +
17469 + if (p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg)
17470 + return p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg(h_FmMac, phyAddr, reg, data);
17471 +
17472 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17473 +}
17474 +
17475 +/* ......................................................................... */
17476 +
17477 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data)
17478 +{
17479 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17480 +
17481 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17482 +
17483 + if (p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg)
17484 + return p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg(h_FmMac, phyAddr, reg, p_Data);
17485 +
17486 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17487 +}
17488 +
17489 +/* ......................................................................... */
17490 +
17491 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac)
17492 +{
17493 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17494 +
17495 + SANITY_CHECK_RETURN_VALUE(p_FmMacControllerDriver, E_INVALID_HANDLE, 0);
17496 +
17497 + if (p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength)
17498 + return p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength(h_FmMac);
17499 +
17500 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17501 + return 0;
17502 +}
17503 +
17504 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17505 +/*****************************************************************************/
17506 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac)
17507 +{
17508 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17509 +
17510 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17511 +
17512 + if (p_FmMacControllerDriver->f_FM_MAC_DumpRegs)
17513 + return p_FmMacControllerDriver->f_FM_MAC_DumpRegs(h_FmMac);
17514 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17515 +}
17516 +#endif /* (defined(DEBUG_ERRORS) && ... */
17517 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
17518 new file mode 100644
17519 index 00000000..ba3b9133
17520 --- /dev/null
17521 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
17522 @@ -0,0 +1,226 @@
17523 +/*
17524 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17525 + *
17526 + * Redistribution and use in source and binary forms, with or without
17527 + * modification, are permitted provided that the following conditions are met:
17528 + * * Redistributions of source code must retain the above copyright
17529 + * notice, this list of conditions and the following disclaimer.
17530 + * * Redistributions in binary form must reproduce the above copyright
17531 + * notice, this list of conditions and the following disclaimer in the
17532 + * documentation and/or other materials provided with the distribution.
17533 + * * Neither the name of Freescale Semiconductor nor the
17534 + * names of its contributors may be used to endorse or promote products
17535 + * derived from this software without specific prior written permission.
17536 + *
17537 + *
17538 + * ALTERNATIVELY, this software may be distributed under the terms of the
17539 + * GNU General Public License ("GPL") as published by the Free Software
17540 + * Foundation, either version 2 of that License or (at your option) any
17541 + * later version.
17542 + *
17543 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17544 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17545 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17546 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17547 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17548 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17549 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17550 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17551 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17552 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17553 + */
17554 +
17555 +
17556 +/******************************************************************************
17557 + @File fm_mac.h
17558 +
17559 + @Description FM MAC ...
17560 +*//***************************************************************************/
17561 +#ifndef __FM_MAC_H
17562 +#define __FM_MAC_H
17563 +
17564 +#include "std_ext.h"
17565 +#include "error_ext.h"
17566 +#include "list_ext.h"
17567 +#include "fm_mac_ext.h"
17568 +#include "fm_common.h"
17569 +
17570 +
17571 +#define __ERR_MODULE__ MODULE_FM_MAC
17572 +
17573 +/**************************************************************************//**
17574 + @Description defaults
17575 +*//***************************************************************************/
17576 +
17577 +
17578 +#define DEFAULT_halfDuplex FALSE
17579 +#define DEFAULT_padAndCrcEnable TRUE
17580 +#define DEFAULT_resetOnInit FALSE
17581 +
17582 +
17583 +typedef struct {
17584 + uint64_t addr; /* Ethernet Address */
17585 + t_List node;
17586 +} t_EthHashEntry;
17587 +#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node)
17588 +
17589 +typedef struct {
17590 + uint16_t size;
17591 + t_List *p_Lsts;
17592 +} t_EthHash;
17593 +
17594 +typedef struct {
17595 + t_Error (*f_FM_MAC_Init) (t_Handle h_FmMac);
17596 + t_Error (*f_FM_MAC_Free) (t_Handle h_FmMac);
17597 +
17598 + t_Error (*f_FM_MAC_SetStatistics) (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
17599 + t_Error (*f_FM_MAC_ConfigLoopback) (t_Handle h_FmMac, bool newVal);
17600 + t_Error (*f_FM_MAC_ConfigMaxFrameLength) (t_Handle h_FmMac, uint16_t newVal);
17601 + t_Error (*f_FM_MAC_ConfigWan) (t_Handle h_FmMac, bool flag);
17602 + t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal);
17603 + t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal);
17604 + t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal);
17605 + t_Error (*f_FM_MAC_ConfigTbiPhyAddr) (t_Handle h_FmMac, uint8_t newVal);
17606 + t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable);
17607 + t_Error (*f_FM_MAC_ConfigResetOnInit) (t_Handle h_FmMac, bool enable);
17608 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17609 + t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac);
17610 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17611 +
17612 + t_Error (*f_FM_MAC_SetException) (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
17613 +
17614 + t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode);
17615 + t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode);
17616 + t_Error (*f_FM_MAC_Resume) (t_Handle h_FmMac);
17617 + t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac);
17618 + t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac);
17619 + t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait);
17620 +
17621 + t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac,
17622 + uint16_t pauseTime);
17623 + t_Error (*f_FM_MAC_SetTxPauseFrames) (t_Handle h_FmMac,
17624 + uint8_t priority,
17625 + uint16_t pauseTime,
17626 + uint16_t threshTime);
17627 + t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en);
17628 +
17629 + t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac);
17630 + t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
17631 + t_Error (*f_FM_MAC_GetFrameSizeCounters) (t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
17632 +
17633 + t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17634 + t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17635 + t_Error (*f_FM_MAC_RemoveHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17636 + t_Error (*f_FM_MAC_AddExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17637 + t_Error (*f_FM_MAC_RemovelExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17638 +
17639 + t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal);
17640 + t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
17641 + t_Error (*f_FM_MAC_RestartAutoneg) (t_Handle h_FmMac);
17642 +
17643 + t_Error (*f_FM_MAC_SetWakeOnLan) (t_Handle h_FmMac, bool en);
17644 +
17645 + t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId);
17646 +
17647 + t_Error (*f_FM_MAC_GetVersion) (t_Handle h_FmMac, uint32_t *macVersion);
17648 +
17649 + uint16_t (*f_FM_MAC_GetMaxFrameLength) (t_Handle h_FmMac);
17650 +
17651 + t_Error (*f_FM_MAC_MII_WritePhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
17652 + t_Error (*f_FM_MAC_MII_ReadPhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
17653 +
17654 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17655 + t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac);
17656 +#endif /* (defined(DEBUG_ERRORS) && ... */
17657 +
17658 + t_Handle h_Fm;
17659 + t_FmRevisionInfo fmRevInfo;
17660 + e_EnetMode enetMode;
17661 + uint8_t macId;
17662 + bool resetOnInit;
17663 + uint16_t clkFreq;
17664 +} t_FmMacControllerDriver;
17665 +
17666 +
17667 +#if (DPAA_VERSION == 10)
17668 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam);
17669 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams);
17670 +#else
17671 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam);
17672 +#endif /* (DPAA_VERSION == 10) */
17673 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
17674 +
17675 +
17676 +/* ........................................................................... */
17677 +
17678 +static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst)
17679 +{
17680 + t_EthHashEntry *p_HashEntry = NULL;
17681 + if (!LIST_IsEmpty(p_AddrLst))
17682 + {
17683 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next);
17684 + LIST_DelAndInit(&p_HashEntry->node);
17685 + }
17686 + return p_HashEntry;
17687 +}
17688 +
17689 +/* ........................................................................... */
17690 +
17691 +static __inline__ void FreeHashTable(t_EthHash *p_Hash)
17692 +{
17693 + t_EthHashEntry *p_HashEntry;
17694 + int i = 0;
17695 +
17696 + if (p_Hash)
17697 + {
17698 + if (p_Hash->p_Lsts)
17699 + {
17700 + for (i=0; i<p_Hash->size; i++)
17701 + {
17702 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17703 + while (p_HashEntry)
17704 + {
17705 + XX_Free(p_HashEntry);
17706 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17707 + }
17708 + }
17709 +
17710 + XX_Free(p_Hash->p_Lsts);
17711 + }
17712 +
17713 + XX_Free(p_Hash);
17714 + }
17715 +}
17716 +
17717 +/* ........................................................................... */
17718 +
17719 +static __inline__ t_EthHash * AllocHashTable(uint16_t size)
17720 +{
17721 + uint32_t i;
17722 + t_EthHash *p_Hash;
17723 +
17724 + /* Allocate address hash table */
17725 + p_Hash = (t_EthHash *)XX_Malloc(sizeof(t_EthHash));
17726 + if (!p_Hash)
17727 + {
17728 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17729 + return NULL;
17730 + }
17731 + p_Hash->size = size;
17732 +
17733 + p_Hash->p_Lsts = (t_List *)XX_Malloc(p_Hash->size*sizeof(t_List));
17734 + if (!p_Hash->p_Lsts)
17735 + {
17736 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17737 + XX_Free(p_Hash);
17738 + return NULL;
17739 + }
17740 +
17741 + for (i=0 ; i<p_Hash->size; i++)
17742 + INIT_LIST(&p_Hash->p_Lsts[i]);
17743 +
17744 + return p_Hash;
17745 +}
17746 +
17747 +
17748 +#endif /* __FM_MAC_H */
17749 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
17750 new file mode 100644
17751 index 00000000..b6a4ca25
17752 --- /dev/null
17753 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
17754 @@ -0,0 +1,119 @@
17755 +/*
17756 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17757 + *
17758 + * Redistribution and use in source and binary forms, with or without
17759 + * modification, are permitted provided that the following conditions are met:
17760 + * * Redistributions of source code must retain the above copyright
17761 + * notice, this list of conditions and the following disclaimer.
17762 + * * Redistributions in binary form must reproduce the above copyright
17763 + * notice, this list of conditions and the following disclaimer in the
17764 + * documentation and/or other materials provided with the distribution.
17765 + * * Neither the name of Freescale Semiconductor nor the
17766 + * names of its contributors may be used to endorse or promote products
17767 + * derived from this software without specific prior written permission.
17768 + *
17769 + *
17770 + * ALTERNATIVELY, this software may be distributed under the terms of the
17771 + * GNU General Public License ("GPL") as published by the Free Software
17772 + * Foundation, either version 2 of that License or (at your option) any
17773 + * later version.
17774 + *
17775 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17776 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17777 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17778 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17779 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17780 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17781 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17782 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17783 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17784 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17785 + */
17786 +
17787 +
17788 +#include "fman_crc32.h"
17789 +#include "common/general.h"
17790 +
17791 +
17792 +/* precomputed CRC values for address hashing */
17793 +static const uint32_t crc_tbl[256] = {
17794 + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
17795 + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
17796 + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
17797 + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
17798 + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
17799 + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
17800 + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
17801 + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
17802 + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
17803 + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
17804 + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
17805 + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
17806 + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
17807 + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
17808 + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
17809 + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
17810 + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
17811 + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
17812 + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
17813 + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
17814 + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
17815 + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
17816 + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
17817 + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
17818 + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
17819 + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
17820 + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
17821 + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
17822 + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
17823 + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
17824 + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
17825 + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
17826 + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
17827 + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
17828 + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
17829 + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
17830 + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
17831 + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
17832 + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
17833 + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
17834 + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
17835 + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
17836 + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
17837 +};
17838 +
17839 +/* Get the mirrored value of a byte size number. (0x11010011 --> 0x11001011) */
17840 +static inline uint8_t get_mirror8(uint8_t n)
17841 +{
17842 + uint8_t mirror[16] = {
17843 + 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
17844 + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
17845 + };
17846 + return (uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4])));
17847 +}
17848 +
17849 +static inline uint32_t get_mirror32(uint32_t n)
17850 +{
17851 + return ((uint32_t)get_mirror8((uint8_t)(n))<<24) |
17852 + ((uint32_t)get_mirror8((uint8_t)(n>>8))<<16) |
17853 + ((uint32_t)get_mirror8((uint8_t)(n>>16))<<8) |
17854 + ((uint32_t)get_mirror8((uint8_t)(n>>24)));
17855 +}
17856 +
17857 +uint32_t get_mac_addr_crc(uint64_t _addr)
17858 +{
17859 + uint32_t i;
17860 + uint8_t data;
17861 + uint32_t crc;
17862 +
17863 + /* CRC calculation */
17864 + crc = 0xffffffff;
17865 + for (i = 0; i < 6; i++) {
17866 + data = (uint8_t)(_addr >> ((5-i)*8));
17867 + crc = crc ^ data;
17868 + crc = crc_tbl[crc&0xff] ^ (crc>>8);
17869 + }
17870 +
17871 + crc = get_mirror32(crc);
17872 + return crc;
17873 +}
17874 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
17875 new file mode 100644
17876 index 00000000..6e32fdc6
17877 --- /dev/null
17878 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
17879 @@ -0,0 +1,43 @@
17880 +/*
17881 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17882 + *
17883 + * Redistribution and use in source and binary forms, with or without
17884 + * modification, are permitted provided that the following conditions are met:
17885 + * * Redistributions of source code must retain the above copyright
17886 + * notice, this list of conditions and the following disclaimer.
17887 + * * Redistributions in binary form must reproduce the above copyright
17888 + * notice, this list of conditions and the following disclaimer in the
17889 + * documentation and/or other materials provided with the distribution.
17890 + * * Neither the name of Freescale Semiconductor nor the
17891 + * names of its contributors may be used to endorse or promote products
17892 + * derived from this software without specific prior written permission.
17893 + *
17894 + *
17895 + * ALTERNATIVELY, this software may be distributed under the terms of the
17896 + * GNU General Public License ("GPL") as published by the Free Software
17897 + * Foundation, either version 2 of that License or (at your option) any
17898 + * later version.
17899 + *
17900 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17901 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17902 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17903 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17904 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17905 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17906 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17907 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17908 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17909 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17910 + */
17911 +
17912 +
17913 +#ifndef __FMAN_CRC32_H
17914 +#define __FMAN_CRC32_H
17915 +
17916 +#include "common/general.h"
17917 +
17918 +
17919 +uint32_t get_mac_addr_crc(uint64_t _addr);
17920 +
17921 +
17922 +#endif /* __FMAN_CRC32_H */
17923 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
17924 new file mode 100644
17925 index 00000000..5b092865
17926 --- /dev/null
17927 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
17928 @@ -0,0 +1,845 @@
17929 +/*
17930 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17931 + *
17932 + * Redistribution and use in source and binary forms, with or without
17933 + * modification, are permitted provided that the following conditions are met:
17934 + * * Redistributions of source code must retain the above copyright
17935 + * notice, this list of conditions and the following disclaimer.
17936 + * * Redistributions in binary form must reproduce the above copyright
17937 + * notice, this list of conditions and the following disclaimer in the
17938 + * documentation and/or other materials provided with the distribution.
17939 + * * Neither the name of Freescale Semiconductor nor the
17940 + * names of its contributors may be used to endorse or promote products
17941 + * derived from this software without specific prior written permission.
17942 + *
17943 + *
17944 + * ALTERNATIVELY, this software may be distributed under the terms of the
17945 + * GNU General Public License ("GPL") as published by the Free Software
17946 + * Foundation, either version 2 of that License or (at your option) any
17947 + * later version.
17948 + *
17949 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17950 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17951 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17952 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17953 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17954 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17955 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17956 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17957 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17958 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17959 + */
17960 +
17961 +
17962 +#include "fsl_fman_dtsec.h"
17963 +
17964 +
17965 +void fman_dtsec_stop_rx(struct dtsec_regs *regs)
17966 +{
17967 + /* Assert the graceful stop bit */
17968 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_GRS, &regs->rctrl);
17969 +}
17970 +
17971 +void fman_dtsec_stop_tx(struct dtsec_regs *regs)
17972 +{
17973 + /* Assert the graceful stop bit */
17974 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_GTS, &regs->tctrl);
17975 +}
17976 +
17977 +void fman_dtsec_start_tx(struct dtsec_regs *regs)
17978 +{
17979 + /* clear the graceful stop bit */
17980 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_GTS, &regs->tctrl);
17981 +}
17982 +
17983 +void fman_dtsec_start_rx(struct dtsec_regs *regs)
17984 +{
17985 + /* clear the graceful stop bit */
17986 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_GRS, &regs->rctrl);
17987 +}
17988 +
17989 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg)
17990 +{
17991 + cfg->halfdup_on = DEFAULT_HALFDUP_ON;
17992 + cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;
17993 + cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;
17994 + cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER;
17995 + cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF;
17996 + cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF;
17997 + cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL;
17998 + cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN;
17999 + cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST;
18000 + cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM;
18001 + cfg->rx_len_check = DEFAULT_RX_LEN_CHECK;
18002 + cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC;
18003 + cfg->tx_crc = DEFAULT_TX_CRC;
18004 + cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC;
18005 + cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;
18006 + cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/
18007 + cfg->rx_prepend = DEFAULT_RX_PREPEND;
18008 + cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN;
18009 + cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN;
18010 + cfg->preamble_len = DEFAULT_PREAMBLE_LEN;
18011 + cfg->rx_preamble = DEFAULT_RX_PREAMBLE;
18012 + cfg->tx_preamble = DEFAULT_TX_PREAMBLE;
18013 + cfg->loopback = DEFAULT_LOOPBACK;
18014 + cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN;
18015 + cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN;
18016 + cfg->rx_flow = DEFAULT_RX_FLOW;
18017 + cfg->tx_flow = DEFAULT_TX_FLOW;
18018 + cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD;
18019 + cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;
18020 + cfg->rx_promisc = DEFAULT_RX_PROMISC;
18021 + cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;
18022 + cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;
18023 + cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;
18024 + cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;
18025 + cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;
18026 + cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR;
18027 + cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN;
18028 +}
18029 +
18030 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
18031 + enum enet_interface iface_mode,
18032 + enum enet_speed iface_speed,
18033 + uint8_t *macaddr,
18034 + uint8_t fm_rev_maj,
18035 + uint8_t fm_rev_min,
18036 + uint32_t exception_mask)
18037 +{
18038 + bool is_rgmii = FALSE;
18039 + bool is_sgmii = FALSE;
18040 + bool is_qsgmii = FALSE;
18041 + int i;
18042 + uint32_t tmp;
18043 +
18044 +UNUSED(fm_rev_maj);UNUSED(fm_rev_min);
18045 +
18046 + /* let's start with a soft reset */
18047 + iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
18048 + iowrite32be(0, &regs->maccfg1);
18049 +
18050 + /*************dtsec_id2******************/
18051 + tmp = ioread32be(&regs->tsec_id2);
18052 +
18053 + /* check RGMII support */
18054 + if (iface_mode == E_ENET_IF_RGMII ||
18055 + iface_mode == E_ENET_IF_RMII)
18056 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
18057 + return -EINVAL;
18058 +
18059 + if (iface_mode == E_ENET_IF_SGMII ||
18060 + iface_mode == E_ENET_IF_MII)
18061 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
18062 + return -EINVAL;
18063 +
18064 + /***************ECNTRL************************/
18065 +
18066 + is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE);
18067 + is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE);
18068 + is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE);
18069 +
18070 + tmp = 0;
18071 + if (is_rgmii || iface_mode == E_ENET_IF_GMII)
18072 + tmp |= DTSEC_ECNTRL_GMIIM;
18073 + if (is_sgmii)
18074 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
18075 + if (is_qsgmii)
18076 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
18077 + DTSEC_ECNTRL_QSGMIIM);
18078 + if (is_rgmii)
18079 + tmp |= DTSEC_ECNTRL_RPM;
18080 + if (iface_speed == E_ENET_SPEED_100)
18081 + tmp |= DTSEC_ECNTRL_R100M;
18082 +
18083 + iowrite32be(tmp, &regs->ecntrl);
18084 + /***************ECNTRL************************/
18085 +
18086 + /***************TCTRL************************/
18087 + tmp = 0;
18088 + if (cfg->halfdup_on)
18089 + tmp |= DTSEC_TCTRL_THDF;
18090 + if (cfg->tx_time_stamp_en)
18091 + tmp |= DTSEC_TCTRL_TTSE;
18092 +
18093 + iowrite32be(tmp, &regs->tctrl);
18094 +
18095 + /***************TCTRL************************/
18096 +
18097 + /***************PTV************************/
18098 + tmp = 0;
18099 +
18100 +#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
18101 + if ((fm_rev_maj == 1) && (fm_rev_min == 0))
18102 + cfg->tx_pause_time += 2;
18103 +#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
18104 +
18105 + if (cfg->tx_pause_time)
18106 + tmp |= cfg->tx_pause_time;
18107 + if (cfg->tx_pause_time_extd)
18108 + tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST;
18109 + iowrite32be(tmp, &regs->ptv);
18110 +
18111 + /***************RCTRL************************/
18112 + tmp = 0;
18113 + tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16;
18114 + if (cfg->rx_ctrl_acc)
18115 + tmp |= RCTRL_CFA;
18116 + if (cfg->rx_group_hash_exd)
18117 + tmp |= RCTRL_GHTX;
18118 + if (cfg->rx_time_stamp_en)
18119 + tmp |= RCTRL_RTSE;
18120 + if (cfg->rx_drop_bcast)
18121 + tmp |= RCTRL_BC_REJ;
18122 + if (cfg->rx_short_frm)
18123 + tmp |= RCTRL_RSF;
18124 + if (cfg->rx_promisc)
18125 + tmp |= RCTRL_PROM;
18126 +
18127 + iowrite32be(tmp, &regs->rctrl);
18128 + /***************RCTRL************************/
18129 +
18130 + /*
18131 + * Assign a Phy Address to the TBI (TBIPA).
18132 + * Done also in cases where TBI is not selected to avoid conflict with
18133 + * the external PHY's Physical address
18134 + */
18135 + iowrite32be(cfg->tbipa, &regs->tbipa);
18136 +
18137 + /***************TMR_CTL************************/
18138 + iowrite32be(0, &regs->tmr_ctrl);
18139 +
18140 + if (cfg->ptp_tsu_en) {
18141 + tmp = 0;
18142 + tmp |= TMR_PEVENT_TSRE;
18143 + iowrite32be(tmp, &regs->tmr_pevent);
18144 +
18145 + if (cfg->ptp_exception_en) {
18146 + tmp = 0;
18147 + tmp |= TMR_PEMASK_TSREEN;
18148 + iowrite32be(tmp, &regs->tmr_pemask);
18149 + }
18150 + }
18151 +
18152 + /***************MACCFG1***********************/
18153 + tmp = 0;
18154 + if (cfg->loopback)
18155 + tmp |= MACCFG1_LOOPBACK;
18156 + if (cfg->rx_flow)
18157 + tmp |= MACCFG1_RX_FLOW;
18158 + if (cfg->tx_flow)
18159 + tmp |= MACCFG1_TX_FLOW;
18160 + iowrite32be(tmp, &regs->maccfg1);
18161 +
18162 + /***************MACCFG1***********************/
18163 +
18164 + /***************MACCFG2***********************/
18165 + tmp = 0;
18166 +
18167 + if (iface_speed < E_ENET_SPEED_1000)
18168 + tmp |= MACCFG2_NIBBLE_MODE;
18169 + else if (iface_speed == E_ENET_SPEED_1000)
18170 + tmp |= MACCFG2_BYTE_MODE;
18171 +
18172 + tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f)
18173 + << PREAMBLE_LENGTH_SHIFT;
18174 +
18175 + if (cfg->rx_preamble)
18176 + tmp |= MACCFG2_PRE_AM_Rx_EN;
18177 + if (cfg->tx_preamble)
18178 + tmp |= MACCFG2_PRE_AM_Tx_EN;
18179 + if (cfg->rx_len_check)
18180 + tmp |= MACCFG2_LENGTH_CHECK;
18181 + if (cfg->tx_pad_crc)
18182 + tmp |= MACCFG2_PAD_CRC_EN;
18183 + if (cfg->tx_crc)
18184 + tmp |= MACCFG2_CRC_EN;
18185 + if (!cfg->halfdup_on)
18186 + tmp |= MACCFG2_FULL_DUPLEX;
18187 + iowrite32be(tmp, &regs->maccfg2);
18188 +
18189 + /***************MACCFG2***********************/
18190 +
18191 + /***************IPGIFG************************/
18192 + tmp = (((cfg->non_back_to_back_ipg1 <<
18193 + IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)
18194 + & IPGIFG_NON_BACK_TO_BACK_IPG_1)
18195 + | ((cfg->non_back_to_back_ipg2 <<
18196 + IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)
18197 + & IPGIFG_NON_BACK_TO_BACK_IPG_2)
18198 + | ((cfg->min_ifg_enforcement <<
18199 + IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)
18200 + & IPGIFG_MIN_IFG_ENFORCEMENT)
18201 + | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));
18202 + iowrite32be(tmp, &regs->ipgifg);
18203 +
18204 + /***************IPGIFG************************/
18205 +
18206 + /***************HAFDUP************************/
18207 + tmp = 0;
18208 +
18209 + if (cfg->halfdup_alt_backoff_en)
18210 + tmp = (uint32_t)(HAFDUP_ALT_BEB |
18211 + ((cfg->halfdup_alt_backoff_val & 0x0000000f)
18212 + << HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
18213 + if (cfg->halfdup_bp_no_backoff)
18214 + tmp |= HAFDUP_BP_NO_BACKOFF;
18215 + if (cfg->halfdup_no_backoff)
18216 + tmp |= HAFDUP_NO_BACKOFF;
18217 + if (cfg->halfdup_excess_defer)
18218 + tmp |= HAFDUP_EXCESS_DEFER;
18219 + tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)
18220 + & HAFDUP_RETRANSMISSION_MAX);
18221 + tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);
18222 +
18223 + iowrite32be(tmp, &regs->hafdup);
18224 + /***************HAFDUP************************/
18225 +
18226 + /***************MAXFRM************************/
18227 + /* Initialize MAXFRM */
18228 + iowrite32be(cfg->maximum_frame, &regs->maxfrm);
18229 +
18230 + /***************MAXFRM************************/
18231 +
18232 + /***************CAM1************************/
18233 + iowrite32be(0xffffffff, &regs->cam1);
18234 + iowrite32be(0xffffffff, &regs->cam2);
18235 +
18236 + /***************IMASK************************/
18237 + iowrite32be(exception_mask, &regs->imask);
18238 + /***************IMASK************************/
18239 +
18240 + /***************IEVENT************************/
18241 + iowrite32be(0xffffffff, &regs->ievent);
18242 +
18243 + /***************MACSTNADDR1/2*****************/
18244 +
18245 + tmp = (uint32_t)((macaddr[5] << 24) |
18246 + (macaddr[4] << 16) |
18247 + (macaddr[3] << 8) |
18248 + macaddr[2]);
18249 + iowrite32be(tmp, &regs->macstnaddr1);
18250 +
18251 + tmp = (uint32_t)((macaddr[1] << 24) |
18252 + (macaddr[0] << 16));
18253 + iowrite32be(tmp, &regs->macstnaddr2);
18254 +
18255 + /***************MACSTNADDR1/2*****************/
18256 +
18257 + /*****************HASH************************/
18258 + for (i = 0; i < NUM_OF_HASH_REGS ; i++) {
18259 + /* Initialize IADDRx */
18260 + iowrite32be(0, &regs->igaddr[i]);
18261 + /* Initialize GADDRx */
18262 + iowrite32be(0, &regs->gaddr[i]);
18263 + }
18264 +
18265 + fman_dtsec_reset_stat(regs);
18266 +
18267 + return 0;
18268 +}
18269 +
18270 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs)
18271 +{
18272 + return (uint16_t)ioread32be(&regs->maxfrm);
18273 +}
18274 +
18275 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length)
18276 +{
18277 + iowrite32be(length, &regs->maxfrm);
18278 +}
18279 +
18280 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr)
18281 +{
18282 + uint32_t tmp;
18283 +
18284 + tmp = (uint32_t)((adr[5] << 24) |
18285 + (adr[4] << 16) |
18286 + (adr[3] << 8) |
18287 + adr[2]);
18288 + iowrite32be(tmp, &regs->macstnaddr1);
18289 +
18290 + tmp = (uint32_t)((adr[1] << 24) |
18291 + (adr[0] << 16));
18292 + iowrite32be(tmp, &regs->macstnaddr2);
18293 +}
18294 +
18295 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr)
18296 +{
18297 + uint32_t tmp1, tmp2;
18298 +
18299 + tmp1 = ioread32be(&regs->macstnaddr1);
18300 + tmp2 = ioread32be(&regs->macstnaddr2);
18301 +
18302 + macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16);
18303 + macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24);
18304 + macaddr[2] = (uint8_t)(tmp1 & 0x000000ff);
18305 + macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8);
18306 + macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16);
18307 + macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24);
18308 +}
18309 +
18310 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx)
18311 +{
18312 + int32_t bucket;
18313 + if (ghtx)
18314 + bucket = (int32_t)((crc >> 23) & 0x1ff);
18315 + else {
18316 + bucket = (int32_t)((crc >> 24) & 0xff);
18317 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
18318 + if (mcast)
18319 + bucket += 0x100;
18320 + }
18321 + fman_dtsec_set_bucket(regs, bucket, TRUE);
18322 +}
18323 +
18324 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable)
18325 +{
18326 + int reg_idx = (bucket >> 5) & 0xf;
18327 + int bit_idx = bucket & 0x1f;
18328 + uint32_t bit_mask = 0x80000000 >> bit_idx;
18329 + uint32_t *reg;
18330 +
18331 + if (reg_idx > 7)
18332 + reg = &regs->gaddr[reg_idx-8];
18333 + else
18334 + reg = &regs->igaddr[reg_idx];
18335 +
18336 + if (enable)
18337 + iowrite32be(ioread32be(reg) | bit_mask, reg);
18338 + else
18339 + iowrite32be(ioread32be(reg) & (~bit_mask), reg);
18340 +}
18341 +
18342 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast)
18343 +{
18344 + int i;
18345 + bool ghtx;
18346 +
18347 + ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? TRUE : FALSE);
18348 +
18349 + if (ucast || (ghtx && mcast)) {
18350 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18351 + iowrite32be(0, &regs->igaddr[i]);
18352 + }
18353 + if (mcast) {
18354 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18355 + iowrite32be(0, &regs->gaddr[i]);
18356 + }
18357 +}
18358 +
18359 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
18360 + uint8_t addr)
18361 +{
18362 + if (addr > 0 && addr < 32)
18363 + iowrite32be(addr, &regs->tbipa);
18364 + else
18365 + return -EINVAL;
18366 +
18367 + return 0;
18368 +}
18369 +
18370 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en)
18371 +{
18372 + uint32_t tmp;
18373 +
18374 + tmp = ioread32be(&regs->maccfg2);
18375 + if (en)
18376 + tmp |= MACCFG2_MAGIC_PACKET_EN;
18377 + else
18378 + tmp &= ~MACCFG2_MAGIC_PACKET_EN;
18379 + iowrite32be(tmp, &regs->maccfg2);
18380 +}
18381 +
18382 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
18383 + enum enet_interface iface_mode,
18384 + enum enet_speed speed, bool full_dx)
18385 +{
18386 + uint32_t tmp;
18387 +
18388 + UNUSED(iface_mode);
18389 +
18390 + if ((speed == E_ENET_SPEED_1000) && !full_dx)
18391 + return -EINVAL;
18392 +
18393 + tmp = ioread32be(&regs->maccfg2);
18394 + if (!full_dx)
18395 + tmp &= ~MACCFG2_FULL_DUPLEX;
18396 + else
18397 + tmp |= MACCFG2_FULL_DUPLEX;
18398 +
18399 + tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
18400 + if (speed < E_ENET_SPEED_1000)
18401 + tmp |= MACCFG2_NIBBLE_MODE;
18402 + else if (speed == E_ENET_SPEED_1000)
18403 + tmp |= MACCFG2_BYTE_MODE;
18404 + iowrite32be(tmp, &regs->maccfg2);
18405 +
18406 + tmp = ioread32be(&regs->ecntrl);
18407 + if (speed == E_ENET_SPEED_100)
18408 + tmp |= DTSEC_ECNTRL_R100M;
18409 + else
18410 + tmp &= ~DTSEC_ECNTRL_R100M;
18411 + iowrite32be(tmp, &regs->ecntrl);
18412 +
18413 + return 0;
18414 +}
18415 +
18416 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable)
18417 +{
18418 + uint32_t tmp;
18419 +
18420 + tmp = ioread32be(&regs->rctrl);
18421 +
18422 + if (enable)
18423 + tmp |= RCTRL_UPROM;
18424 + else
18425 + tmp &= ~RCTRL_UPROM;
18426 +
18427 + iowrite32be(tmp, &regs->rctrl);
18428 +}
18429 +
18430 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable)
18431 +{
18432 + uint32_t tmp;
18433 +
18434 + tmp = ioread32be(&regs->rctrl);
18435 +
18436 + if (enable)
18437 + tmp |= RCTRL_MPROM;
18438 + else
18439 + tmp &= ~RCTRL_MPROM;
18440 +
18441 + iowrite32be(tmp, &regs->rctrl);
18442 +}
18443 +
18444 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
18445 + uint32_t *car1, uint32_t *car2)
18446 +{
18447 + /* read carry registers */
18448 + *car1 = ioread32be(&regs->car1);
18449 + *car2 = ioread32be(&regs->car2);
18450 + /* clear carry registers */
18451 + if (*car1)
18452 + iowrite32be(*car1, &regs->car1);
18453 + if (*car2)
18454 + iowrite32be(*car2, &regs->car2);
18455 +
18456 + return (bool)((*car1 | *car2) ? TRUE : FALSE);
18457 +}
18458 +
18459 +void fman_dtsec_reset_stat(struct dtsec_regs *regs)
18460 +{
18461 + /* clear HW counters */
18462 + iowrite32be(ioread32be(&regs->ecntrl) |
18463 + DTSEC_ECNTRL_CLRCNT, &regs->ecntrl);
18464 +}
18465 +
18466 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level)
18467 +{
18468 + switch (level) {
18469 + case E_MAC_STAT_NONE:
18470 + iowrite32be(0xffffffff, &regs->cam1);
18471 + iowrite32be(0xffffffff, &regs->cam2);
18472 + iowrite32be(ioread32be(&regs->ecntrl) & ~DTSEC_ECNTRL_STEN,
18473 + &regs->ecntrl);
18474 + iowrite32be(ioread32be(&regs->imask) & ~DTSEC_IMASK_MSROEN,
18475 + &regs->imask);
18476 + break;
18477 + case E_MAC_STAT_PARTIAL:
18478 + iowrite32be(CAM1_ERRORS_ONLY, &regs->cam1);
18479 + iowrite32be(CAM2_ERRORS_ONLY, &regs->cam2);
18480 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18481 + &regs->ecntrl);
18482 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18483 + &regs->imask);
18484 + break;
18485 + case E_MAC_STAT_MIB_GRP1:
18486 + iowrite32be((uint32_t)~CAM1_MIB_GRP_1, &regs->cam1);
18487 + iowrite32be((uint32_t)~CAM2_MIB_GRP_1, &regs->cam2);
18488 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18489 + &regs->ecntrl);
18490 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18491 + &regs->imask);
18492 + break;
18493 + case E_MAC_STAT_FULL:
18494 + iowrite32be(0, &regs->cam1);
18495 + iowrite32be(0, &regs->cam2);
18496 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18497 + &regs->ecntrl);
18498 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18499 + &regs->imask);
18500 + break;
18501 + default:
18502 + return -EINVAL;
18503 + }
18504 +
18505 + return 0;
18506 +}
18507 +
18508 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en)
18509 +{
18510 + if (en) {
18511 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_RTSE,
18512 + &regs->rctrl);
18513 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_TTSE,
18514 + &regs->tctrl);
18515 + } else {
18516 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_RTSE,
18517 + &regs->rctrl);
18518 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_TTSE,
18519 + &regs->tctrl);
18520 + }
18521 +}
18522 +
18523 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18524 +{
18525 + uint32_t tmp;
18526 +
18527 + tmp = ioread32be(&regs->maccfg1);
18528 +
18529 + if (apply_rx)
18530 + tmp |= MACCFG1_RX_EN ;
18531 +
18532 + if (apply_tx)
18533 + tmp |= MACCFG1_TX_EN ;
18534 +
18535 + iowrite32be(tmp, &regs->maccfg1);
18536 +}
18537 +
18538 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num)
18539 +{
18540 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match1);
18541 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match2);
18542 +}
18543 +
18544 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
18545 + uint64_t addr,
18546 + uint8_t paddr_num)
18547 +{
18548 + uint32_t tmp;
18549 +
18550 + tmp = (uint32_t)(addr);
18551 + /* swap */
18552 + tmp = (((tmp & 0x000000FF) << 24) |
18553 + ((tmp & 0x0000FF00) << 8) |
18554 + ((tmp & 0x00FF0000) >> 8) |
18555 + ((tmp & 0xFF000000) >> 24));
18556 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match1);
18557 +
18558 + tmp = (uint32_t)(addr>>32);
18559 + /* swap */
18560 + tmp = (((tmp & 0x000000FF) << 24) |
18561 + ((tmp & 0x0000FF00) << 8) |
18562 + ((tmp & 0x00FF0000) >> 8) |
18563 + ((tmp & 0xFF000000) >> 24));
18564 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match2);
18565 +}
18566 +
18567 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18568 +{
18569 + uint32_t tmp;
18570 +
18571 + tmp = ioread32be(&regs->maccfg1);
18572 +
18573 + if (apply_rx)
18574 + tmp &= ~MACCFG1_RX_EN;
18575 +
18576 + if (apply_tx)
18577 + tmp &= ~MACCFG1_TX_EN;
18578 +
18579 + iowrite32be(tmp, &regs->maccfg1);
18580 +}
18581 +
18582 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time)
18583 +{
18584 + uint32_t ptv = 0;
18585 +
18586 + /* fixme: don't enable tx pause for half-duplex */
18587 +
18588 + if (time) {
18589 + ptv = ioread32be(&regs->ptv);
18590 + ptv &= 0xffff0000;
18591 + ptv |= time & 0x0000ffff;
18592 + iowrite32be(ptv, &regs->ptv);
18593 +
18594 + /* trigger the transmission of a flow-control pause frame */
18595 + iowrite32be(ioread32be(&regs->maccfg1) | MACCFG1_TX_FLOW,
18596 + &regs->maccfg1);
18597 + } else
18598 + iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
18599 + &regs->maccfg1);
18600 +}
18601 +
18602 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en)
18603 +{
18604 + uint32_t tmp;
18605 +
18606 + /* todo: check if mac is set to full-duplex */
18607 +
18608 + tmp = ioread32be(&regs->maccfg1);
18609 + if (en)
18610 + tmp |= MACCFG1_RX_FLOW;
18611 + else
18612 + tmp &= ~MACCFG1_RX_FLOW;
18613 + iowrite32be(tmp, &regs->maccfg1);
18614 +}
18615 +
18616 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs)
18617 +{
18618 + return ioread32be(&regs->rctrl);
18619 +}
18620 +
18621 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs)
18622 +{
18623 + return ioread32be(&regs->tsec_id);
18624 +}
18625 +
18626 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask)
18627 +{
18628 + return ioread32be(&regs->ievent) & ev_mask;
18629 +}
18630 +
18631 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask)
18632 +{
18633 + iowrite32be(ev_mask, &regs->ievent);
18634 +}
18635 +
18636 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs)
18637 +{
18638 + return ioread32be(&regs->imask);
18639 +}
18640 +
18641 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs)
18642 +{
18643 + uint32_t event;
18644 +
18645 + event = ioread32be(&regs->tmr_pevent);
18646 + event &= ioread32be(&regs->tmr_pemask);
18647 +
18648 + if (event)
18649 + iowrite32be(event, &regs->tmr_pevent);
18650 + return event;
18651 +}
18652 +
18653 +void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs)
18654 +{
18655 + iowrite32be(ioread32be(&regs->tmr_pemask) | TMR_PEMASK_TSREEN,
18656 + &regs->tmr_pemask);
18657 +}
18658 +
18659 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs)
18660 +{
18661 + iowrite32be(ioread32be(&regs->tmr_pemask) & ~TMR_PEMASK_TSREEN,
18662 + &regs->tmr_pemask);
18663 +}
18664 +
18665 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18666 +{
18667 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
18668 +}
18669 +
18670 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18671 +{
18672 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
18673 +}
18674 +
18675 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
18676 + enum dtsec_stat_counters reg_name)
18677 +{
18678 + uint32_t ret_val;
18679 +
18680 + switch (reg_name) {
18681 + case E_DTSEC_STAT_TR64:
18682 + ret_val = ioread32be(&regs->tr64);
18683 + break;
18684 + case E_DTSEC_STAT_TR127:
18685 + ret_val = ioread32be(&regs->tr127);
18686 + break;
18687 + case E_DTSEC_STAT_TR255:
18688 + ret_val = ioread32be(&regs->tr255);
18689 + break;
18690 + case E_DTSEC_STAT_TR511:
18691 + ret_val = ioread32be(&regs->tr511);
18692 + break;
18693 + case E_DTSEC_STAT_TR1K:
18694 + ret_val = ioread32be(&regs->tr1k);
18695 + break;
18696 + case E_DTSEC_STAT_TRMAX:
18697 + ret_val = ioread32be(&regs->trmax);
18698 + break;
18699 + case E_DTSEC_STAT_TRMGV:
18700 + ret_val = ioread32be(&regs->trmgv);
18701 + break;
18702 + case E_DTSEC_STAT_RBYT:
18703 + ret_val = ioread32be(&regs->rbyt);
18704 + break;
18705 + case E_DTSEC_STAT_RPKT:
18706 + ret_val = ioread32be(&regs->rpkt);
18707 + break;
18708 + case E_DTSEC_STAT_RMCA:
18709 + ret_val = ioread32be(&regs->rmca);
18710 + break;
18711 + case E_DTSEC_STAT_RBCA:
18712 + ret_val = ioread32be(&regs->rbca);
18713 + break;
18714 + case E_DTSEC_STAT_RXPF:
18715 + ret_val = ioread32be(&regs->rxpf);
18716 + break;
18717 + case E_DTSEC_STAT_RALN:
18718 + ret_val = ioread32be(&regs->raln);
18719 + break;
18720 + case E_DTSEC_STAT_RFLR:
18721 + ret_val = ioread32be(&regs->rflr);
18722 + break;
18723 + case E_DTSEC_STAT_RCDE:
18724 + ret_val = ioread32be(&regs->rcde);
18725 + break;
18726 + case E_DTSEC_STAT_RCSE:
18727 + ret_val = ioread32be(&regs->rcse);
18728 + break;
18729 + case E_DTSEC_STAT_RUND:
18730 + ret_val = ioread32be(&regs->rund);
18731 + break;
18732 + case E_DTSEC_STAT_ROVR:
18733 + ret_val = ioread32be(&regs->rovr);
18734 + break;
18735 + case E_DTSEC_STAT_RFRG:
18736 + ret_val = ioread32be(&regs->rfrg);
18737 + break;
18738 + case E_DTSEC_STAT_RJBR:
18739 + ret_val = ioread32be(&regs->rjbr);
18740 + break;
18741 + case E_DTSEC_STAT_RDRP:
18742 + ret_val = ioread32be(&regs->rdrp);
18743 + break;
18744 + case E_DTSEC_STAT_TFCS:
18745 + ret_val = ioread32be(&regs->tfcs);
18746 + break;
18747 + case E_DTSEC_STAT_TBYT:
18748 + ret_val = ioread32be(&regs->tbyt);
18749 + break;
18750 + case E_DTSEC_STAT_TPKT:
18751 + ret_val = ioread32be(&regs->tpkt);
18752 + break;
18753 + case E_DTSEC_STAT_TMCA:
18754 + ret_val = ioread32be(&regs->tmca);
18755 + break;
18756 + case E_DTSEC_STAT_TBCA:
18757 + ret_val = ioread32be(&regs->tbca);
18758 + break;
18759 + case E_DTSEC_STAT_TXPF:
18760 + ret_val = ioread32be(&regs->txpf);
18761 + break;
18762 + case E_DTSEC_STAT_TNCL:
18763 + ret_val = ioread32be(&regs->tncl);
18764 + break;
18765 + case E_DTSEC_STAT_TDRP:
18766 + ret_val = ioread32be(&regs->tdrp);
18767 + break;
18768 + default:
18769 + ret_val = 0;
18770 + }
18771 +
18772 + return ret_val;
18773 +}
18774 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
18775 new file mode 100644
18776 index 00000000..8819f8fc
18777 --- /dev/null
18778 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
18779 @@ -0,0 +1,163 @@
18780 +/*
18781 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18782 + *
18783 + * Redistribution and use in source and binary forms, with or without
18784 + * modification, are permitted provided that the following conditions are met:
18785 + * * Redistributions of source code must retain the above copyright
18786 + * notice, this list of conditions and the following disclaimer.
18787 + * * Redistributions in binary form must reproduce the above copyright
18788 + * notice, this list of conditions and the following disclaimer in the
18789 + * documentation and/or other materials provided with the distribution.
18790 + * * Neither the name of Freescale Semiconductor nor the
18791 + * names of its contributors may be used to endorse or promote products
18792 + * derived from this software without specific prior written permission.
18793 + *
18794 + *
18795 + * ALTERNATIVELY, this software may be distributed under the terms of the
18796 + * GNU General Public License ("GPL") as published by the Free Software
18797 + * Foundation, either version 2 of that License or (at your option) any
18798 + * later version.
18799 + *
18800 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18801 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18802 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18803 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18804 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18805 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18806 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18807 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18808 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18809 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18810 + */
18811 +
18812 +
18813 +#include "common/general.h"
18814 +#include "fsl_fman_dtsec_mii_acc.h"
18815 +
18816 +
18817 +/**
18818 + * dtsec_mii_get_div() - calculates the value of the dtsec mii divider
18819 + * @dtsec_freq: dtsec clock frequency (in Mhz)
18820 + *
18821 + * This function calculates the dtsec mii clock divider that determines
18822 + * the MII MDC clock. MII MDC clock will be set to work in the range
18823 + * of 1.5 to 2.5Mhz
18824 + * The output of this function is the value of MIIMCFG[MgmtClk] which
18825 + * implicitly determines the divider value.
18826 + * Note: the dTSEC system clock is equal to 1/2 of the FMan clock.
18827 + *
18828 + * The table below which reflects dtsec_mii_get_div() functionality
18829 + * shows the relations among dtsec_freq, MgmtClk, actual divider
18830 + * and the MII frequency:
18831 + *
18832 + * dtsec freq MgmtClk div MII freq Mhz
18833 + * [0.....80] 1 (1/4)(1/8) [0 to 2.5]
18834 + * [81...120] 2 (1/6)(1/8) [1.6 to 2.5]
18835 + * [121..160] 3 (1/8)(1/8) [1.8 to 2.5]
18836 + * [161..200] 4 (1/10)(1/8) [2.0 to 2.5]
18837 + * [201..280] 5 (1/14)(1/8) [1.8 to 2.5]
18838 + * [281..400] 6 (1/20)(1/8) [1.1 to 2.5]
18839 + * [401..560] 7 (1/28)(1/8) [1.8 to 2.5]
18840 + * [560..frq] 7 (1/28)(1/8) [frq/224]
18841 + *
18842 + * Returns: the MIIMCFG[MgmtClk] appropriate value
18843 + */
18844 +
18845 +static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq)
18846 +{
18847 + uint16_t mgmt_clk;
18848 +
18849 + if (dtsec_freq < 80) mgmt_clk = 1;
18850 + else if (dtsec_freq < 120) mgmt_clk = 2;
18851 + else if (dtsec_freq < 160) mgmt_clk = 3;
18852 + else if (dtsec_freq < 200) mgmt_clk = 4;
18853 + else if (dtsec_freq < 280) mgmt_clk = 5;
18854 + else if (dtsec_freq < 400) mgmt_clk = 6;
18855 + else mgmt_clk = 7;
18856 +
18857 + return (uint8_t)mgmt_clk;
18858 +}
18859 +
18860 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs)
18861 +{
18862 + /* Reset the management interface */
18863 + iowrite32be(ioread32be(&regs->miimcfg) | MIIMCFG_RESET_MGMT,
18864 + &regs->miimcfg);
18865 + iowrite32be(ioread32be(&regs->miimcfg) & ~MIIMCFG_RESET_MGMT,
18866 + &regs->miimcfg);
18867 +}
18868 +
18869 +
18870 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18871 + uint8_t reg, uint16_t data, uint16_t dtsec_freq)
18872 +{
18873 + uint32_t tmp;
18874 +
18875 + /* Setup the MII Mgmt clock speed */
18876 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18877 + wmb();
18878 +
18879 + /* Stop the MII management read cycle */
18880 + iowrite32be(0, &regs->miimcom);
18881 + /* Dummy read to make sure MIIMCOM is written */
18882 + tmp = ioread32be(&regs->miimcom);
18883 + wmb();
18884 +
18885 + /* Setting up MII Management Address Register */
18886 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18887 + iowrite32be(tmp, &regs->miimadd);
18888 + wmb();
18889 +
18890 + /* Setting up MII Management Control Register with data */
18891 + iowrite32be((uint32_t)data, &regs->miimcon);
18892 + /* Dummy read to make sure MIIMCON is written */
18893 + tmp = ioread32be(&regs->miimcon);
18894 + wmb();
18895 +
18896 + /* Wait until MII management write is complete */
18897 + /* todo: a timeout could be useful here */
18898 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
18899 + /* busy wait */;
18900 +
18901 + return 0;
18902 +}
18903 +
18904 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18905 + uint8_t reg, uint16_t *data, uint16_t dtsec_freq)
18906 +{
18907 + uint32_t tmp;
18908 +
18909 + /* Setup the MII Mgmt clock speed */
18910 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18911 + wmb();
18912 +
18913 + /* Setting up the MII Management Address Register */
18914 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18915 + iowrite32be(tmp, &regs->miimadd);
18916 + wmb();
18917 +
18918 + /* Perform an MII management read cycle */
18919 + iowrite32be(MIIMCOM_READ_CYCLE, &regs->miimcom);
18920 + /* Dummy read to make sure MIIMCOM is written */
18921 + tmp = ioread32be(&regs->miimcom);
18922 + wmb();
18923 +
18924 + /* Wait until MII management read is complete */
18925 + /* todo: a timeout could be useful here */
18926 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
18927 + /* busy wait */;
18928 +
18929 + /* Read MII management status */
18930 + *data = (uint16_t)ioread32be(&regs->miimstat);
18931 + wmb();
18932 +
18933 + iowrite32be(0, &regs->miimcom);
18934 + /* Dummy read to make sure MIIMCOM is written */
18935 + tmp = ioread32be(&regs->miimcom);
18936 +
18937 + if (*data == 0xffff)
18938 + return -ENXIO;
18939 +
18940 + return 0;
18941 +}
18942 +
18943 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
18944 new file mode 100644
18945 index 00000000..f31a92a2
18946 --- /dev/null
18947 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
18948 @@ -0,0 +1,532 @@
18949 +/*
18950 + * Copyright 2008-2012 Freescale Semiconductor Inc.
18951 + *
18952 + * Redistribution and use in source and binary forms, with or without
18953 + * modification, are permitted provided that the following conditions are met:
18954 + * * Redistributions of source code must retain the above copyright
18955 + * notice, this list of conditions and the following disclaimer.
18956 + * * Redistributions in binary form must reproduce the above copyright
18957 + * notice, this list of conditions and the following disclaimer in the
18958 + * documentation and/or other materials provided with the distribution.
18959 + * * Neither the name of Freescale Semiconductor nor the
18960 + * names of its contributors may be used to endorse or promote products
18961 + * derived from this software without specific prior written permission.
18962 + *
18963 + *
18964 + * ALTERNATIVELY, this software may be distributed under the terms of the
18965 + * GNU General Public License ("GPL") as published by the Free Software
18966 + * Foundation, either version 2 of that License or (at your option) any
18967 + * later version.
18968 + *
18969 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18970 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18971 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18972 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18973 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18974 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18975 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18976 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18977 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18978 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18979 + */
18980 +
18981 +
18982 +#include "fsl_fman_memac.h"
18983 +
18984 +
18985 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
18986 +{
18987 + return ioread32be(&regs->ievent) & ev_mask;
18988 +}
18989 +
18990 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
18991 +{
18992 + return ioread32be(&regs->imask);
18993 +}
18994 +
18995 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
18996 +{
18997 + iowrite32be(ev_mask, &regs->ievent);
18998 +}
18999 +
19000 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val)
19001 +{
19002 + uint32_t tmp;
19003 +
19004 + tmp = ioread32be(&regs->command_config);
19005 +
19006 + if (val)
19007 + tmp |= CMD_CFG_PROMIS_EN;
19008 + else
19009 + tmp &= ~CMD_CFG_PROMIS_EN;
19010 +
19011 + iowrite32be(tmp, &regs->command_config);
19012 +}
19013 +
19014 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
19015 + uint8_t paddr_num)
19016 +{
19017 + if (paddr_num == 0) {
19018 + iowrite32be(0, &regs->mac_addr0.mac_addr_l);
19019 + iowrite32be(0, &regs->mac_addr0.mac_addr_u);
19020 + } else {
19021 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_l);
19022 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_u);
19023 + }
19024 +}
19025 +
19026 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
19027 + uint8_t *adr,
19028 + uint8_t paddr_num)
19029 +{
19030 + uint32_t tmp0, tmp1;
19031 +
19032 + tmp0 = (uint32_t)(adr[0] |
19033 + adr[1] << 8 |
19034 + adr[2] << 16 |
19035 + adr[3] << 24);
19036 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19037 +
19038 + if (paddr_num == 0) {
19039 + iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l);
19040 + iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u);
19041 + } else {
19042 + iowrite32be(tmp0, &regs->mac_addr[paddr_num-1].mac_addr_l);
19043 + iowrite32be(tmp1, &regs->mac_addr[paddr_num-1].mac_addr_u);
19044 + }
19045 +}
19046 +
19047 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
19048 +{
19049 + uint32_t tmp;
19050 +
19051 + tmp = ioread32be(&regs->command_config);
19052 +
19053 + if (apply_rx)
19054 + tmp |= CMD_CFG_RX_EN;
19055 +
19056 + if (apply_tx)
19057 + tmp |= CMD_CFG_TX_EN;
19058 +
19059 + iowrite32be(tmp, &regs->command_config);
19060 +}
19061 +
19062 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
19063 +{
19064 + uint32_t tmp;
19065 +
19066 + tmp = ioread32be(&regs->command_config);
19067 +
19068 + if (apply_rx)
19069 + tmp &= ~CMD_CFG_RX_EN;
19070 +
19071 + if (apply_tx)
19072 + tmp &= ~CMD_CFG_TX_EN;
19073 +
19074 + iowrite32be(tmp, &regs->command_config);
19075 +}
19076 +
19077 +void fman_memac_reset_stat(struct memac_regs *regs)
19078 +{
19079 + uint32_t tmp;
19080 +
19081 + tmp = ioread32be(&regs->statn_config);
19082 +
19083 + tmp |= STATS_CFG_CLR;
19084 +
19085 + iowrite32be(tmp, &regs->statn_config);
19086 +
19087 + while (ioread32be(&regs->statn_config) & STATS_CFG_CLR);
19088 +}
19089 +
19090 +void fman_memac_reset(struct memac_regs *regs)
19091 +{
19092 + uint32_t tmp;
19093 +
19094 + tmp = ioread32be(&regs->command_config);
19095 +
19096 + tmp |= CMD_CFG_SW_RESET;
19097 +
19098 + iowrite32be(tmp, &regs->command_config);
19099 +
19100 + while (ioread32be(&regs->command_config) & CMD_CFG_SW_RESET);
19101 +}
19102 +
19103 +int fman_memac_init(struct memac_regs *regs,
19104 + struct memac_cfg *cfg,
19105 + enum enet_interface enet_interface,
19106 + enum enet_speed enet_speed,
19107 + bool slow_10g_if,
19108 + uint32_t exceptions)
19109 +{
19110 + uint32_t tmp;
19111 +
19112 + /* Config */
19113 + tmp = 0;
19114 + if (cfg->wan_mode_enable)
19115 + tmp |= CMD_CFG_WAN_MODE;
19116 + if (cfg->promiscuous_mode_enable)
19117 + tmp |= CMD_CFG_PROMIS_EN;
19118 + if (cfg->pause_forward_enable)
19119 + tmp |= CMD_CFG_PAUSE_FWD;
19120 + if (cfg->pause_ignore)
19121 + tmp |= CMD_CFG_PAUSE_IGNORE;
19122 + if (cfg->tx_addr_ins_enable)
19123 + tmp |= CMD_CFG_TX_ADDR_INS;
19124 + if (cfg->loopback_enable)
19125 + tmp |= CMD_CFG_LOOPBACK_EN;
19126 + if (cfg->cmd_frame_enable)
19127 + tmp |= CMD_CFG_CNT_FRM_EN;
19128 + if (cfg->send_idle_enable)
19129 + tmp |= CMD_CFG_SEND_IDLE;
19130 + if (cfg->no_length_check_enable)
19131 + tmp |= CMD_CFG_NO_LEN_CHK;
19132 + if (cfg->rx_sfd_any)
19133 + tmp |= CMD_CFG_SFD_ANY;
19134 + if (cfg->pad_enable)
19135 + tmp |= CMD_CFG_TX_PAD_EN;
19136 + if (cfg->wake_on_lan)
19137 + tmp |= CMD_CFG_MG;
19138 +
19139 + tmp |= CMD_CFG_CRC_FWD;
19140 +
19141 + iowrite32be(tmp, &regs->command_config);
19142 +
19143 + /* Max Frame Length */
19144 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
19145 +
19146 + /* Pause Time */
19147 + iowrite32be((uint32_t)cfg->pause_quanta, &regs->pause_quanta[0]);
19148 + iowrite32be((uint32_t)0, &regs->pause_thresh[0]);
19149 +
19150 + /* IF_MODE */
19151 + tmp = 0;
19152 + switch (enet_interface) {
19153 + case E_ENET_IF_XGMII:
19154 + case E_ENET_IF_XFI:
19155 + tmp |= IF_MODE_XGMII;
19156 + break;
19157 + default:
19158 + tmp |= IF_MODE_GMII;
19159 + if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable)
19160 + tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
19161 + }
19162 + iowrite32be(tmp, &regs->if_mode);
19163 +
19164 + /* TX_FIFO_SECTIONS */
19165 + tmp = 0;
19166 + if (enet_interface == E_ENET_IF_XGMII ||
19167 + enet_interface == E_ENET_IF_XFI) {
19168 + if(slow_10g_if) {
19169 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
19170 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19171 + } else {
19172 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
19173 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19174 + }
19175 + } else {
19176 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
19177 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
19178 + }
19179 + iowrite32be(tmp, &regs->tx_fifo_sections);
19180 +
19181 + /* clear all pending events and set-up interrupts */
19182 + fman_memac_ack_event(regs, 0xffffffff);
19183 + fman_memac_set_exception(regs, exceptions, TRUE);
19184 +
19185 + return 0;
19186 +}
19187 +
19188 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable)
19189 +{
19190 + uint32_t tmp;
19191 +
19192 + tmp = ioread32be(&regs->imask);
19193 + if (enable)
19194 + tmp |= val;
19195 + else
19196 + tmp &= ~val;
19197 +
19198 + iowrite32be(tmp, &regs->imask);
19199 +}
19200 +
19201 +void fman_memac_reset_filter_table(struct memac_regs *regs)
19202 +{
19203 + uint32_t i;
19204 + for (i = 0; i < 64; i++)
19205 + iowrite32be(i & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19206 +}
19207 +
19208 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc)
19209 +{
19210 + iowrite32be(crc | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19211 +}
19212 +
19213 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
19214 +{
19215 + iowrite32be(val, &regs->hashtable_ctrl);
19216 +}
19217 +
19218 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs)
19219 +{
19220 + uint32_t tmp;
19221 +
19222 + tmp = ioread32be(&regs->maxfrm);
19223 +
19224 + return(uint16_t)tmp;
19225 +}
19226 +
19227 +
19228 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
19229 + uint8_t priority,
19230 + uint16_t pause_time,
19231 + uint16_t thresh_time)
19232 +{
19233 + uint32_t tmp;
19234 +
19235 + tmp = ioread32be(&regs->tx_fifo_sections);
19236 +
19237 + if (priority == 0xff) {
19238 + GET_TX_EMPTY_DEFAULT_VALUE(tmp);
19239 + iowrite32be(tmp, &regs->tx_fifo_sections);
19240 +
19241 + tmp = ioread32be(&regs->command_config);
19242 + tmp &= ~CMD_CFG_PFC_MODE;
19243 + priority = 0;
19244 + } else {
19245 + GET_TX_EMPTY_PFC_VALUE(tmp);
19246 + iowrite32be(tmp, &regs->tx_fifo_sections);
19247 +
19248 + tmp = ioread32be(&regs->command_config);
19249 + tmp |= CMD_CFG_PFC_MODE;
19250 + }
19251 +
19252 + iowrite32be(tmp, &regs->command_config);
19253 +
19254 + tmp = ioread32be(&regs->pause_quanta[priority / 2]);
19255 + if (priority % 2)
19256 + tmp &= 0x0000FFFF;
19257 + else
19258 + tmp &= 0xFFFF0000;
19259 + tmp |= ((uint32_t)pause_time << (16 * (priority % 2)));
19260 + iowrite32be(tmp, &regs->pause_quanta[priority / 2]);
19261 +
19262 + tmp = ioread32be(&regs->pause_thresh[priority / 2]);
19263 + if (priority % 2)
19264 + tmp &= 0x0000FFFF;
19265 + else
19266 + tmp &= 0xFFFF0000;
19267 + tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2)));
19268 + iowrite32be(tmp, &regs->pause_thresh[priority / 2]);
19269 +}
19270 +
19271 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable)
19272 +{
19273 + uint32_t tmp;
19274 +
19275 + tmp = ioread32be(&regs->command_config);
19276 + if (enable)
19277 + tmp |= CMD_CFG_PAUSE_IGNORE;
19278 + else
19279 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19280 +
19281 + iowrite32be(tmp, &regs->command_config);
19282 +}
19283 +
19284 +void fman_memac_set_wol(struct memac_regs *regs, bool enable)
19285 +{
19286 + uint32_t tmp;
19287 +
19288 + tmp = ioread32be(&regs->command_config);
19289 +
19290 + if (enable)
19291 + tmp |= CMD_CFG_MG;
19292 + else
19293 + tmp &= ~CMD_CFG_MG;
19294 +
19295 + iowrite32be(tmp, &regs->command_config);
19296 +}
19297 +
19298 +#define GET_MEMAC_CNTR_64(bn) \
19299 + (ioread32be(&regs->bn ## _l) | \
19300 + ((uint64_t)ioread32be(&regs->bn ## _u) << 32))
19301 +
19302 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
19303 + enum memac_counters reg_name)
19304 +{
19305 + uint64_t ret_val;
19306 +
19307 + switch (reg_name) {
19308 + case E_MEMAC_COUNTER_R64:
19309 + ret_val = GET_MEMAC_CNTR_64(r64);
19310 + break;
19311 + case E_MEMAC_COUNTER_T64:
19312 + ret_val = GET_MEMAC_CNTR_64(t64);
19313 + break;
19314 + case E_MEMAC_COUNTER_R127:
19315 + ret_val = GET_MEMAC_CNTR_64(r127);
19316 + break;
19317 + case E_MEMAC_COUNTER_T127:
19318 + ret_val = GET_MEMAC_CNTR_64(t127);
19319 + break;
19320 + case E_MEMAC_COUNTER_R255:
19321 + ret_val = GET_MEMAC_CNTR_64(r255);
19322 + break;
19323 + case E_MEMAC_COUNTER_T255:
19324 + ret_val = GET_MEMAC_CNTR_64(t255);
19325 + break;
19326 + case E_MEMAC_COUNTER_R511:
19327 + ret_val = GET_MEMAC_CNTR_64(r511);
19328 + break;
19329 + case E_MEMAC_COUNTER_T511:
19330 + ret_val = GET_MEMAC_CNTR_64(t511);
19331 + break;
19332 + case E_MEMAC_COUNTER_R1023:
19333 + ret_val = GET_MEMAC_CNTR_64(r1023);
19334 + break;
19335 + case E_MEMAC_COUNTER_T1023:
19336 + ret_val = GET_MEMAC_CNTR_64(t1023);
19337 + break;
19338 + case E_MEMAC_COUNTER_R1518:
19339 + ret_val = GET_MEMAC_CNTR_64(r1518);
19340 + break;
19341 + case E_MEMAC_COUNTER_T1518:
19342 + ret_val = GET_MEMAC_CNTR_64(t1518);
19343 + break;
19344 + case E_MEMAC_COUNTER_R1519X:
19345 + ret_val = GET_MEMAC_CNTR_64(r1519x);
19346 + break;
19347 + case E_MEMAC_COUNTER_T1519X:
19348 + ret_val = GET_MEMAC_CNTR_64(t1519x);
19349 + break;
19350 + case E_MEMAC_COUNTER_RFRG:
19351 + ret_val = GET_MEMAC_CNTR_64(rfrg);
19352 + break;
19353 + case E_MEMAC_COUNTER_RJBR:
19354 + ret_val = GET_MEMAC_CNTR_64(rjbr);
19355 + break;
19356 + case E_MEMAC_COUNTER_RDRP:
19357 + ret_val = GET_MEMAC_CNTR_64(rdrp);
19358 + break;
19359 + case E_MEMAC_COUNTER_RALN:
19360 + ret_val = GET_MEMAC_CNTR_64(raln);
19361 + break;
19362 + case E_MEMAC_COUNTER_TUND:
19363 + ret_val = GET_MEMAC_CNTR_64(tund);
19364 + break;
19365 + case E_MEMAC_COUNTER_ROVR:
19366 + ret_val = GET_MEMAC_CNTR_64(rovr);
19367 + break;
19368 + case E_MEMAC_COUNTER_RXPF:
19369 + ret_val = GET_MEMAC_CNTR_64(rxpf);
19370 + break;
19371 + case E_MEMAC_COUNTER_TXPF:
19372 + ret_val = GET_MEMAC_CNTR_64(txpf);
19373 + break;
19374 + case E_MEMAC_COUNTER_ROCT:
19375 + ret_val = GET_MEMAC_CNTR_64(roct);
19376 + break;
19377 + case E_MEMAC_COUNTER_RMCA:
19378 + ret_val = GET_MEMAC_CNTR_64(rmca);
19379 + break;
19380 + case E_MEMAC_COUNTER_RBCA:
19381 + ret_val = GET_MEMAC_CNTR_64(rbca);
19382 + break;
19383 + case E_MEMAC_COUNTER_RPKT:
19384 + ret_val = GET_MEMAC_CNTR_64(rpkt);
19385 + break;
19386 + case E_MEMAC_COUNTER_RUCA:
19387 + ret_val = GET_MEMAC_CNTR_64(ruca);
19388 + break;
19389 + case E_MEMAC_COUNTER_RERR:
19390 + ret_val = GET_MEMAC_CNTR_64(rerr);
19391 + break;
19392 + case E_MEMAC_COUNTER_TOCT:
19393 + ret_val = GET_MEMAC_CNTR_64(toct);
19394 + break;
19395 + case E_MEMAC_COUNTER_TMCA:
19396 + ret_val = GET_MEMAC_CNTR_64(tmca);
19397 + break;
19398 + case E_MEMAC_COUNTER_TBCA:
19399 + ret_val = GET_MEMAC_CNTR_64(tbca);
19400 + break;
19401 + case E_MEMAC_COUNTER_TUCA:
19402 + ret_val = GET_MEMAC_CNTR_64(tuca);
19403 + break;
19404 + case E_MEMAC_COUNTER_TERR:
19405 + ret_val = GET_MEMAC_CNTR_64(terr);
19406 + break;
19407 + default:
19408 + ret_val = 0;
19409 + }
19410 +
19411 + return ret_val;
19412 +}
19413 +
19414 +void fman_memac_adjust_link(struct memac_regs *regs,
19415 + enum enet_interface iface_mode,
19416 + enum enet_speed speed, bool full_dx)
19417 +{
19418 + uint32_t tmp;
19419 +
19420 + tmp = ioread32be(&regs->if_mode);
19421 +
19422 + if (full_dx)
19423 + tmp &= ~IF_MODE_HD;
19424 + else
19425 + tmp |= IF_MODE_HD;
19426 +
19427 + if (iface_mode == E_ENET_IF_RGMII) {
19428 + /* Configure RGMII in manual mode */
19429 + tmp &= ~IF_MODE_RGMII_AUTO;
19430 + tmp &= ~IF_MODE_RGMII_SP_MASK;
19431 +
19432 + if (full_dx)
19433 + tmp |= IF_MODE_RGMII_FD;
19434 + else
19435 + tmp &= ~IF_MODE_RGMII_FD;
19436 +
19437 + switch (speed) {
19438 + case E_ENET_SPEED_1000:
19439 + tmp |= IF_MODE_RGMII_1000;
19440 + break;
19441 + case E_ENET_SPEED_100:
19442 + tmp |= IF_MODE_RGMII_100;
19443 + break;
19444 + case E_ENET_SPEED_10:
19445 + tmp |= IF_MODE_RGMII_10;
19446 + break;
19447 + default:
19448 + break;
19449 + }
19450 + }
19451 +
19452 + iowrite32be(tmp, &regs->if_mode);
19453 +}
19454 +
19455 +void fman_memac_defconfig(struct memac_cfg *cfg)
19456 +{
19457 + cfg->reset_on_init = FALSE;
19458 + cfg->wan_mode_enable = FALSE;
19459 + cfg->promiscuous_mode_enable = FALSE;
19460 + cfg->pause_forward_enable = FALSE;
19461 + cfg->pause_ignore = FALSE;
19462 + cfg->tx_addr_ins_enable = FALSE;
19463 + cfg->loopback_enable = FALSE;
19464 + cfg->cmd_frame_enable = FALSE;
19465 + cfg->rx_error_discard = FALSE;
19466 + cfg->send_idle_enable = FALSE;
19467 + cfg->no_length_check_enable = TRUE;
19468 + cfg->lgth_check_nostdr = FALSE;
19469 + cfg->time_stamp_enable = FALSE;
19470 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
19471 + cfg->max_frame_length = DEFAULT_FRAME_LENGTH;
19472 + cfg->pause_quanta = DEFAULT_PAUSE_QUANTA;
19473 + cfg->pad_enable = TRUE;
19474 + cfg->phy_tx_ena_on = FALSE;
19475 + cfg->rx_sfd_any = FALSE;
19476 + cfg->rx_pbl_fwd = FALSE;
19477 + cfg->tx_pbl_fwd = FALSE;
19478 + cfg->debug_mode = FALSE;
19479 + cfg->wake_on_lan = FALSE;
19480 +}
19481 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
19482 new file mode 100755
19483 index 00000000..ccda11ec
19484 --- /dev/null
19485 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
19486 @@ -0,0 +1,213 @@
19487 +/*
19488 + * Copyright 2008-2013 Freescale Semiconductor Inc.
19489 + *
19490 + * Redistribution and use in source and binary forms, with or without
19491 + * modification, are permitted provided that the following conditions are met:
19492 + * * Redistributions of source code must retain the above copyright
19493 + * notice, this list of conditions and the following disclaimer.
19494 + * * Redistributions in binary form must reproduce the above copyright
19495 + * notice, this list of conditions and the following disclaimer in the
19496 + * documentation and/or other materials provided with the distribution.
19497 + * * Neither the name of Freescale Semiconductor nor the
19498 + * names of its contributors may be used to endorse or promote products
19499 + * derived from this software without specific prior written permission.
19500 + *
19501 + *
19502 + * ALTERNATIVELY, this software may be distributed under the terms of the
19503 + * GNU General Public License ("GPL") as published by the Free Software
19504 + * Foundation, either version 2 of that License or (at your option) any
19505 + * later version.
19506 + *
19507 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19508 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19509 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19510 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19511 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19512 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19513 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19514 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19515 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19516 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19517 + */
19518 +
19519 +
19520 +#include "fsl_fman_memac_mii_acc.h"
19521 +
19522 +static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19523 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19524 +{
19525 + uint32_t tmp_reg;
19526 +
19527 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19528 + /* Leave only MDIO_CLK_DIV bits set on */
19529 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19530 + /* Set maximum MDIO_HOLD value to allow phy to see
19531 + change of data signal */
19532 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19533 + /* Add 10G interface mode */
19534 + tmp_reg |= MDIO_CFG_ENC45;
19535 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19536 +
19537 + /* Wait for command completion */
19538 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19539 + udelay(1);
19540 +
19541 + /* Specify phy and register to be accessed */
19542 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19543 + iowrite32be(reg, &mii_regs->mdio_addr);
19544 + wmb();
19545 +
19546 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19547 + udelay(1);
19548 +
19549 + /* Write data */
19550 + iowrite32be(data, &mii_regs->mdio_data);
19551 + wmb();
19552 +
19553 + /* Wait for write transaction end */
19554 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19555 + udelay(1);
19556 +}
19557 +
19558 +static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19559 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19560 +{
19561 + uint32_t tmp_reg;
19562 +
19563 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19564 + /* Leave only MDIO_CLK_DIV bits set on */
19565 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19566 + /* Set maximum MDIO_HOLD value to allow phy to see
19567 + change of data signal */
19568 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19569 + /* Add 10G interface mode */
19570 + tmp_reg |= MDIO_CFG_ENC45;
19571 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19572 +
19573 + /* Wait for command completion */
19574 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19575 + udelay(1);
19576 +
19577 + /* Specify phy and register to be accessed */
19578 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19579 + iowrite32be(reg, &mii_regs->mdio_addr);
19580 + wmb();
19581 +
19582 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19583 + udelay(1);
19584 +
19585 + /* Read cycle */
19586 + tmp_reg = phy_addr;
19587 + tmp_reg |= MDIO_CTL_READ;
19588 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19589 + wmb();
19590 +
19591 + /* Wait for data to be available */
19592 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19593 + udelay(1);
19594 +
19595 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19596 +
19597 + /* Check if there was an error */
19598 + return ioread32be(&mii_regs->mdio_cfg);
19599 +}
19600 +
19601 +static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19602 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19603 +{
19604 + uint32_t tmp_reg;
19605 +
19606 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19607 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19608 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19609 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19610 +
19611 + /* Wait for command completion */
19612 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19613 + udelay(1);
19614 +
19615 + /* Write transaction */
19616 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19617 + tmp_reg |= reg;
19618 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19619 +
19620 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19621 + udelay(1);
19622 +
19623 + iowrite32be(data, &mii_regs->mdio_data);
19624 +
19625 + wmb();
19626 +
19627 + /* Wait for write transaction to end */
19628 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19629 + udelay(1);
19630 +}
19631 +
19632 +static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19633 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19634 +{
19635 + uint32_t tmp_reg;
19636 +
19637 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19638 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19639 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
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 + /* Read transaction */
19647 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19648 + tmp_reg |= reg;
19649 + tmp_reg |= MDIO_CTL_READ;
19650 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19651 +
19652 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19653 + udelay(1);
19654 +
19655 + /* Wait for data to be available */
19656 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19657 + udelay(1);
19658 +
19659 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19660 +
19661 + /* Check error */
19662 + return ioread32be(&mii_regs->mdio_cfg);
19663 +}
19664 +
19665 +/*****************************************************************************/
19666 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19667 + uint8_t phy_addr, uint8_t reg, uint16_t data,
19668 + enum enet_speed enet_speed)
19669 +{
19670 + /* Figure out interface type - 10G vs 1G.
19671 + In 10G interface both phy_addr and devAddr present. */
19672 + if (enet_speed == E_ENET_SPEED_10000)
19673 + write_phy_reg_10g(mii_regs, phy_addr, reg, data);
19674 + else
19675 + write_phy_reg_1g(mii_regs, phy_addr, reg, data);
19676 +
19677 + return 0;
19678 +}
19679 +
19680 +/*****************************************************************************/
19681 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19682 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
19683 + enum enet_speed enet_speed)
19684 +{
19685 + uint32_t ans;
19686 + /* Figure out interface type - 10G vs 1G.
19687 + In 10G interface both phy_addr and devAddr present. */
19688 + if (enet_speed == E_ENET_SPEED_10000)
19689 + ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data);
19690 + else
19691 + ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data);
19692 +
19693 + if (ans & MDIO_CFG_READ_ERR)
19694 + return -EINVAL;
19695 + return 0;
19696 +}
19697 +
19698 +/* ......................................................................... */
19699 +
19700 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
19701 new file mode 100644
19702 index 00000000..fff9d5de
19703 --- /dev/null
19704 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
19705 @@ -0,0 +1,367 @@
19706 +/*
19707 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19708 + *
19709 + * Redistribution and use in source and binary forms, with or without
19710 + * modification, are permitted provided that the following conditions are met:
19711 + * * Redistributions of source code must retain the above copyright
19712 + * notice, this list of conditions and the following disclaimer.
19713 + * * Redistributions in binary form must reproduce the above copyright
19714 + * notice, this list of conditions and the following disclaimer in the
19715 + * documentation and/or other materials provided with the distribution.
19716 + * * Neither the name of Freescale Semiconductor nor the
19717 + * names of its contributors may be used to endorse or promote products
19718 + * derived from this software without specific prior written permission.
19719 + *
19720 + *
19721 + * ALTERNATIVELY, this software may be distributed under the terms of the
19722 + * GNU General Public License ("GPL") as published by the Free Software
19723 + * Foundation, either version 2 of that License or (at your option) any
19724 + * later version.
19725 + *
19726 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19727 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19728 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19729 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19730 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19731 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19732 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19733 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19734 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19735 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19736 + */
19737 +
19738 +
19739 +#include "fsl_fman_tgec.h"
19740 +
19741 +
19742 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)
19743 +{
19744 + uint32_t tmp0, tmp1;
19745 +
19746 + tmp0 = (uint32_t)(adr[0] |
19747 + adr[1] << 8 |
19748 + adr[2] << 16 |
19749 + adr[3] << 24);
19750 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19751 + iowrite32be(tmp0, &regs->mac_addr_0);
19752 + iowrite32be(tmp1, &regs->mac_addr_1);
19753 +}
19754 +
19755 +void fman_tgec_reset_stat(struct tgec_regs *regs)
19756 +{
19757 + uint32_t tmp;
19758 +
19759 + tmp = ioread32be(&regs->command_config);
19760 +
19761 + tmp |= CMD_CFG_STAT_CLR;
19762 +
19763 + iowrite32be(tmp, &regs->command_config);
19764 +
19765 + while (ioread32be(&regs->command_config) & CMD_CFG_STAT_CLR) ;
19766 +}
19767 +
19768 +#define GET_TGEC_CNTR_64(bn) \
19769 + (((uint64_t)ioread32be(&regs->bn ## _u) << 32) | \
19770 + ioread32be(&regs->bn ## _l))
19771 +
19772 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)
19773 +{
19774 + uint64_t ret_val;
19775 +
19776 + switch (reg_name) {
19777 + case E_TGEC_COUNTER_R64:
19778 + ret_val = GET_TGEC_CNTR_64(r64);
19779 + break;
19780 + case E_TGEC_COUNTER_R127:
19781 + ret_val = GET_TGEC_CNTR_64(r127);
19782 + break;
19783 + case E_TGEC_COUNTER_R255:
19784 + ret_val = GET_TGEC_CNTR_64(r255);
19785 + break;
19786 + case E_TGEC_COUNTER_R511:
19787 + ret_val = GET_TGEC_CNTR_64(r511);
19788 + break;
19789 + case E_TGEC_COUNTER_R1023:
19790 + ret_val = GET_TGEC_CNTR_64(r1023);
19791 + break;
19792 + case E_TGEC_COUNTER_R1518:
19793 + ret_val = GET_TGEC_CNTR_64(r1518);
19794 + break;
19795 + case E_TGEC_COUNTER_R1519X:
19796 + ret_val = GET_TGEC_CNTR_64(r1519x);
19797 + break;
19798 + case E_TGEC_COUNTER_TRFRG:
19799 + ret_val = GET_TGEC_CNTR_64(trfrg);
19800 + break;
19801 + case E_TGEC_COUNTER_TRJBR:
19802 + ret_val = GET_TGEC_CNTR_64(trjbr);
19803 + break;
19804 + case E_TGEC_COUNTER_RDRP:
19805 + ret_val = GET_TGEC_CNTR_64(rdrp);
19806 + break;
19807 + case E_TGEC_COUNTER_RALN:
19808 + ret_val = GET_TGEC_CNTR_64(raln);
19809 + break;
19810 + case E_TGEC_COUNTER_TRUND:
19811 + ret_val = GET_TGEC_CNTR_64(trund);
19812 + break;
19813 + case E_TGEC_COUNTER_TROVR:
19814 + ret_val = GET_TGEC_CNTR_64(trovr);
19815 + break;
19816 + case E_TGEC_COUNTER_RXPF:
19817 + ret_val = GET_TGEC_CNTR_64(rxpf);
19818 + break;
19819 + case E_TGEC_COUNTER_TXPF:
19820 + ret_val = GET_TGEC_CNTR_64(txpf);
19821 + break;
19822 + case E_TGEC_COUNTER_ROCT:
19823 + ret_val = GET_TGEC_CNTR_64(roct);
19824 + break;
19825 + case E_TGEC_COUNTER_RMCA:
19826 + ret_val = GET_TGEC_CNTR_64(rmca);
19827 + break;
19828 + case E_TGEC_COUNTER_RBCA:
19829 + ret_val = GET_TGEC_CNTR_64(rbca);
19830 + break;
19831 + case E_TGEC_COUNTER_RPKT:
19832 + ret_val = GET_TGEC_CNTR_64(rpkt);
19833 + break;
19834 + case E_TGEC_COUNTER_RUCA:
19835 + ret_val = GET_TGEC_CNTR_64(ruca);
19836 + break;
19837 + case E_TGEC_COUNTER_RERR:
19838 + ret_val = GET_TGEC_CNTR_64(rerr);
19839 + break;
19840 + case E_TGEC_COUNTER_TOCT:
19841 + ret_val = GET_TGEC_CNTR_64(toct);
19842 + break;
19843 + case E_TGEC_COUNTER_TMCA:
19844 + ret_val = GET_TGEC_CNTR_64(tmca);
19845 + break;
19846 + case E_TGEC_COUNTER_TBCA:
19847 + ret_val = GET_TGEC_CNTR_64(tbca);
19848 + break;
19849 + case E_TGEC_COUNTER_TUCA:
19850 + ret_val = GET_TGEC_CNTR_64(tuca);
19851 + break;
19852 + case E_TGEC_COUNTER_TERR:
19853 + ret_val = GET_TGEC_CNTR_64(terr);
19854 + break;
19855 + default:
19856 + ret_val = 0;
19857 + }
19858 +
19859 + return ret_val;
19860 +}
19861 +
19862 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19863 +{
19864 + uint32_t tmp;
19865 +
19866 + tmp = ioread32be(&regs->command_config);
19867 + if (apply_rx)
19868 + tmp |= CMD_CFG_RX_EN;
19869 + if (apply_tx)
19870 + tmp |= CMD_CFG_TX_EN;
19871 + iowrite32be(tmp, &regs->command_config);
19872 +}
19873 +
19874 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19875 +{
19876 + uint32_t tmp_reg_32;
19877 +
19878 + tmp_reg_32 = ioread32be(&regs->command_config);
19879 + if (apply_rx)
19880 + tmp_reg_32 &= ~CMD_CFG_RX_EN;
19881 + if (apply_tx)
19882 + tmp_reg_32 &= ~CMD_CFG_TX_EN;
19883 + iowrite32be(tmp_reg_32, &regs->command_config);
19884 +}
19885 +
19886 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)
19887 +{
19888 + uint32_t tmp;
19889 +
19890 + tmp = ioread32be(&regs->command_config);
19891 + if (val)
19892 + tmp |= CMD_CFG_PROMIS_EN;
19893 + else
19894 + tmp &= ~CMD_CFG_PROMIS_EN;
19895 + iowrite32be(tmp, &regs->command_config);
19896 +}
19897 +
19898 +void fman_tgec_reset_filter_table(struct tgec_regs *regs)
19899 +{
19900 + uint32_t i;
19901 + for (i = 0; i < 512; i++)
19902 + iowrite32be(i & ~TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
19903 +}
19904 +
19905 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)
19906 +{
19907 + uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
19908 + iowrite32be(hash | TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
19909 +}
19910 +
19911 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)
19912 +{
19913 + iowrite32be(value, &regs->hashtable_ctrl);
19914 +}
19915 +
19916 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)
19917 +{
19918 + iowrite32be((uint32_t)pause_time, &regs->pause_quant);
19919 +}
19920 +
19921 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)
19922 +{
19923 + uint32_t tmp;
19924 +
19925 + tmp = ioread32be(&regs->command_config);
19926 + if (en)
19927 + tmp |= CMD_CFG_PAUSE_IGNORE;
19928 + else
19929 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19930 + iowrite32be(tmp, &regs->command_config);
19931 +}
19932 +
19933 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)
19934 +{
19935 + uint32_t tmp;
19936 +
19937 + tmp = ioread32be(&regs->command_config);
19938 + if (en)
19939 + tmp |= CMD_CFG_EN_TIMESTAMP;
19940 + else
19941 + tmp &= ~CMD_CFG_EN_TIMESTAMP;
19942 + iowrite32be(tmp, &regs->command_config);
19943 +}
19944 +
19945 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)
19946 +{
19947 + return ioread32be(&regs->ievent) & ev_mask;
19948 +}
19949 +
19950 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)
19951 +{
19952 + iowrite32be(ev_mask, &regs->ievent);
19953 +}
19954 +
19955 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)
19956 +{
19957 + return ioread32be(&regs->imask);
19958 +}
19959 +
19960 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)
19961 +{
19962 + uint32_t tmp0, tmp1;
19963 +
19964 + tmp0 = (uint32_t)(adr[0] |
19965 + adr[1] << 8 |
19966 + adr[2] << 16 |
19967 + adr[3] << 24);
19968 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19969 + iowrite32be(tmp0, &regs->mac_addr_2);
19970 + iowrite32be(tmp1, &regs->mac_addr_3);
19971 +}
19972 +
19973 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)
19974 +{
19975 + iowrite32be(0, &regs->mac_addr_2);
19976 + iowrite32be(0, &regs->mac_addr_3);
19977 +}
19978 +
19979 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs)
19980 +{
19981 + return ioread32be(&regs->tgec_id);
19982 +}
19983 +
19984 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
19985 +{
19986 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
19987 +}
19988 +
19989 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
19990 +{
19991 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
19992 +}
19993 +
19994 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)
19995 +{
19996 + return (uint16_t) ioread32be(&regs->maxfrm);
19997 +}
19998 +
19999 +void fman_tgec_defconfig(struct tgec_cfg *cfg)
20000 +{
20001 + cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;
20002 + cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;
20003 + cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;
20004 + cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;
20005 + cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;
20006 + cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;
20007 + cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;
20008 + cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;
20009 + cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;
20010 + cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;
20011 + cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;
20012 + cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;
20013 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
20014 + cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
20015 + cfg->pause_quant = DEFAULT_PAUSE_QUANT;
20016 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
20017 + cfg->skip_fman11_workaround = FALSE;
20018 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
20019 +}
20020 +
20021 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
20022 + uint32_t exception_mask)
20023 +{
20024 + uint32_t tmp;
20025 +
20026 + /* Config */
20027 + tmp = 0x40; /* CRC forward */
20028 + if (cfg->wan_mode_enable)
20029 + tmp |= CMD_CFG_WAN_MODE;
20030 + if (cfg->promiscuous_mode_enable)
20031 + tmp |= CMD_CFG_PROMIS_EN;
20032 + if (cfg->pause_forward_enable)
20033 + tmp |= CMD_CFG_PAUSE_FWD;
20034 + if (cfg->pause_ignore)
20035 + tmp |= CMD_CFG_PAUSE_IGNORE;
20036 + if (cfg->tx_addr_ins_enable)
20037 + tmp |= CMD_CFG_TX_ADDR_INS;
20038 + if (cfg->loopback_enable)
20039 + tmp |= CMD_CFG_LOOPBACK_EN;
20040 + if (cfg->cmd_frame_enable)
20041 + tmp |= CMD_CFG_CMD_FRM_EN;
20042 + if (cfg->rx_error_discard)
20043 + tmp |= CMD_CFG_RX_ER_DISC;
20044 + if (cfg->send_idle_enable)
20045 + tmp |= CMD_CFG_SEND_IDLE;
20046 + if (cfg->no_length_check_enable)
20047 + tmp |= CMD_CFG_NO_LEN_CHK;
20048 + if (cfg->time_stamp_enable)
20049 + tmp |= CMD_CFG_EN_TIMESTAMP;
20050 + iowrite32be(tmp, &regs->command_config);
20051 +
20052 + /* Max Frame Length */
20053 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
20054 + /* Pause Time */
20055 + iowrite32be(cfg->pause_quant, &regs->pause_quant);
20056 +
20057 + /* clear all pending events and set-up interrupts */
20058 + fman_tgec_ack_event(regs, 0xffffffff);
20059 + fman_tgec_enable_interrupt(regs, exception_mask);
20060 +
20061 + return 0;
20062 +}
20063 +
20064 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)
20065 +{
20066 + uint32_t tmp;
20067 +
20068 + /* restore the default tx ipg Length */
20069 + tmp = (ioread32be(&regs->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;
20070 +
20071 + iowrite32be(tmp, &regs->tx_ipg_len);
20072 +}
20073 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
20074 new file mode 100644
20075 index 00000000..0f299e72
20076 --- /dev/null
20077 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
20078 @@ -0,0 +1,1153 @@
20079 +/*
20080 + * Copyright 2008-2012 Freescale Semiconductor Inc.
20081 + *
20082 + * Redistribution and use in source and binary forms, with or without
20083 + * modification, are permitted provided that the following conditions are met:
20084 + * * Redistributions of source code must retain the above copyright
20085 + * notice, this list of conditions and the following disclaimer.
20086 + * * Redistributions in binary form must reproduce the above copyright
20087 + * notice, this list of conditions and the following disclaimer in the
20088 + * documentation and/or other materials provided with the distribution.
20089 + * * Neither the name of Freescale Semiconductor nor the
20090 + * names of its contributors may be used to endorse or promote products
20091 + * derived from this software without specific prior written permission.
20092 + *
20093 + *
20094 + * ALTERNATIVELY, this software may be distributed under the terms of the
20095 + * GNU General Public License ("GPL") as published by the Free Software
20096 + * Foundation, either version 2 of that License or (at your option) any
20097 + * later version.
20098 + *
20099 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20100 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20101 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20102 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
20103 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20104 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20105 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20106 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20107 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20108 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20109 + */
20110 +
20111 +
20112 +/******************************************************************************
20113 + @File memac.c
20114 +
20115 + @Description FM mEMAC driver
20116 +*//***************************************************************************/
20117 +
20118 +#include "std_ext.h"
20119 +#include "string_ext.h"
20120 +#include "error_ext.h"
20121 +#include "xx_ext.h"
20122 +#include "endian_ext.h"
20123 +#include "debug_ext.h"
20124 +
20125 +#include "fm_common.h"
20126 +#include "memac.h"
20127 +
20128 +
20129 +/*****************************************************************************/
20130 +/* Internal routines */
20131 +/*****************************************************************************/
20132 +
20133 +/* ......................................................................... */
20134 +
20135 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
20136 +{
20137 + uint64_t mask1, mask2;
20138 + uint32_t xorVal = 0;
20139 + uint8_t i, j;
20140 +
20141 + for (i=0; i<6; i++)
20142 + {
20143 + mask1 = ethAddr & (uint64_t)0x01;
20144 + ethAddr >>= 1;
20145 +
20146 + for (j=0; j<7; j++)
20147 + {
20148 + mask2 = ethAddr & (uint64_t)0x01;
20149 + mask1 ^= mask2;
20150 + ethAddr >>= 1;
20151 + }
20152 +
20153 + xorVal |= (mask1 << (5-i));
20154 + }
20155 +
20156 + return xorVal;
20157 +}
20158 +
20159 +/* ......................................................................... */
20160 +
20161 +static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr)
20162 +{
20163 + uint16_t tmpReg16;
20164 + e_EnetMode enetMode;
20165 +
20166 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20167 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20168 + to 1G one, so MII functions can work correctly. */
20169 + enetMode = p_Memac->enetMode;
20170 +
20171 + /* SGMII mode + AN enable */
20172 + tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
20173 + if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500)
20174 + tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII;
20175 +
20176 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20177 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20178 +
20179 + /* Device ability according to SGMII specification */
20180 + tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII;
20181 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20182 +
20183 + /* Adjust link timer for SGMII -
20184 + According to Cisco SGMII specification the timer should be 1.6 ms.
20185 + The link_timer register is configured in units of the clock.
20186 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20187 + unit = 1 / (125*10^6 Hz) = 8 ns.
20188 + 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40
20189 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20190 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20191 + 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
20192 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20193 + we always set up here a value of 2.5 SGMII. */
20194 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007);
20195 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120);
20196 +
20197 + /* Restart AN */
20198 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20199 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20200 +
20201 + /* Restore original enet mode */
20202 + p_Memac->enetMode = enetMode;
20203 +}
20204 +
20205 +/* ......................................................................... */
20206 +
20207 +static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr)
20208 +{
20209 + uint16_t tmpReg16;
20210 + e_EnetMode enetMode;
20211 +
20212 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20213 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20214 + to 1G one, so MII functions can work correctly. */
20215 + enetMode = p_Memac->enetMode;
20216 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20217 +
20218 + /* 1000BaseX mode */
20219 + tmpReg16 = PHY_SGMII_IF_MODE_1000X;
20220 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20221 +
20222 + /* AN Device capability */
20223 + tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X;
20224 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20225 +
20226 + /* Adjust link timer for SGMII -
20227 + For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
20228 + The link_timer register is configured in units of the clock.
20229 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20230 + unit = 1 / (125*10^6 Hz) = 8 ns.
20231 + 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
20232 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20233 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20234 + 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
20235 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20236 + we always set up here a value of 2.5 SGMII. */
20237 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f);
20238 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08);
20239 +
20240 + /* Restart AN */
20241 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20242 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20243 +
20244 + /* Restore original enet mode */
20245 + p_Memac->enetMode = enetMode;
20246 +}
20247 +
20248 +/* ......................................................................... */
20249 +
20250 +static t_Error CheckInitParameters(t_Memac *p_Memac)
20251 +{
20252 + e_FmMacType portType;
20253 +
20254 + portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20255 +
20256 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
20257 + if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS))
20258 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS));
20259 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
20260 +
20261 + if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS))
20262 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS));
20263 + if (p_Memac->addr == 0)
20264 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address"));
20265 + if (!p_Memac->f_Exception)
20266 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception"));
20267 + if (!p_Memac->f_Event)
20268 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event"));
20269 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
20270 + if (!p_Memac->p_MemacDriverParam->no_length_check_enable)
20271 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
20272 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
20273 +
20274 + return E_OK;
20275 +}
20276 +
20277 +/* ........................................................................... */
20278 +
20279 +static void MemacErrException(t_Handle h_Memac)
20280 +{
20281 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20282 + uint32_t event, imask;
20283 +
20284 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20285 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20286 +
20287 + /* Imask include both error and notification/event bits.
20288 + Leaving only error bits enabled by imask.
20289 + The imask error bits are shifted by 16 bits offset from
20290 + their corresponding location in the ievent - hence the >> 16 */
20291 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20292 +
20293 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20294 +
20295 + if (event & MEMAC_IEVNT_TS_ECC_ER)
20296 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR);
20297 + if (event & MEMAC_IEVNT_TX_ECC_ER)
20298 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
20299 + if (event & MEMAC_IEVNT_RX_ECC_ER)
20300 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
20301 +}
20302 +
20303 +static void MemacException(t_Handle h_Memac)
20304 +{
20305 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20306 + uint32_t event, imask;
20307 +
20308 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20309 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20310 +
20311 + /* Imask include both error and notification/event bits.
20312 + Leaving only error bits enabled by imask.
20313 + The imask error bits are shifted by 16 bits offset from
20314 + their corresponding location in the ievent - hence the >> 16 */
20315 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20316 +
20317 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20318 +
20319 + if (event & MEMAC_IEVNT_MGI)
20320 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION);
20321 +}
20322 +
20323 +/* ......................................................................... */
20324 +
20325 +static void FreeInitResources(t_Memac *p_Memac)
20326 +{
20327 + e_FmMacType portType;
20328 +
20329 + portType =
20330 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20331 +
20332 + if (portType == e_FM_MAC_10G)
20333 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20334 + else
20335 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20336 +
20337 + /* release the driver's group hash table */
20338 + FreeHashTable(p_Memac->p_MulticastAddrHash);
20339 + p_Memac->p_MulticastAddrHash = NULL;
20340 +
20341 + /* release the driver's individual hash table */
20342 + FreeHashTable(p_Memac->p_UnicastAddrHash);
20343 + p_Memac->p_UnicastAddrHash = NULL;
20344 +}
20345 +
20346 +
20347 +/*****************************************************************************/
20348 +/* mEMAC API routines */
20349 +/*****************************************************************************/
20350 +
20351 +/* ......................................................................... */
20352 +
20353 +static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode)
20354 +{
20355 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20356 +
20357 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20358 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20359 +
20360 + fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20361 +
20362 + return E_OK;
20363 +}
20364 +
20365 +/* ......................................................................... */
20366 +
20367 +static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode)
20368 +{
20369 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20370 +
20371 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20372 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20373 +
20374 + fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20375 +
20376 + return E_OK;
20377 +}
20378 +
20379 +/* ......................................................................... */
20380 +
20381 +static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool newVal)
20382 +{
20383 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20384 +
20385 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20386 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20387 +
20388 + fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal);
20389 +
20390 + return E_OK;
20391 +}
20392 +
20393 +/* .............................................................................. */
20394 +
20395 +static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex)
20396 +{
20397 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20398 +
20399 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20400 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20401 +
20402 + if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex))
20403 + RETURN_ERROR(MAJOR, E_CONFLICT,
20404 + ("Ethernet MAC 1G or 10G does not support half-duplex"));
20405 +
20406 + fman_memac_adjust_link(p_Memac->p_MemMap,
20407 + (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode),
20408 + (enum enet_speed)speed,
20409 + fullDuplex);
20410 + return E_OK;
20411 +}
20412 +
20413 +
20414 +/*****************************************************************************/
20415 +/* Memac Configs modification functions */
20416 +/*****************************************************************************/
20417 +
20418 +/* ......................................................................... */
20419 +
20420 +static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal)
20421 +{
20422 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20423 +
20424 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20425 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20426 +
20427 + p_Memac->p_MemacDriverParam->loopback_enable = newVal;
20428 +
20429 + return E_OK;
20430 +}
20431 +
20432 +/* ......................................................................... */
20433 +
20434 +static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal)
20435 +{
20436 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20437 +
20438 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20439 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20440 +
20441 + p_Memac->p_MemacDriverParam->wan_mode_enable = newVal;
20442 +
20443 + return E_OK;
20444 +}
20445 +
20446 +/* ......................................................................... */
20447 +
20448 +static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal)
20449 +{
20450 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20451 +
20452 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20453 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20454 +
20455 + p_Memac->p_MemacDriverParam->max_frame_length = newVal;
20456 +
20457 + return E_OK;
20458 +}
20459 +
20460 +/* ......................................................................... */
20461 +
20462 +static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal)
20463 +{
20464 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20465 +
20466 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20467 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20468 +
20469 + p_Memac->p_MemacDriverParam->pad_enable = newVal;
20470 +
20471 + return E_OK;
20472 +}
20473 +
20474 +/* ......................................................................... */
20475 +
20476 +static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal)
20477 +{
20478 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20479 +
20480 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20481 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20482 +
20483 + p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal;
20484 +
20485 + return E_OK;
20486 +}
20487 +
20488 +/* ......................................................................... */
20489 +
20490 +static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20491 +{
20492 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20493 + uint32_t bitMask = 0;
20494 +
20495 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20496 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20497 +
20498 + GET_EXCEPTION_FLAG(bitMask, exception);
20499 + if (bitMask)
20500 + {
20501 + if (enable)
20502 + p_Memac->exceptions |= bitMask;
20503 + else
20504 + p_Memac->exceptions &= ~bitMask;
20505 + }
20506 + else
20507 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20508 +
20509 + return E_OK;
20510 +}
20511 +
20512 +/* ......................................................................... */
20513 +
20514 +static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable)
20515 +{
20516 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20517 +
20518 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20519 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20520 +
20521 + p_Memac->p_MemacDriverParam->reset_on_init = enable;
20522 +
20523 + return E_OK;
20524 +}
20525 +
20526 +
20527 +/*****************************************************************************/
20528 +/* Memac Run Time API functions */
20529 +/*****************************************************************************/
20530 +
20531 +/* ......................................................................... */
20532 +
20533 +static t_Error MemacSetTxPauseFrames(t_Handle h_Memac,
20534 + uint8_t priority,
20535 + uint16_t pauseTime,
20536 + uint16_t threshTime)
20537 +{
20538 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20539 +
20540 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20541 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20542 +
20543 + if (priority != 0xFF)
20544 + {
20545 + bool PortConfigured, PreFetchEnabled;
20546 +
20547 + if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0)
20548 + RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled"));
20549 +
20550 + FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm,
20551 + p_Memac->fmMacControllerDriver.macId,
20552 + &PortConfigured,
20553 + &PreFetchEnabled);
20554 +
20555 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured)
20556 + DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20557 +
20558 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled)
20559 + DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20560 + }
20561 +
20562 + fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime);
20563 +
20564 + return E_OK;
20565 +}
20566 +
20567 +/* ......................................................................... */
20568 +
20569 +static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac,
20570 + uint16_t pauseTime)
20571 +{
20572 + return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0);
20573 +}
20574 +
20575 +/* ......................................................................... */
20576 +
20577 +static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en)
20578 +{
20579 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20580 +
20581 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20582 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20583 +
20584 + fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en);
20585 +
20586 + return E_OK;
20587 +}
20588 +
20589 +/* ......................................................................... */
20590 +
20591 +static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en)
20592 +{
20593 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20594 +
20595 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20596 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20597 +
20598 + fman_memac_set_wol(p_Memac->p_MemMap, en);
20599 +
20600 + return E_OK;
20601 +}
20602 +
20603 +/* .............................................................................. */
20604 +
20605 +static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac)
20606 +{
20607 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20608 +
20609 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20610 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20611 +UNUSED(p_Memac);
20612 +DBG(WARNING, ("mEMAC has 1588 always enabled!"));
20613 +
20614 + return E_OK;
20615 +}
20616 +
20617 +/* Counters handling */
20618 +/* ......................................................................... */
20619 +
20620 +static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics)
20621 +{
20622 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20623 +
20624 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20625 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20626 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
20627 +
20628 + p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
20629 + p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
20630 + p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
20631 + p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
20632 + p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
20633 + p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
20634 + p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
20635 +/* */
20636 + p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG);
20637 + p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR);
20638 +
20639 + p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP);
20640 + p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN);
20641 +
20642 + p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND);
20643 + p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR);
20644 +/* Pause */
20645 + p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF);
20646 + p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF);
20647 +
20648 +/* MIB II */
20649 + p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT);
20650 + p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA);
20651 + p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA);
20652 + p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA);
20653 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
20654 + + p_Statistics->ifInMcastPkts
20655 + + p_Statistics->ifInBcastPkts;
20656 + p_Statistics->ifInDiscards = 0;
20657 + p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR);
20658 +
20659 + p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT);
20660 + p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA);
20661 + p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA);
20662 + p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA);
20663 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
20664 + + p_Statistics->ifOutMcastPkts
20665 + + p_Statistics->ifOutBcastPkts;
20666 + p_Statistics->ifOutDiscards = 0;
20667 + p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR);
20668 +
20669 + return E_OK;
20670 +}
20671 +
20672 +/* ......................................................................... */
20673 +
20674 +static t_Error MemacGetFrameSizeCounters(t_Handle h_Memac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
20675 +{
20676 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20677 +
20678 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20679 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20680 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
20681 +
20682 + switch (type)
20683 + {
20684 + case e_COMM_MODE_NONE:
20685 + break;
20686 +
20687 + case e_COMM_MODE_RX:
20688 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
20689 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
20690 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
20691 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
20692 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
20693 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
20694 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
20695 + break;
20696 +
20697 + case e_COMM_MODE_TX:
20698 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
20699 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
20700 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
20701 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
20702 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
20703 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
20704 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
20705 + break;
20706 +
20707 + case e_COMM_MODE_RX_AND_TX:
20708 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64)
20709 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
20710 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127)
20711 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
20712 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255)
20713 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
20714 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511)
20715 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
20716 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023)
20717 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
20718 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518)
20719 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
20720 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X)
20721 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
20722 + break;
20723 + }
20724 +
20725 + return E_OK;
20726 +}
20727 +
20728 +/* ......................................................................... */
20729 +
20730 +static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr)
20731 +{
20732 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20733 +
20734 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20735 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20736 +
20737 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0);
20738 +
20739 + return E_OK;
20740 +}
20741 +
20742 +/* ......................................................................... */
20743 +
20744 +static t_Error MemacResetCounters (t_Handle h_Memac)
20745 +{
20746 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20747 +
20748 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20749 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20750 +
20751 + fman_memac_reset_stat(p_Memac->p_MemMap);
20752 +
20753 + return E_OK;
20754 +}
20755 +
20756 +/* ......................................................................... */
20757 +
20758 +static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20759 +{
20760 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20761 + uint64_t ethAddr;
20762 + uint8_t paddrNum;
20763 +
20764 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20765 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20766 +
20767 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20768 +
20769 + if (ethAddr & GROUP_ADDRESS)
20770 + /* Multicast address has no effect in PADDR */
20771 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
20772 +
20773 + /* Make sure no PADDR contains this address */
20774 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20775 + if (p_Memac->indAddrRegUsed[paddrNum])
20776 + if (p_Memac->paddr[paddrNum] == ethAddr)
20777 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
20778 +
20779 + /* Find first unused PADDR */
20780 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20781 + if (!(p_Memac->indAddrRegUsed[paddrNum]))
20782 + {
20783 + /* mark this PADDR as used */
20784 + p_Memac->indAddrRegUsed[paddrNum] = TRUE;
20785 + /* store address */
20786 + p_Memac->paddr[paddrNum] = ethAddr;
20787 +
20788 + /* put in hardware */
20789 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum);
20790 + p_Memac->numOfIndAddrInRegs++;
20791 +
20792 + return E_OK;
20793 + }
20794 +
20795 + /* No free PADDR */
20796 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
20797 +}
20798 +
20799 +/* ......................................................................... */
20800 +
20801 +static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20802 +{
20803 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20804 + uint64_t ethAddr;
20805 + uint8_t paddrNum;
20806 +
20807 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20808 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20809 +
20810 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20811 +
20812 + /* Find used PADDR containing this address */
20813 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20814 + {
20815 + if ((p_Memac->indAddrRegUsed[paddrNum]) &&
20816 + (p_Memac->paddr[paddrNum] == ethAddr))
20817 + {
20818 + /* mark this PADDR as not used */
20819 + p_Memac->indAddrRegUsed[paddrNum] = FALSE;
20820 + /* clear in hardware */
20821 + fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum);
20822 + p_Memac->numOfIndAddrInRegs--;
20823 +
20824 + return E_OK;
20825 + }
20826 + }
20827 +
20828 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
20829 +}
20830 +
20831 +/* ......................................................................... */
20832 +
20833 +static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId)
20834 +{
20835 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20836 +
20837 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20838 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20839 +
20840 + *macId = p_Memac->macId;
20841 +
20842 + return E_OK;
20843 +}
20844 +
20845 +/* ......................................................................... */
20846 +
20847 +
20848 +static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20849 +{
20850 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20851 + t_EthHashEntry *p_HashEntry;
20852 + uint32_t hash;
20853 + uint64_t ethAddr;
20854 +
20855 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20856 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20857 +
20858 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20859 +
20860 + if (!(ethAddr & GROUP_ADDRESS))
20861 + /* Unicast addresses not supported in hash */
20862 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
20863 +
20864 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20865 +
20866 + /* Create element to be added to the driver hash table */
20867 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
20868 + p_HashEntry->addr = ethAddr;
20869 + INIT_LIST(&p_HashEntry->node);
20870 +
20871 + LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]));
20872 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN));
20873 +
20874 + return E_OK;
20875 +}
20876 +
20877 +/* ......................................................................... */
20878 +
20879 +static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20880 +{
20881 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20882 + t_EthHashEntry *p_HashEntry = NULL;
20883 + t_List *p_Pos;
20884 + uint32_t hash;
20885 + uint64_t ethAddr;
20886 +
20887 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20888 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20889 +
20890 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20891 +
20892 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20893 +
20894 + LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20895 + {
20896 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
20897 + if (p_HashEntry->addr == ethAddr)
20898 + {
20899 + LIST_DelAndInit(&p_HashEntry->node);
20900 + XX_Free(p_HashEntry);
20901 + break;
20902 + }
20903 + }
20904 + if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20905 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN));
20906 +
20907 + return E_OK;
20908 +}
20909 +
20910 +
20911 +/* ......................................................................... */
20912 +
20913 +static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20914 +{
20915 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20916 + uint32_t bitMask = 0;
20917 +
20918 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20919 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20920 +
20921 + GET_EXCEPTION_FLAG(bitMask, exception);
20922 + if (bitMask)
20923 + {
20924 + if (enable)
20925 + p_Memac->exceptions |= bitMask;
20926 + else
20927 + p_Memac->exceptions &= ~bitMask;
20928 + }
20929 + else
20930 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20931 +
20932 + fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable);
20933 +
20934 + return E_OK;
20935 +}
20936 +
20937 +/* ......................................................................... */
20938 +
20939 +static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac)
20940 +{
20941 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20942 +
20943 + SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0);
20944 + SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0);
20945 +
20946 + return fman_memac_get_max_frame_len(p_Memac->p_MemMap);
20947 +}
20948 +
20949 +static t_Error MemacInitInternalPhy(t_Handle h_Memac)
20950 +{
20951 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20952 + uint8_t i, phyAddr;
20953 +
20954 + if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII)
20955 + {
20956 + /* Configure internal SGMII PHY */
20957 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
20958 + SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR);
20959 + else
20960 + SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR);
20961 + }
20962 + else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII)
20963 + {
20964 + /* Configure 4 internal SGMII PHYs */
20965 + for (i = 0; i < 4; i++)
20966 + {
20967 + /* QSGMII PHY address occupies 3 upper bits of 5-bit
20968 + phyAddress; the lower 2 bits are used to extend
20969 + register address space and access each one of 4
20970 + ports inside QSGMII. */
20971 + phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i);
20972 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
20973 + SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr);
20974 + else
20975 + SetupSgmiiInternalPhy(p_Memac, phyAddr);
20976 + }
20977 + }
20978 + return E_OK;
20979 +}
20980 +
20981 +/*****************************************************************************/
20982 +/* mEMAC Init & Free API */
20983 +/*****************************************************************************/
20984 +
20985 +/* ......................................................................... */
20986 +void *g_MemacRegs;
20987 +static t_Error MemacInit(t_Handle h_Memac)
20988 +{
20989 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20990 + struct memac_cfg *p_MemacDriverParam;
20991 + enum enet_interface enet_interface;
20992 + enum enet_speed enet_speed;
20993 + t_EnetAddr ethAddr;
20994 + e_FmMacType portType;
20995 + t_Error err;
20996 + bool slow_10g_if = FALSE;
20997 + if (p_Memac->macId == 3) /* This is a quick WA */
20998 + g_MemacRegs = p_Memac->p_MemMap;
20999 +
21000 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21001 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21002 + SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
21003 +
21004 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
21005 + if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 &&
21006 + p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4)
21007 + slow_10g_if = TRUE;
21008 +
21009 + CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters);
21010 +
21011 + p_MemacDriverParam = p_Memac->p_MemacDriverParam;
21012 +
21013 + portType =
21014 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
21015 +
21016 + /* First, reset the MAC if desired. */
21017 + if (p_MemacDriverParam->reset_on_init)
21018 + fman_memac_reset(p_Memac->p_MemMap);
21019 +
21020 + /* MAC Address */
21021 + MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr);
21022 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0);
21023 +
21024 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode);
21025 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode);
21026 +
21027 + fman_memac_init(p_Memac->p_MemMap,
21028 + p_Memac->p_MemacDriverParam,
21029 + enet_interface,
21030 + enet_speed,
21031 + slow_10g_if,
21032 + p_Memac->exceptions);
21033 +
21034 +#ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
21035 + {
21036 + uint32_t tmpReg = 0;
21037 +
21038 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
21039 + /* check the FMAN version - the bug exists only in rev1 */
21040 + if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) &&
21041 + (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0))
21042 + {
21043 + /* MAC strips CRC from received frames - this workaround should
21044 + decrease the likelihood of bug appearance
21045 + */
21046 + tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config);
21047 + tmpReg &= ~CMD_CFG_CRC_FWD;
21048 + WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg);
21049 + /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/
21050 + }
21051 + }
21052 +#endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */
21053 +
21054 + MemacInitInternalPhy(h_Memac);
21055 +
21056 + /* Max Frame Length */
21057 + err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm,
21058 + portType,
21059 + p_Memac->fmMacControllerDriver.macId,
21060 + p_MemacDriverParam->max_frame_length);
21061 + if (err)
21062 + RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED"));
21063 +
21064 + p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
21065 + if (!p_Memac->p_MulticastAddrHash)
21066 + {
21067 + FreeInitResources(p_Memac);
21068 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
21069 + }
21070 +
21071 + p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
21072 + if (!p_Memac->p_UnicastAddrHash)
21073 + {
21074 + FreeInitResources(p_Memac);
21075 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
21076 + }
21077 +
21078 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
21079 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
21080 + p_Memac->macId,
21081 + e_FM_INTR_TYPE_ERR,
21082 + MemacErrException,
21083 + p_Memac);
21084 +
21085 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
21086 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
21087 + p_Memac->macId,
21088 + e_FM_INTR_TYPE_NORMAL,
21089 + MemacException,
21090 + p_Memac);
21091 +
21092 + XX_Free(p_MemacDriverParam);
21093 + p_Memac->p_MemacDriverParam = NULL;
21094 +
21095 + return E_OK;
21096 +}
21097 +
21098 +/* ......................................................................... */
21099 +
21100 +static t_Error MemacFree(t_Handle h_Memac)
21101 +{
21102 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21103 +
21104 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21105 +
21106 + if (p_Memac->p_MemacDriverParam)
21107 + {
21108 + /* Called after config */
21109 + XX_Free(p_Memac->p_MemacDriverParam);
21110 + p_Memac->p_MemacDriverParam = NULL;
21111 + }
21112 + else
21113 + /* Called after init */
21114 + FreeInitResources(p_Memac);
21115 +
21116 + XX_Free(p_Memac);
21117 +
21118 + return E_OK;
21119 +}
21120 +
21121 +/* ......................................................................... */
21122 +
21123 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
21124 +{
21125 + p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit;
21126 + p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree;
21127 +
21128 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
21129 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback;
21130 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength;
21131 +
21132 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan;
21133 +
21134 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad;
21135 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */
21136 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck;
21137 +
21138 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException;
21139 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit;
21140 +
21141 + p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException;
21142 +
21143 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */
21144 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL;
21145 +
21146 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous;
21147 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink;
21148 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
21149 +
21150 + p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable;
21151 + p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable;
21152 + p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy;
21153 +
21154 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames;
21155 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames;
21156 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames;
21157 +
21158 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan;
21159 +
21160 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters;
21161 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics;
21162 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = MemacGetFrameSizeCounters;
21163 +
21164 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress;
21165 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress;
21166 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress;
21167 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress;
21168 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress;
21169 + p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId;
21170 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL;
21171 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength;
21172 +
21173 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg;
21174 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg;
21175 +}
21176 +
21177 +
21178 +/*****************************************************************************/
21179 +/* mEMAC Config Main Entry */
21180 +/*****************************************************************************/
21181 +
21182 +/* ......................................................................... */
21183 +
21184 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam)
21185 +{
21186 + t_Memac *p_Memac;
21187 + struct memac_cfg *p_MemacDriverParam;
21188 + uintptr_t baseAddr;
21189 +
21190 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
21191 +
21192 + baseAddr = p_FmMacParam->baseAddr;
21193 + /* Allocate memory for the mEMAC data structure */
21194 + p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac));
21195 + if (!p_Memac)
21196 + {
21197 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure"));
21198 + return NULL;
21199 + }
21200 + memset(p_Memac, 0, sizeof(t_Memac));
21201 + InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver);
21202 +
21203 + /* Allocate memory for the mEMAC driver parameters data structure */
21204 + p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg));
21205 + if (!p_MemacDriverParam)
21206 + {
21207 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters"));
21208 + XX_Free(p_Memac);
21209 + return NULL;
21210 + }
21211 + memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg));
21212 +
21213 + /* Plant parameter structure pointer */
21214 + p_Memac->p_MemacDriverParam = p_MemacDriverParam;
21215 +
21216 + fman_memac_defconfig(p_MemacDriverParam);
21217 +
21218 + p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
21219 +
21220 + p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr);
21221 + p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET);
21222 +
21223 + p_Memac->enetMode = p_FmMacParam->enetMode;
21224 + p_Memac->macId = p_FmMacParam->macId;
21225 + p_Memac->exceptions = MEMAC_default_exceptions;
21226 + p_Memac->f_Exception = p_FmMacParam->f_Exception;
21227 + p_Memac->f_Event = p_FmMacParam->f_Event;
21228 + p_Memac->h_App = p_FmMacParam->h_App;
21229 +
21230 + return p_Memac;
21231 +}
21232 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
21233 new file mode 100644
21234 index 00000000..2fd89dae
21235 --- /dev/null
21236 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
21237 @@ -0,0 +1,110 @@
21238 +/*
21239 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21240 + *
21241 + * Redistribution and use in source and binary forms, with or without
21242 + * modification, are permitted provided that the following conditions are met:
21243 + * * Redistributions of source code must retain the above copyright
21244 + * notice, this list of conditions and the following disclaimer.
21245 + * * Redistributions in binary form must reproduce the above copyright
21246 + * notice, this list of conditions and the following disclaimer in the
21247 + * documentation and/or other materials provided with the distribution.
21248 + * * Neither the name of Freescale Semiconductor nor the
21249 + * names of its contributors may be used to endorse or promote products
21250 + * derived from this software without specific prior written permission.
21251 + *
21252 + *
21253 + * ALTERNATIVELY, this software may be distributed under the terms of the
21254 + * GNU General Public License ("GPL") as published by the Free Software
21255 + * Foundation, either version 2 of that License or (at your option) any
21256 + * later version.
21257 + *
21258 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21259 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21260 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21261 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21262 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21263 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21264 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21265 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21266 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21267 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21268 + */
21269 +
21270 +
21271 +/******************************************************************************
21272 + @File memac.h
21273 +
21274 + @Description FM Multirate Ethernet MAC (mEMAC)
21275 +*//***************************************************************************/
21276 +#ifndef __MEMAC_H
21277 +#define __MEMAC_H
21278 +
21279 +#include "std_ext.h"
21280 +#include "error_ext.h"
21281 +#include "list_ext.h"
21282 +
21283 +#include "fsl_fman_memac_mii_acc.h"
21284 +#include "fm_mac.h"
21285 +#include "fsl_fman_memac.h"
21286 +
21287 +
21288 +#define MEMAC_default_exceptions \
21289 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI))
21290 +
21291 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
21292 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
21293 + bitMask = MEMAC_IMASK_TECC_ER; break; \
21294 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
21295 + bitMask = MEMAC_IMASK_RECC_ER; break; \
21296 + case e_FM_MAC_EX_TS_FIFO_ECC_ERR: \
21297 + bitMask = MEMAC_IMASK_TSECC_ER; break; \
21298 + case e_FM_MAC_EX_MAGIC_PACKET_INDICATION: \
21299 + bitMask = MEMAC_IMASK_MGI; break; \
21300 + default: bitMask = 0;break;}
21301 +
21302 +
21303 +typedef struct
21304 +{
21305 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
21306 + t_Handle h_App; /**< Handle to the upper layer application */
21307 + struct memac_regs *p_MemMap; /**< Pointer to MAC memory mapped registers */
21308 + struct memac_mii_access_mem_map *p_MiiMemMap; /**< Pointer to MII memory mapped registers */
21309 + uint64_t addr; /**< MAC address of device */
21310 + e_EnetMode enetMode; /**< Ethernet physical interface */
21311 + t_FmMacExceptionCallback *f_Exception;
21312 + int mdioIrq;
21313 + t_FmMacExceptionCallback *f_Event;
21314 + bool indAddrRegUsed[MEMAC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
21315 + uint64_t paddr[MEMAC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
21316 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
21317 + t_EthHash *p_MulticastAddrHash; /**< Pointer to driver's global address hash table */
21318 + t_EthHash *p_UnicastAddrHash; /**< Pointer to driver's individual address hash table */
21319 + bool debugMode;
21320 + uint8_t macId;
21321 + uint32_t exceptions;
21322 + struct memac_cfg *p_MemacDriverParam;
21323 +} t_Memac;
21324 +
21325 +
21326 +/* Internal PHY access */
21327 +#define PHY_MDIO_ADDR 0
21328 +
21329 +/* Internal PHY Registers - SGMII */
21330 +#define PHY_SGMII_CR_PHY_RESET 0x8000
21331 +#define PHY_SGMII_CR_RESET_AN 0x0200
21332 +#define PHY_SGMII_CR_DEF_VAL 0x1140
21333 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
21334 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
21335 +#define PHY_SGMII_IF_SPEED_GIGABIT 0x0008
21336 +#define PHY_SGMII_IF_MODE_AN 0x0002
21337 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
21338 +#define PHY_SGMII_IF_MODE_1000X 0x0000
21339 +
21340 +
21341 +#define MEMAC_TO_MII_OFFSET 0x030 /* Offset from the MEM map to the MDIO mem map */
21342 +
21343 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t data);
21344 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
21345 +
21346 +
21347 +#endif /* __MEMAC_H */
21348 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
21349 new file mode 100644
21350 index 00000000..56eaffbc
21351 --- /dev/null
21352 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
21353 @@ -0,0 +1,78 @@
21354 +/*
21355 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21356 + *
21357 + * Redistribution and use in source and binary forms, with or without
21358 + * modification, are permitted provided that the following conditions are met:
21359 + * * Redistributions of source code must retain the above copyright
21360 + * notice, this list of conditions and the following disclaimer.
21361 + * * Redistributions in binary form must reproduce the above copyright
21362 + * notice, this list of conditions and the following disclaimer in the
21363 + * documentation and/or other materials provided with the distribution.
21364 + * * Neither the name of Freescale Semiconductor nor the
21365 + * names of its contributors may be used to endorse or promote products
21366 + * derived from this software without specific prior written permission.
21367 + *
21368 + *
21369 + * ALTERNATIVELY, this software may be distributed under the terms of the
21370 + * GNU General Public License ("GPL") as published by the Free Software
21371 + * Foundation, either version 2 of that License or (at your option) any
21372 + * later version.
21373 + *
21374 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21375 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21376 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21377 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21378 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21379 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21380 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21381 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21382 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21383 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21384 + */
21385 +
21386 +
21387 +#include "error_ext.h"
21388 +#include "std_ext.h"
21389 +#include "fm_mac.h"
21390 +#include "memac.h"
21391 +#include "xx_ext.h"
21392 +
21393 +#include "fm_common.h"
21394 +#include "memac_mii_acc.h"
21395 +
21396 +
21397 +/*****************************************************************************/
21398 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac,
21399 + uint8_t phyAddr,
21400 + uint8_t reg,
21401 + uint16_t data)
21402 +{
21403 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21404 +
21405 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21406 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21407 +
21408 + return (t_Error)fman_memac_mii_write_phy_reg(p_Memac->p_MiiMemMap,
21409 + phyAddr,
21410 + reg,
21411 + data,
21412 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21413 +}
21414 +
21415 +/*****************************************************************************/
21416 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac,
21417 + uint8_t phyAddr,
21418 + uint8_t reg,
21419 + uint16_t *p_Data)
21420 +{
21421 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21422 +
21423 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21424 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21425 +
21426 + return fman_memac_mii_read_phy_reg(p_Memac->p_MiiMemMap,
21427 + phyAddr,
21428 + reg,
21429 + p_Data,
21430 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21431 +}
21432 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
21433 new file mode 100644
21434 index 00000000..325ec082
21435 --- /dev/null
21436 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
21437 @@ -0,0 +1,73 @@
21438 +/*
21439 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21440 + *
21441 + * Redistribution and use in source and binary forms, with or without
21442 + * modification, are permitted provided that the following conditions are met:
21443 + * * Redistributions of source code must retain the above copyright
21444 + * notice, this list of conditions and the following disclaimer.
21445 + * * Redistributions in binary form must reproduce the above copyright
21446 + * notice, this list of conditions and the following disclaimer in the
21447 + * documentation and/or other materials provided with the distribution.
21448 + * * Neither the name of Freescale Semiconductor nor the
21449 + * names of its contributors may be used to endorse or promote products
21450 + * derived from this software without specific prior written permission.
21451 + *
21452 + *
21453 + * ALTERNATIVELY, this software may be distributed under the terms of the
21454 + * GNU General Public License ("GPL") as published by the Free Software
21455 + * Foundation, either version 2 of that License or (at your option) any
21456 + * later version.
21457 + *
21458 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21459 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21460 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21461 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21462 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21463 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21464 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21465 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21466 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21467 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21468 + */
21469 +
21470 +
21471 +#ifndef __MEMAC_MII_ACC_H
21472 +#define __MEMAC_MII_ACC_H
21473 +
21474 +#include "std_ext.h"
21475 +
21476 +
21477 +/* MII Management Registers */
21478 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
21479 +#define MDIO_CFG_CLK_DIV_SHIFT 7
21480 +#define MDIO_CFG_HOLD_MASK 0x0000001c
21481 +#define MDIO_CFG_ENC45 0x00000040
21482 +#define MDIO_CFG_READ_ERR 0x00000002
21483 +#define MDIO_CFG_BSY 0x00000001
21484 +
21485 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
21486 +#define MDIO_CTL_READ 0x00008000
21487 +
21488 +#define MDIO_DATA_BSY 0x80000000
21489 +
21490 +#if defined(__MWERKS__) && !defined(__GNUC__)
21491 +#pragma pack(push,1)
21492 +#endif /* defined(__MWERKS__) && ... */
21493 +
21494 +/*----------------------------------------------------*/
21495 +/* MII Configuration Control Memory Map Registers */
21496 +/*----------------------------------------------------*/
21497 +typedef struct t_MemacMiiAccessMemMap
21498 +{
21499 + volatile uint32_t mdio_cfg; /* 0x030 */
21500 + volatile uint32_t mdio_ctrl; /* 0x034 */
21501 + volatile uint32_t mdio_data; /* 0x038 */
21502 + volatile uint32_t mdio_addr; /* 0x03c */
21503 +} t_MemacMiiAccessMemMap ;
21504 +
21505 +#if defined(__MWERKS__) && !defined(__GNUC__)
21506 +#pragma pack(pop)
21507 +#endif /* defined(__MWERKS__) && ... */
21508 +
21509 +
21510 +#endif /* __MEMAC_MII_ACC_H */
21511 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
21512 new file mode 100644
21513 index 00000000..eb00759f
21514 --- /dev/null
21515 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
21516 @@ -0,0 +1,1017 @@
21517 +/*
21518 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21519 + *
21520 + * Redistribution and use in source and binary forms, with or without
21521 + * modification, are permitted provided that the following conditions are met:
21522 + * * Redistributions of source code must retain the above copyright
21523 + * notice, this list of conditions and the following disclaimer.
21524 + * * Redistributions in binary form must reproduce the above copyright
21525 + * notice, this list of conditions and the following disclaimer in the
21526 + * documentation and/or other materials provided with the distribution.
21527 + * * Neither the name of Freescale Semiconductor nor the
21528 + * names of its contributors may be used to endorse or promote products
21529 + * derived from this software without specific prior written permission.
21530 + *
21531 + *
21532 + * ALTERNATIVELY, this software may be distributed under the terms of the
21533 + * GNU General Public License ("GPL") as published by the Free Software
21534 + * Foundation, either version 2 of that License or (at your option) any
21535 + * later version.
21536 + *
21537 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21538 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21539 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21540 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21541 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21542 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21543 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21544 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21545 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21546 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21547 + */
21548 +
21549 +
21550 +/******************************************************************************
21551 + @File tgec.c
21552 +
21553 + @Description FM 10G MAC ...
21554 +*//***************************************************************************/
21555 +
21556 +#include "std_ext.h"
21557 +#include "string_ext.h"
21558 +#include "error_ext.h"
21559 +#include "xx_ext.h"
21560 +#include "endian_ext.h"
21561 +#include "debug_ext.h"
21562 +#include "crc_mac_addr_ext.h"
21563 +
21564 +#include "fm_common.h"
21565 +#include "fsl_fman_tgec.h"
21566 +#include "tgec.h"
21567 +
21568 +
21569 +/*****************************************************************************/
21570 +/* Internal routines */
21571 +/*****************************************************************************/
21572 +
21573 +static t_Error CheckInitParameters(t_Tgec *p_Tgec)
21574 +{
21575 + if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)
21576 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));
21577 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
21578 + if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)
21579 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));
21580 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
21581 +
21582 + if (p_Tgec->addr == 0)
21583 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));
21584 + if (!p_Tgec->f_Exception)
21585 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));
21586 + if (!p_Tgec->f_Event)
21587 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));
21588 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
21589 + if (!p_Tgec->p_TgecDriverParam->no_length_check_enable)
21590 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
21591 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
21592 + return E_OK;
21593 +}
21594 +
21595 +/* ......................................................................... */
21596 +
21597 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
21598 +{
21599 + uint32_t crc;
21600 +
21601 + /* CRC calculation */
21602 + GET_MAC_ADDR_CRC(ethAddr, crc);
21603 +
21604 + crc = GetMirror32(crc);
21605 +
21606 + return crc;
21607 +}
21608 +
21609 +/* ......................................................................... */
21610 +
21611 +static void TgecErrException(t_Handle h_Tgec)
21612 +{
21613 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21614 + uint32_t event;
21615 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21616 +
21617 + /* do not handle MDIO events */
21618 + event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21619 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21620 +
21621 + fman_tgec_ack_event(p_TgecMemMap, event);
21622 +
21623 + if (event & TGEC_IMASK_REM_FAULT)
21624 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);
21625 + if (event & TGEC_IMASK_LOC_FAULT)
21626 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);
21627 + if (event & TGEC_IMASK_TX_ECC_ER)
21628 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
21629 + if (event & TGEC_IMASK_TX_FIFO_UNFL)
21630 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);
21631 + if (event & TGEC_IMASK_TX_FIFO_OVFL)
21632 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);
21633 + if (event & TGEC_IMASK_TX_ER)
21634 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);
21635 + if (event & TGEC_IMASK_RX_FIFO_OVFL)
21636 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);
21637 + if (event & TGEC_IMASK_RX_ECC_ER)
21638 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
21639 + if (event & TGEC_IMASK_RX_JAB_FRM)
21640 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);
21641 + if (event & TGEC_IMASK_RX_OVRSZ_FRM)
21642 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);
21643 + if (event & TGEC_IMASK_RX_RUNT_FRM)
21644 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);
21645 + if (event & TGEC_IMASK_RX_FRAG_FRM)
21646 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);
21647 + if (event & TGEC_IMASK_RX_LEN_ER)
21648 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);
21649 + if (event & TGEC_IMASK_RX_CRC_ER)
21650 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);
21651 + if (event & TGEC_IMASK_RX_ALIGN_ER)
21652 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);
21653 +}
21654 +
21655 +/* ......................................................................... */
21656 +
21657 +static void TgecException(t_Handle h_Tgec)
21658 +{
21659 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21660 + uint32_t event;
21661 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21662 +
21663 + /* handle only MDIO events */
21664 + event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21665 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21666 +
21667 + fman_tgec_ack_event(p_TgecMemMap, event);
21668 +
21669 + if (event & TGEC_IMASK_MDIO_SCAN_EVENT)
21670 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);
21671 + if (event & TGEC_IMASK_MDIO_CMD_CMPL)
21672 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);
21673 +}
21674 +
21675 +/* ......................................................................... */
21676 +
21677 +static void FreeInitResources(t_Tgec *p_Tgec)
21678 +{
21679 + if (p_Tgec->mdioIrq != NO_IRQ)
21680 + {
21681 + XX_DisableIntr(p_Tgec->mdioIrq);
21682 + XX_FreeIntr(p_Tgec->mdioIrq);
21683 + }
21684 +
21685 + FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);
21686 +
21687 + /* release the driver's group hash table */
21688 + FreeHashTable(p_Tgec->p_MulticastAddrHash);
21689 + p_Tgec->p_MulticastAddrHash = NULL;
21690 +
21691 + /* release the driver's individual hash table */
21692 + FreeHashTable(p_Tgec->p_UnicastAddrHash);
21693 + p_Tgec->p_UnicastAddrHash = NULL;
21694 +}
21695 +
21696 +
21697 +/*****************************************************************************/
21698 +/* 10G MAC API routines */
21699 +/*****************************************************************************/
21700 +
21701 +/* ......................................................................... */
21702 +
21703 +static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode)
21704 +{
21705 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21706 +
21707 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21708 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21709 +
21710 + fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21711 +
21712 + return E_OK;
21713 +}
21714 +
21715 +/* ......................................................................... */
21716 +
21717 +static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)
21718 +{
21719 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21720 +
21721 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21722 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21723 +
21724 + fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21725 +
21726 + return E_OK;
21727 +}
21728 +
21729 +/* ......................................................................... */
21730 +
21731 +static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)
21732 +{
21733 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21734 +
21735 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21736 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21737 +
21738 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal);
21739 +
21740 + return E_OK;
21741 +}
21742 +
21743 +
21744 +/*****************************************************************************/
21745 +/* Tgec Configs modification functions */
21746 +/*****************************************************************************/
21747 +
21748 +/* ......................................................................... */
21749 +
21750 +static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)
21751 +{
21752 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21753 +
21754 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21755 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21756 +
21757 + p_Tgec->p_TgecDriverParam->loopback_enable = newVal;
21758 +
21759 + return E_OK;
21760 +}
21761 +
21762 +/* ......................................................................... */
21763 +
21764 +static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)
21765 +{
21766 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21767 +
21768 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21769 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21770 +
21771 + p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal;
21772 +
21773 + return E_OK;
21774 +}
21775 +
21776 +/* ......................................................................... */
21777 +
21778 +static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)
21779 +{
21780 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21781 +
21782 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21783 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21784 +
21785 + p_Tgec->p_TgecDriverParam->max_frame_length = newVal;
21786 +
21787 + return E_OK;
21788 +}
21789 +
21790 +/* ......................................................................... */
21791 +
21792 +static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)
21793 +{
21794 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21795 +
21796 + UNUSED(newVal);
21797 +
21798 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21799 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21800 +
21801 + p_Tgec->p_TgecDriverParam->no_length_check_enable = !newVal;
21802 +
21803 + return E_OK;
21804 +}
21805 +
21806 +/* ......................................................................... */
21807 +
21808 +static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
21809 +{
21810 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21811 + uint32_t bitMask = 0;
21812 +
21813 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21814 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21815 +
21816 + GET_EXCEPTION_FLAG(bitMask, exception);
21817 + if (bitMask)
21818 + {
21819 + if (enable)
21820 + p_Tgec->exceptions |= bitMask;
21821 + else
21822 + p_Tgec->exceptions &= ~bitMask;
21823 + }
21824 + else
21825 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
21826 +
21827 + return E_OK;
21828 +}
21829 +
21830 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
21831 +/* ......................................................................... */
21832 +
21833 +static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)
21834 +{
21835 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21836 +
21837 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21838 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21839 +
21840 + p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE;
21841 +
21842 + return E_OK;
21843 +}
21844 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
21845 +
21846 +
21847 +/*****************************************************************************/
21848 +/* Tgec Run Time API functions */
21849 +/*****************************************************************************/
21850 +
21851 +/* ......................................................................... */
21852 +/* backward compatibility. will be removed in the future. */
21853 +static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)
21854 +{
21855 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21856 +
21857 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21858 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21859 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21860 +
21861 +
21862 + return E_OK;
21863 +}
21864 +
21865 +/* ......................................................................... */
21866 +
21867 +static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec,
21868 + uint8_t priority,
21869 + uint16_t pauseTime,
21870 + uint16_t threshTime)
21871 +{
21872 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21873 +
21874 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21875 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21876 +
21877 + UNUSED(priority); UNUSED(threshTime);
21878 +
21879 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21880 +
21881 + return E_OK;
21882 +}
21883 +
21884 +/* ......................................................................... */
21885 +
21886 +static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)
21887 +{
21888 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21889 +
21890 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21891 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21892 +
21893 + fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en);
21894 +
21895 + return E_OK;
21896 +}
21897 +
21898 +/* ......................................................................... */
21899 +
21900 +static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)
21901 +{
21902 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21903 + struct tgec_regs *p_TgecMemMap;
21904 +
21905 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21906 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21907 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
21908 +
21909 + p_TgecMemMap = p_Tgec->p_MemMap;
21910 +
21911 + p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
21912 + p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
21913 + p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
21914 + p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
21915 + p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
21916 + p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
21917 + p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
21918 +/* */
21919 + p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG);
21920 + p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR);
21921 +
21922 + p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP);
21923 + p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN);
21924 +
21925 + p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND);
21926 + p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR);
21927 +/* Pause */
21928 + p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF);
21929 + p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF);
21930 +
21931 +/* MIB II */
21932 + p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT);
21933 + p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA);
21934 + p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA);
21935 + p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA);
21936 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
21937 + + p_Statistics->ifInMcastPkts
21938 + + p_Statistics->ifInBcastPkts;
21939 + p_Statistics->ifInDiscards = 0;
21940 + p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR);
21941 +
21942 + p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT);
21943 + p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA);
21944 + p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA);
21945 + p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA);
21946 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
21947 + + p_Statistics->ifOutMcastPkts
21948 + + p_Statistics->ifOutBcastPkts;
21949 + p_Statistics->ifOutDiscards = 0;
21950 + p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR);
21951 +
21952 + return E_OK;
21953 +}
21954 +
21955 +/* ......................................................................... */
21956 +
21957 +static t_Error TgecGetFrameSizeCounters(t_Handle h_Tgec, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
21958 +{
21959 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21960 + struct tgec_regs *p_TgecMemMap;
21961 +
21962 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21963 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21964 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
21965 +
21966 + p_TgecMemMap = p_Tgec->p_MemMap;
21967 +
21968 + switch (type)
21969 + {
21970 + case e_COMM_MODE_NONE:
21971 + break;
21972 +
21973 + case e_COMM_MODE_RX:
21974 + p_FrameSizeCounters->count_pkts_64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
21975 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
21976 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
21977 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
21978 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
21979 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
21980 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
21981 + break;
21982 +
21983 + case e_COMM_MODE_TX:
21984 + //Tx counters not supported
21985 + break;
21986 +
21987 + case e_COMM_MODE_RX_AND_TX:
21988 + //Tx counters not supported
21989 + break;
21990 + }
21991 +
21992 + return E_OK;
21993 +}
21994 +
21995 +
21996 +/* ......................................................................... */
21997 +
21998 +static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)
21999 +{
22000 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22001 +
22002 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22003 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22004 +
22005 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1);
22006 +
22007 + return E_OK;
22008 +}
22009 +
22010 +/* ......................................................................... */
22011 +
22012 +static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)
22013 +{
22014 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22015 +
22016 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22017 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22018 +
22019 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0);
22020 +
22021 + return E_OK;
22022 +}
22023 +
22024 +/* ......................................................................... */
22025 +
22026 +static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)
22027 +{
22028 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22029 +
22030 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22031 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22032 +
22033 + p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
22034 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr));
22035 +
22036 + return E_OK;
22037 +}
22038 +
22039 +/* ......................................................................... */
22040 +
22041 +static t_Error TgecResetCounters (t_Handle h_Tgec)
22042 +{
22043 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22044 +
22045 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22046 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22047 +
22048 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
22049 +
22050 + return E_OK;
22051 +}
22052 +
22053 +/* ......................................................................... */
22054 +
22055 +static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22056 +{
22057 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
22058 + uint64_t ethAddr;
22059 + uint8_t paddrNum;
22060 +
22061 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22062 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22063 +
22064 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22065 +
22066 + if (ethAddr & GROUP_ADDRESS)
22067 + /* Multicast address has no effect in PADDR */
22068 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
22069 +
22070 + /* Make sure no PADDR contains this address */
22071 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
22072 + if (p_Tgec->indAddrRegUsed[paddrNum])
22073 + if (p_Tgec->paddr[paddrNum] == ethAddr)
22074 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
22075 +
22076 + /* Find first unused PADDR */
22077 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
22078 + {
22079 + if (!(p_Tgec->indAddrRegUsed[paddrNum]))
22080 + {
22081 + /* mark this PADDR as used */
22082 + p_Tgec->indAddrRegUsed[paddrNum] = TRUE;
22083 + /* store address */
22084 + p_Tgec->paddr[paddrNum] = ethAddr;
22085 +
22086 + /* put in hardware */
22087 + fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */);
22088 + p_Tgec->numOfIndAddrInRegs++;
22089 +
22090 + return E_OK;
22091 + }
22092 + }
22093 +
22094 + /* No free PADDR */
22095 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
22096 +}
22097 +
22098 +/* ......................................................................... */
22099 +
22100 +static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22101 +{
22102 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
22103 + uint64_t ethAddr;
22104 + uint8_t paddrNum;
22105 +
22106 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22107 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22108 +
22109 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22110 +
22111 + /* Find used PADDR containing this address */
22112 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
22113 + {
22114 + if ((p_Tgec->indAddrRegUsed[paddrNum]) &&
22115 + (p_Tgec->paddr[paddrNum] == ethAddr))
22116 + {
22117 + /* mark this PADDR as not used */
22118 + p_Tgec->indAddrRegUsed[paddrNum] = FALSE;
22119 + /* clear in hardware */
22120 + fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */);
22121 + p_Tgec->numOfIndAddrInRegs--;
22122 +
22123 + return E_OK;
22124 + }
22125 + }
22126 +
22127 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
22128 +}
22129 +
22130 +/* ......................................................................... */
22131 +
22132 +static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22133 +{
22134 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22135 + t_EthHashEntry *p_HashEntry;
22136 + uint32_t crc;
22137 + uint32_t hash;
22138 + uint64_t ethAddr;
22139 +
22140 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22141 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22142 +
22143 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22144 +
22145 + if (!(ethAddr & GROUP_ADDRESS))
22146 + /* Unicast addresses not supported in hash */
22147 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
22148 +
22149 + /* CRC calculation */
22150 + crc = GetMacAddrHashCode(ethAddr);
22151 +
22152 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
22153 +
22154 + /* Create element to be added to the driver hash table */
22155 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
22156 + p_HashEntry->addr = ethAddr;
22157 + INIT_LIST(&p_HashEntry->node);
22158 +
22159 + LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));
22160 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN));
22161 +
22162 + return E_OK;
22163 +}
22164 +
22165 +/* ......................................................................... */
22166 +
22167 +static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22168 +{
22169 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22170 + t_EthHashEntry *p_HashEntry = NULL;
22171 + t_List *p_Pos;
22172 + uint32_t crc;
22173 + uint32_t hash;
22174 + uint64_t ethAddr;
22175 +
22176 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22177 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22178 +
22179 + ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
22180 +
22181 + /* CRC calculation */
22182 + crc = GetMacAddrHashCode(ethAddr);
22183 +
22184 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
22185 +
22186 + LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
22187 + {
22188 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
22189 + if (p_HashEntry->addr == ethAddr)
22190 + {
22191 + LIST_DelAndInit(&p_HashEntry->node);
22192 + XX_Free(p_HashEntry);
22193 + break;
22194 + }
22195 + }
22196 + if (LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
22197 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN));
22198 +
22199 + return E_OK;
22200 +}
22201 +
22202 +/* ......................................................................... */
22203 +
22204 +static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)
22205 +{
22206 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22207 +
22208 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22209 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22210 +
22211 + UNUSED(p_Tgec);
22212 + UNUSED(macId);
22213 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));
22214 +}
22215 +
22216 +/* ......................................................................... */
22217 +
22218 +static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)
22219 +{
22220 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22221 +
22222 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22223 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22224 +
22225 + *macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap);
22226 +
22227 + return E_OK;
22228 +}
22229 +
22230 +/* ......................................................................... */
22231 +
22232 +static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
22233 +{
22234 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22235 + uint32_t bitMask = 0;
22236 +
22237 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22238 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22239 +
22240 + GET_EXCEPTION_FLAG(bitMask, exception);
22241 + if (bitMask)
22242 + {
22243 + if (enable)
22244 + p_Tgec->exceptions |= bitMask;
22245 + else
22246 + p_Tgec->exceptions &= ~bitMask;
22247 + }
22248 + else
22249 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
22250 +
22251 + if (enable)
22252 + fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask);
22253 + else
22254 + fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask);
22255 +
22256 + return E_OK;
22257 +}
22258 +
22259 +/* ......................................................................... */
22260 +
22261 +static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)
22262 +{
22263 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22264 +
22265 + SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);
22266 + SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0);
22267 +
22268 + return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap);
22269 +}
22270 +
22271 +/* ......................................................................... */
22272 +
22273 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22274 +static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)
22275 +{
22276 + t_Error err;
22277 +
22278 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22279 + XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... ");
22280 +#endif /* (DEBUG_ERRORS > 0) */
22281 + /* enable and set promiscuous */
22282 + fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE);
22283 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE);
22284 + err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);
22285 + /* disable */
22286 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE);
22287 + fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE);
22288 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
22289 + fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff);
22290 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22291 + if (err)
22292 + XX_Print("FAILED!\n");
22293 + else
22294 + XX_Print("done.\n");
22295 +#endif /* (DEBUG_ERRORS > 0) */
22296 +
22297 + return err;
22298 +}
22299 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22300 +
22301 +/*****************************************************************************/
22302 +/* FM Init & Free API */
22303 +/*****************************************************************************/
22304 +
22305 +/* ......................................................................... */
22306 +
22307 +static t_Error TgecInit(t_Handle h_Tgec)
22308 +{
22309 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22310 + struct tgec_cfg *p_TgecDriverParam;
22311 + t_EnetAddr ethAddr;
22312 + t_Error err;
22313 +
22314 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22315 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22316 + SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
22317 +
22318 + FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo);
22319 + CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);
22320 +
22321 + p_TgecDriverParam = p_Tgec->p_TgecDriverParam;
22322 +
22323 + MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr);
22324 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr);
22325 +
22326 + /* interrupts */
22327 +#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
22328 + {
22329 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2)
22330 + p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT);
22331 + }
22332 +#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */
22333 +
22334 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22335 + if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround &&
22336 + ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))
22337 + {
22338 + FreeInitResources(p_Tgec);
22339 + REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED"));
22340 + }
22341 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22342 +
22343 + err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions);
22344 + if (err)
22345 + {
22346 + FreeInitResources(p_Tgec);
22347 + RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode"));
22348 + }
22349 +
22350 + /* Max Frame Length */
22351 + err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm,
22352 + e_FM_MAC_10G,
22353 + p_Tgec->fmMacControllerDriver.macId,
22354 + p_TgecDriverParam->max_frame_length);
22355 + if (err != E_OK)
22356 + {
22357 + FreeInitResources(p_Tgec);
22358 + RETURN_ERROR(MINOR, err, NO_MSG);
22359 + }
22360 +/* we consider having no IPC a non crasher... */
22361 +
22362 +#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
22363 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
22364 + fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap);
22365 +#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */
22366 +
22367 + p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22368 + if (!p_Tgec->p_MulticastAddrHash)
22369 + {
22370 + FreeInitResources(p_Tgec);
22371 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22372 + }
22373 +
22374 + p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22375 + if (!p_Tgec->p_UnicastAddrHash)
22376 + {
22377 + FreeInitResources(p_Tgec);
22378 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22379 + }
22380 +
22381 + FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm,
22382 + e_FM_MOD_10G_MAC,
22383 + p_Tgec->macId,
22384 + e_FM_INTR_TYPE_ERR,
22385 + TgecErrException,
22386 + p_Tgec);
22387 + if (p_Tgec->mdioIrq != NO_IRQ)
22388 + {
22389 + XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);
22390 + XX_EnableIntr(p_Tgec->mdioIrq);
22391 + }
22392 +
22393 + XX_Free(p_TgecDriverParam);
22394 + p_Tgec->p_TgecDriverParam = NULL;
22395 +
22396 + return E_OK;
22397 +}
22398 +
22399 +/* ......................................................................... */
22400 +
22401 +static t_Error TgecFree(t_Handle h_Tgec)
22402 +{
22403 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22404 +
22405 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22406 +
22407 + if (p_Tgec->p_TgecDriverParam)
22408 + {
22409 + /* Called after config */
22410 + XX_Free(p_Tgec->p_TgecDriverParam);
22411 + p_Tgec->p_TgecDriverParam = NULL;
22412 + }
22413 + else
22414 + /* Called after init */
22415 + FreeInitResources(p_Tgec);
22416 +
22417 + XX_Free(p_Tgec);
22418 +
22419 + return E_OK;
22420 +}
22421 +
22422 +/* ......................................................................... */
22423 +
22424 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
22425 +{
22426 + p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit;
22427 + p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree;
22428 +
22429 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
22430 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback;
22431 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength;
22432 +
22433 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan;
22434 +
22435 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */
22436 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */
22437 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck;
22438 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException;
22439 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
22440 +
22441 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22442 + p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;
22443 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22444 +
22445 + p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion;
22446 +
22447 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp;
22448 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp;
22449 +
22450 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous;
22451 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL;
22452 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL;
22453 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
22454 +
22455 + p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable;
22456 + p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable;
22457 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
22458 +
22459 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause;
22460 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames;
22461 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause;
22462 +
22463 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters;
22464 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics;
22465 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = TgecGetFrameSizeCounters;
22466 +
22467 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress;
22468 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress;
22469 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress;
22470 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress;
22471 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress;
22472 + p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId;
22473 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion;
22474 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength;
22475 +
22476 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg;
22477 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg;
22478 +}
22479 +
22480 +
22481 +/*****************************************************************************/
22482 +/* Tgec Config Main Entry */
22483 +/*****************************************************************************/
22484 +
22485 +/* ......................................................................... */
22486 +
22487 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)
22488 +{
22489 + t_Tgec *p_Tgec;
22490 + struct tgec_cfg *p_TgecDriverParam;
22491 + uintptr_t baseAddr;
22492 +
22493 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
22494 +
22495 + baseAddr = p_FmMacParam->baseAddr;
22496 + /* allocate memory for the UCC GETH data structure. */
22497 + p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec));
22498 + if (!p_Tgec)
22499 + {
22500 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));
22501 + return NULL;
22502 + }
22503 + memset(p_Tgec, 0, sizeof(t_Tgec));
22504 + InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);
22505 +
22506 + /* allocate memory for the 10G MAC driver parameters data structure. */
22507 + p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg));
22508 + if (!p_TgecDriverParam)
22509 + {
22510 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));
22511 + XX_Free(p_Tgec);
22512 + return NULL;
22513 + }
22514 + memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg));
22515 +
22516 + /* Plant parameter structure pointer */
22517 + p_Tgec->p_TgecDriverParam = p_TgecDriverParam;
22518 +
22519 + fman_tgec_defconfig(p_TgecDriverParam);
22520 +
22521 + p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr);
22522 + p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);
22523 + p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
22524 + p_Tgec->enetMode = p_FmMacParam->enetMode;
22525 + p_Tgec->macId = p_FmMacParam->macId;
22526 + p_Tgec->exceptions = DEFAULT_exceptions;
22527 + p_Tgec->mdioIrq = p_FmMacParam->mdioIrq;
22528 + p_Tgec->f_Exception = p_FmMacParam->f_Exception;
22529 + p_Tgec->f_Event = p_FmMacParam->f_Event;
22530 + p_Tgec->h_App = p_FmMacParam->h_App;
22531 +
22532 + return p_Tgec;
22533 +}
22534 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
22535 new file mode 100644
22536 index 00000000..2aa39238
22537 --- /dev/null
22538 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
22539 @@ -0,0 +1,151 @@
22540 +/*
22541 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22542 + *
22543 + * Redistribution and use in source and binary forms, with or without
22544 + * modification, are permitted provided that the following conditions are met:
22545 + * * Redistributions of source code must retain the above copyright
22546 + * notice, this list of conditions and the following disclaimer.
22547 + * * Redistributions in binary form must reproduce the above copyright
22548 + * notice, this list of conditions and the following disclaimer in the
22549 + * documentation and/or other materials provided with the distribution.
22550 + * * Neither the name of Freescale Semiconductor nor the
22551 + * names of its contributors may be used to endorse or promote products
22552 + * derived from this software without specific prior written permission.
22553 + *
22554 + *
22555 + * ALTERNATIVELY, this software may be distributed under the terms of the
22556 + * GNU General Public License ("GPL") as published by the Free Software
22557 + * Foundation, either version 2 of that License or (at your option) any
22558 + * later version.
22559 + *
22560 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22561 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22562 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22563 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22564 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22565 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22566 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22567 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22568 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22569 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22570 + */
22571 +
22572 +
22573 +/******************************************************************************
22574 + @File tgec.h
22575 +
22576 + @Description FM 10G MAC ...
22577 +*//***************************************************************************/
22578 +#ifndef __TGEC_H
22579 +#define __TGEC_H
22580 +
22581 +#include "std_ext.h"
22582 +#include "error_ext.h"
22583 +#include "list_ext.h"
22584 +#include "enet_ext.h"
22585 +
22586 +#include "tgec_mii_acc.h"
22587 +#include "fm_mac.h"
22588 +
22589 +
22590 +#define DEFAULT_exceptions \
22591 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
22592 + TGEC_IMASK_REM_FAULT | \
22593 + TGEC_IMASK_LOC_FAULT | \
22594 + TGEC_IMASK_TX_ECC_ER | \
22595 + TGEC_IMASK_TX_FIFO_UNFL | \
22596 + TGEC_IMASK_TX_FIFO_OVFL | \
22597 + TGEC_IMASK_TX_ER | \
22598 + TGEC_IMASK_RX_FIFO_OVFL | \
22599 + TGEC_IMASK_RX_ECC_ER | \
22600 + TGEC_IMASK_RX_JAB_FRM | \
22601 + TGEC_IMASK_RX_OVRSZ_FRM | \
22602 + TGEC_IMASK_RX_RUNT_FRM | \
22603 + TGEC_IMASK_RX_FRAG_FRM | \
22604 + TGEC_IMASK_RX_CRC_ER | \
22605 + TGEC_IMASK_RX_ALIGN_ER))
22606 +
22607 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
22608 + case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \
22609 + bitMask = TGEC_IMASK_MDIO_SCAN_EVENT ; break; \
22610 + case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \
22611 + bitMask = TGEC_IMASK_MDIO_CMD_CMPL ; break; \
22612 + case e_FM_MAC_EX_10G_REM_FAULT: \
22613 + bitMask = TGEC_IMASK_REM_FAULT ; break; \
22614 + case e_FM_MAC_EX_10G_LOC_FAULT: \
22615 + bitMask = TGEC_IMASK_LOC_FAULT ; break; \
22616 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
22617 + bitMask = TGEC_IMASK_TX_ECC_ER ; break; \
22618 + case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \
22619 + bitMask = TGEC_IMASK_TX_FIFO_UNFL ; break; \
22620 + case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \
22621 + bitMask = TGEC_IMASK_TX_FIFO_OVFL ; break; \
22622 + case e_FM_MAC_EX_10G_TX_ER: \
22623 + bitMask = TGEC_IMASK_TX_ER ; break; \
22624 + case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \
22625 + bitMask = TGEC_IMASK_RX_FIFO_OVFL ; break; \
22626 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
22627 + bitMask = TGEC_IMASK_RX_ECC_ER ; break; \
22628 + case e_FM_MAC_EX_10G_RX_JAB_FRM: \
22629 + bitMask = TGEC_IMASK_RX_JAB_FRM ; break; \
22630 + case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \
22631 + bitMask = TGEC_IMASK_RX_OVRSZ_FRM ; break; \
22632 + case e_FM_MAC_EX_10G_RX_RUNT_FRM: \
22633 + bitMask = TGEC_IMASK_RX_RUNT_FRM ; break; \
22634 + case e_FM_MAC_EX_10G_RX_FRAG_FRM: \
22635 + bitMask = TGEC_IMASK_RX_FRAG_FRM ; break; \
22636 + case e_FM_MAC_EX_10G_RX_LEN_ER: \
22637 + bitMask = TGEC_IMASK_RX_LEN_ER ; break; \
22638 + case e_FM_MAC_EX_10G_RX_CRC_ER: \
22639 + bitMask = TGEC_IMASK_RX_CRC_ER ; break; \
22640 + case e_FM_MAC_EX_10G_RX_ALIGN_ER: \
22641 + bitMask = TGEC_IMASK_RX_ALIGN_ER ; break; \
22642 + default: bitMask = 0;break;}
22643 +
22644 +#define MAX_PACKET_ALIGNMENT 31
22645 +#define MAX_INTER_PACKET_GAP 0x7f
22646 +#define MAX_INTER_PALTERNATE_BEB 0x0f
22647 +#define MAX_RETRANSMISSION 0x0f
22648 +#define MAX_COLLISION_WINDOW 0x03ff
22649 +
22650 +#define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */
22651 +
22652 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
22653 +
22654 +#define HASH_TABLE_SIZE 512 /* Hash table size (= 32 bits * 8 regs) */
22655 +
22656 +#define TGEC_TO_MII_OFFSET 0x1030 /* Offset from the MEM map to the MDIO mem map */
22657 +
22658 +/* 10-gigabit Ethernet MAC Controller ID (10GEC_ID) */
22659 +#define TGEC_ID_ID 0xffff0000
22660 +#define TGEC_ID_MAC_VERSION 0x0000FF00
22661 +#define TGEC_ID_MAC_REV 0x000000ff
22662 +
22663 +
22664 +typedef struct {
22665 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
22666 + t_Handle h_App; /**< Handle to the upper layer application */
22667 + struct tgec_regs *p_MemMap; /**< pointer to 10G memory mapped registers. */
22668 + t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */
22669 + uint64_t addr; /**< MAC address of device; */
22670 + e_EnetMode enetMode; /**< Ethernet physical interface */
22671 + t_FmMacExceptionCallback *f_Exception;
22672 + int mdioIrq;
22673 + t_FmMacExceptionCallback *f_Event;
22674 + bool indAddrRegUsed[TGEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
22675 + uint64_t paddr[TGEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
22676 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
22677 + t_EthHash *p_MulticastAddrHash; /**< pointer to driver's global address hash table */
22678 + t_EthHash *p_UnicastAddrHash; /**< pointer to driver's individual address hash table */
22679 + bool debugMode;
22680 + uint8_t macId;
22681 + uint32_t exceptions;
22682 + struct tgec_cfg *p_TgecDriverParam;
22683 +} t_Tgec;
22684 +
22685 +
22686 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t data);
22687 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
22688 +
22689 +
22690 +#endif /* __TGEC_H */
22691 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
22692 new file mode 100644
22693 index 00000000..e0fafd1d
22694 --- /dev/null
22695 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
22696 @@ -0,0 +1,139 @@
22697 +/*
22698 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22699 + *
22700 + * Redistribution and use in source and binary forms, with or without
22701 + * modification, are permitted provided that the following conditions are met:
22702 + * * Redistributions of source code must retain the above copyright
22703 + * notice, this list of conditions and the following disclaimer.
22704 + * * Redistributions in binary form must reproduce the above copyright
22705 + * notice, this list of conditions and the following disclaimer in the
22706 + * documentation and/or other materials provided with the distribution.
22707 + * * Neither the name of Freescale Semiconductor nor the
22708 + * names of its contributors may be used to endorse or promote products
22709 + * derived from this software without specific prior written permission.
22710 + *
22711 + *
22712 + * ALTERNATIVELY, this software may be distributed under the terms of the
22713 + * GNU General Public License ("GPL") as published by the Free Software
22714 + * Foundation, either version 2 of that License or (at your option) any
22715 + * later version.
22716 + *
22717 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22718 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22719 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22720 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22721 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22722 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22723 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22724 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22725 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22726 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22727 + */
22728 +
22729 +
22730 +
22731 +#include "error_ext.h"
22732 +#include "std_ext.h"
22733 +#include "fm_mac.h"
22734 +#include "tgec.h"
22735 +#include "xx_ext.h"
22736 +
22737 +#include "fm_common.h"
22738 +
22739 +
22740 +/*****************************************************************************/
22741 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec,
22742 + uint8_t phyAddr,
22743 + uint8_t reg,
22744 + uint16_t data)
22745 +{
22746 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22747 + t_TgecMiiAccessMemMap *p_MiiAccess;
22748 + uint32_t cfgStatusReg;
22749 +
22750 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22751 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22752 +
22753 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22754 +
22755 + /* Configure MII */
22756 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22757 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22758 + /* (one half of fm clock => 2.5Mhz) */
22759 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22760 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22761 +
22762 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22763 + XX_UDelay (1);
22764 +
22765 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22766 +
22767 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22768 +
22769 + CORE_MemoryBarrier();
22770 +
22771 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22772 + XX_UDelay (1);
22773 +
22774 + WRITE_UINT32(p_MiiAccess->mdio_data, data);
22775 +
22776 + CORE_MemoryBarrier();
22777 +
22778 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22779 + XX_UDelay (1);
22780 +
22781 + return E_OK;
22782 +}
22783 +
22784 +/*****************************************************************************/
22785 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec,
22786 + uint8_t phyAddr,
22787 + uint8_t reg,
22788 + uint16_t *p_Data)
22789 +{
22790 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22791 + t_TgecMiiAccessMemMap *p_MiiAccess;
22792 + uint32_t cfgStatusReg;
22793 +
22794 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22795 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22796 +
22797 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22798 +
22799 + /* Configure MII */
22800 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22801 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22802 + /* (one half of fm clock => 2.5Mhz) */
22803 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22804 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22805 +
22806 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22807 + XX_UDelay (1);
22808 +
22809 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22810 +
22811 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22812 +
22813 + CORE_MemoryBarrier();
22814 +
22815 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22816 + XX_UDelay (1);
22817 +
22818 + WRITE_UINT32(p_MiiAccess->mdio_command, (uint32_t)(phyAddr | MIIMCOM_READ_CYCLE));
22819 +
22820 + CORE_MemoryBarrier();
22821 +
22822 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22823 + XX_UDelay (1);
22824 +
22825 + *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data);
22826 +
22827 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22828 +
22829 + if (cfgStatusReg & MIIMIND_READ_ERROR)
22830 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
22831 + ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgStatusReg 0x%x",
22832 + ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfgStatusReg));
22833 +
22834 + return E_OK;
22835 +}
22836 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
22837 new file mode 100644
22838 index 00000000..645cdde5
22839 --- /dev/null
22840 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
22841 @@ -0,0 +1,80 @@
22842 +/*
22843 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22844 + *
22845 + * Redistribution and use in source and binary forms, with or without
22846 + * modification, are permitted provided that the following conditions are met:
22847 + * * Redistributions of source code must retain the above copyright
22848 + * notice, this list of conditions and the following disclaimer.
22849 + * * Redistributions in binary form must reproduce the above copyright
22850 + * notice, this list of conditions and the following disclaimer in the
22851 + * documentation and/or other materials provided with the distribution.
22852 + * * Neither the name of Freescale Semiconductor nor the
22853 + * names of its contributors may be used to endorse or promote products
22854 + * derived from this software without specific prior written permission.
22855 + *
22856 + *
22857 + * ALTERNATIVELY, this software may be distributed under the terms of the
22858 + * GNU General Public License ("GPL") as published by the Free Software
22859 + * Foundation, either version 2 of that License or (at your option) any
22860 + * later version.
22861 + *
22862 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22863 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22864 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22865 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22866 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22867 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22868 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22869 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22870 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22871 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22872 + */
22873 +
22874 +
22875 +#ifndef __TGEC_MII_ACC_H
22876 +#define __TGEC_MII_ACC_H
22877 +
22878 +#include "std_ext.h"
22879 +
22880 +
22881 +/* MII Management Command Register */
22882 +#define MIIMCOM_READ_POST_INCREMENT 0x00004000
22883 +#define MIIMCOM_READ_CYCLE 0x00008000
22884 +#define MIIMCOM_SCAN_CYCLE 0x00000800
22885 +#define MIIMCOM_PREAMBLE_DISABLE 0x00000400
22886 +
22887 +#define MIIMCOM_MDIO_HOLD_1_REG_CLK 0
22888 +#define MIIMCOM_MDIO_HOLD_2_REG_CLK 1
22889 +#define MIIMCOM_MDIO_HOLD_3_REG_CLK 2
22890 +#define MIIMCOM_MDIO_HOLD_4_REG_CLK 3
22891 +
22892 +#define MIIMCOM_DIV_MASK 0x0000ff00
22893 +#define MIIMCOM_DIV_SHIFT 8
22894 +
22895 +/* MII Management Indicator Register */
22896 +#define MIIMIND_BUSY 0x00000001
22897 +#define MIIMIND_READ_ERROR 0x00000002
22898 +
22899 +#define MIIDATA_BUSY 0x80000000
22900 +
22901 +#if defined(__MWERKS__) && !defined(__GNUC__)
22902 +#pragma pack(push,1)
22903 +#endif /* defined(__MWERKS__) && ... */
22904 +
22905 +/*----------------------------------------------------*/
22906 +/* MII Configuration Control Memory Map Registers */
22907 +/*----------------------------------------------------*/
22908 +typedef _Packed struct t_TgecMiiAccessMemMap
22909 +{
22910 + volatile uint32_t mdio_cfg_status; /* 0x030 */
22911 + volatile uint32_t mdio_command; /* 0x034 */
22912 + volatile uint32_t mdio_data; /* 0x038 */
22913 + volatile uint32_t mdio_regaddr; /* 0x03c */
22914 +} _PackedType t_TgecMiiAccessMemMap ;
22915 +
22916 +#if defined(__MWERKS__) && !defined(__GNUC__)
22917 +#pragma pack(pop)
22918 +#endif /* defined(__MWERKS__) && ... */
22919 +
22920 +
22921 +#endif /* __TGEC_MII_ACC_H */
22922 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
22923 new file mode 100644
22924 index 00000000..bfa02f5e
22925 --- /dev/null
22926 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
22927 @@ -0,0 +1,15 @@
22928 +#
22929 +# Makefile for the Freescale Ethernet controllers
22930 +#
22931 +ccflags-y += -DVERSION=\"\"
22932 +#
22933 +#Include netcomm SW specific definitions
22934 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
22935 +
22936 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
22937 +
22938 +ccflags-y += -I$(NCSW_FM_INC)
22939 +
22940 +obj-y += fsl-ncsw-macsec.o
22941 +
22942 +fsl-ncsw-macsec-objs := fm_macsec.o fm_macsec_guest.o fm_macsec_master.o fm_macsec_secy.o
22943 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
22944 new file mode 100644
22945 index 00000000..0a1b31f1
22946 --- /dev/null
22947 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
22948 @@ -0,0 +1,237 @@
22949 +/*
22950 + * Copyright 2008-2015 Freescale Semiconductor Inc.
22951 + *
22952 + * Redistribution and use in source and binary forms, with or without
22953 + * modification, are permitted provided that the following conditions are met:
22954 + * * Redistributions of source code must retain the above copyright
22955 + * notice, this list of conditions and the following disclaimer.
22956 + * * Redistributions in binary form must reproduce the above copyright
22957 + * notice, this list of conditions and the following disclaimer in the
22958 + * documentation and/or other materials provided with the distribution.
22959 + * * Neither the name of Freescale Semiconductor nor the
22960 + * names of its contributors may be used to endorse or promote products
22961 + * derived from this software without specific prior written permission.
22962 + *
22963 + *
22964 + * ALTERNATIVELY, this software may be distributed under the terms of the
22965 + * GNU General Public License ("GPL") as published by the Free Software
22966 + * Foundation, either version 2 of that License or (at your option) any
22967 + * later version.
22968 + *
22969 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22970 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22971 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22972 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22973 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22974 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22975 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22976 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22977 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22978 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22979 + */
22980 +/******************************************************************************
22981 +
22982 + @File fm_macsec.c
22983 +
22984 + @Description FM MACSEC driver routines implementation.
22985 +*//***************************************************************************/
22986 +
22987 +#include "std_ext.h"
22988 +#include "error_ext.h"
22989 +#include "xx_ext.h"
22990 +#include "string_ext.h"
22991 +#include "sprint_ext.h"
22992 +#include "debug_ext.h"
22993 +
22994 +#include "fm_macsec.h"
22995 +
22996 +
22997 +/****************************************/
22998 +/* API Init unit functions */
22999 +/****************************************/
23000 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam)
23001 +{
23002 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver;
23003 +
23004 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL);
23005 +
23006 + if (p_FmMacsecParam->guestMode)
23007 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam);
23008 + else
23009 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam);
23010 +
23011 + if (!p_FmMacsecControllerDriver)
23012 + return NULL;
23013 +
23014 + return (t_Handle)p_FmMacsecControllerDriver;
23015 +}
23016 +
23017 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec)
23018 +{
23019 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23020 +
23021 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23022 +
23023 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init)
23024 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec);
23025 +
23026 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23027 +}
23028 +
23029 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec)
23030 +{
23031 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23032 +
23033 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23034 +
23035 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free)
23036 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec);
23037 +
23038 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23039 +}
23040 +
23041 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
23042 +{
23043 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23044 +
23045 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23046 +
23047 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment)
23048 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode);
23049 +
23050 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23051 +}
23052 +
23053 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23054 +{
23055 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23056 +
23057 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23058 +
23059 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment)
23060 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled);
23061 +
23062 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23063 +}
23064 +
23065 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
23066 +{
23067 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23068 +
23069 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23070 +
23071 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment)
23072 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled);
23073 +
23074 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23075 +}
23076 +
23077 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
23078 +{
23079 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23080 +
23081 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23082 +
23083 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment)
23084 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode);
23085 +
23086 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23087 +}
23088 +
23089 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
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_ConfigPnExhaustionThreshold)
23096 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr);
23097 +
23098 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23099 +}
23100 +
23101 +t_Error FM_MACSEC_ConfigKeysUnreadable(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_ConfigKeysUnreadable)
23108 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec);
23109 +
23110 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23111 +}
23112 +
23113 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec)
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_ConfigSectagWithoutSCI)
23120 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec);
23121 +
23122 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23123 +}
23124 +
23125 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
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_ConfigException)
23132 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable);
23133 +
23134 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23135 +}
23136 +
23137 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
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_GetRevision)
23144 + return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision);
23145 +
23146 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23147 +}
23148 +
23149 +
23150 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec)
23151 +{
23152 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23153 +
23154 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23155 +
23156 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable)
23157 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec);
23158 +
23159 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23160 +}
23161 +
23162 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec)
23163 +{
23164 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23165 +
23166 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23167 +
23168 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable)
23169 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec);
23170 +
23171 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23172 +}
23173 +
23174 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23175 +{
23176 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23177 +
23178 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23179 +
23180 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException)
23181 + return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable);
23182 +
23183 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23184 +}
23185 +
23186 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
23187 new file mode 100644
23188 index 00000000..fbe51875
23189 --- /dev/null
23190 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
23191 @@ -0,0 +1,203 @@
23192 +/*
23193 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23194 + *
23195 + * Redistribution and use in source and binary forms, with or without
23196 + * modification, are permitted provided that the following conditions are met:
23197 + * * Redistributions of source code must retain the above copyright
23198 + * notice, this list of conditions and the following disclaimer.
23199 + * * Redistributions in binary form must reproduce the above copyright
23200 + * notice, this list of conditions and the following disclaimer in the
23201 + * documentation and/or other materials provided with the distribution.
23202 + * * Neither the name of Freescale Semiconductor nor the
23203 + * names of its contributors may be used to endorse or promote products
23204 + * derived from this software without specific prior written permission.
23205 + *
23206 + *
23207 + * ALTERNATIVELY, this software may be distributed under the terms of the
23208 + * GNU General Public License ("GPL") as published by the Free Software
23209 + * Foundation, either version 2 of that License or (at your option) any
23210 + * later version.
23211 + *
23212 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23213 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23214 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23215 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23216 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23217 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23218 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23219 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23220 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23221 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23222 + */
23223 +
23224 +/******************************************************************************
23225 + @File fm_macsec.h
23226 +
23227 + @Description FM MACSEC internal structures and definitions.
23228 +*//***************************************************************************/
23229 +#ifndef __FM_MACSEC_H
23230 +#define __FM_MACSEC_H
23231 +
23232 +#include "error_ext.h"
23233 +#include "std_ext.h"
23234 +#include "fm_macsec_ext.h"
23235 +
23236 +#include "fm_common.h"
23237 +
23238 +
23239 +#define __ERR_MODULE__ MODULE_FM_MACSEC
23240 +
23241 +
23242 +typedef struct
23243 +{
23244 + t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec);
23245 + t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec);
23246 +
23247 + t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
23248 + t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23249 + t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled);
23250 + t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23251 + t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
23252 + t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23253 + t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr);
23254 + t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec);
23255 + t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec);
23256 + t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
23257 +
23258 + t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
23259 + t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec);
23260 + t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec);
23261 + t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
23262 +
23263 +} t_FmMacsecControllerDriver;
23264 +
23265 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam);
23266 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams);
23267 +
23268 +/***********************************************************************/
23269 +/* MACSEC internal routines */
23270 +/***********************************************************************/
23271 +
23272 +/**************************************************************************//**
23273 +
23274 + @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit
23275 +
23276 + @Description FM MACSEC Inter Module functions -
23277 + These are not User API routines but routines that may be called
23278 + from other modules. This will be the case in a single core environment,
23279 + where instead of using the XX messaging mechanism, the routines may be
23280 + called from other modules. In a multicore environment, the other modules may
23281 + be run by other cores and therefore these routines may not be called directly.
23282 +
23283 + @{
23284 +*//***************************************************************************/
23285 +
23286 +#define MAX_NUM_OF_SA_PER_SC 4
23287 +
23288 +typedef enum
23289 +{
23290 + e_SC_RX = 0,
23291 + e_SC_TX
23292 +} e_ScType;
23293 +
23294 +typedef enum
23295 +{
23296 + e_SC_SA_A = 0,
23297 + e_SC_SA_B ,
23298 + e_SC_SA_C ,
23299 + e_SC_SA_D
23300 +} e_ScSaId;
23301 +
23302 +typedef struct
23303 +{
23304 + uint32_t scId;
23305 + macsecSCI_t sci;
23306 + bool replayProtect;
23307 + uint32_t replayWindow;
23308 + e_FmMacsecValidFrameBehavior validateFrames;
23309 + uint16_t confidentialityOffset;
23310 + e_FmMacsecSecYCipherSuite cipherSuite;
23311 +} t_RxScParams;
23312 +
23313 +typedef struct
23314 +{
23315 + uint32_t scId;
23316 + macsecSCI_t sci;
23317 + bool protectFrames;
23318 + e_FmMacsecSciInsertionMode sciInsertionMode;
23319 + bool confidentialityEnable;
23320 + uint16_t confidentialityOffset;
23321 + e_FmMacsecSecYCipherSuite cipherSuite;
23322 +} t_TxScParams;
23323 +
23324 +typedef enum e_FmMacsecGlobalExceptions {
23325 + e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */
23326 + e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */
23327 +} e_FmMacsecGlobalExceptions;
23328 +
23329 +typedef enum e_FmMacsecGlobalEvents {
23330 + e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */
23331 +} e_FmMacsecGlobalEvents;
23332 +
23333 +/**************************************************************************//**
23334 + @Description Enum for inter-module interrupts registration
23335 +*//***************************************************************************/
23336 +typedef enum e_FmMacsecEventModules{
23337 + e_FM_MACSEC_MOD_SC_TX,
23338 + e_FM_MACSEC_MOD_DUMMY_LAST
23339 +} e_FmMacsecEventModules;
23340 +
23341 +typedef enum e_FmMacsecInterModuleEvent {
23342 + e_FM_MACSEC_EV_SC_TX,
23343 + e_FM_MACSEC_EV_ERR_SC_TX,
23344 + e_FM_MACSEC_EV_DUMMY_LAST
23345 +} e_FmMacsecInterModuleEvent;
23346 +
23347 +#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2)
23348 +
23349 +#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \
23350 + switch(mod){ \
23351 + case e_FM_MACSEC_MOD_SC_TX: \
23352 + event = (intrType == e_FM_INTR_TYPE_ERR) ? \
23353 + e_FM_MACSEC_EV_ERR_SC_TX: \
23354 + e_FM_MACSEC_EV_SC_TX; \
23355 + event += (uint8_t)(2 * id);break; \
23356 + break; \
23357 + default:event = e_FM_MACSEC_EV_DUMMY_LAST; \
23358 + break;}
23359 +
23360 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23361 + e_FmMacsecEventModules module,
23362 + uint8_t modId,
23363 + e_FmIntrType intrType,
23364 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23365 + t_Handle h_Arg);
23366 +
23367 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23368 + e_FmMacsecEventModules module,
23369 + uint8_t modId,
23370 + e_FmIntrType intrType);
23371 +
23372 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds);
23373 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds);
23374 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams);
23375 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId);
23376 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams);
23377 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId);
23378 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
23379 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key);
23380 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23381 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23382 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive);
23383 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN);
23384 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN);
23385 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an);
23386 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An);
23387 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable);
23388 +
23389 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable);
23390 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable);
23391 +
23392 +
23393 +
23394 +#endif /* __FM_MACSEC_H */
23395 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
23396 new file mode 100644
23397 index 00000000..31d789d0
23398 --- /dev/null
23399 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
23400 @@ -0,0 +1,59 @@
23401 +/*
23402 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23403 + *
23404 + * Redistribution and use in source and binary forms, with or without
23405 + * modification, are permitted provided that the following conditions are met:
23406 + * * Redistributions of source code must retain the above copyright
23407 + * notice, this list of conditions and the following disclaimer.
23408 + * * Redistributions in binary form must reproduce the above copyright
23409 + * notice, this list of conditions and the following disclaimer in the
23410 + * documentation and/or other materials provided with the distribution.
23411 + * * Neither the name of Freescale Semiconductor nor the
23412 + * names of its contributors may be used to endorse or promote products
23413 + * derived from this software without specific prior written permission.
23414 + *
23415 + *
23416 + * ALTERNATIVELY, this software may be distributed under the terms of the
23417 + * GNU General Public License ("GPL") as published by the Free Software
23418 + * Foundation, either version 2 of that License or (at your option) any
23419 + * later version.
23420 + *
23421 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23422 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23423 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23424 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23425 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23426 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23427 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23428 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23429 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23430 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23431 + */
23432 +
23433 +/******************************************************************************
23434 + @File fm_macsec.c
23435 +
23436 + @Description FM MACSEC driver routines implementation.
23437 +*//***************************************************************************/
23438 +
23439 +#include "std_ext.h"
23440 +#include "error_ext.h"
23441 +#include "xx_ext.h"
23442 +#include "string_ext.h"
23443 +#include "sprint_ext.h"
23444 +#include "debug_ext.h"
23445 +#include "fm_macsec.h"
23446 +
23447 +
23448 +/****************************************/
23449 +/* static functions */
23450 +/****************************************/
23451 +
23452 +/****************************************/
23453 +/* API Init unit functions */
23454 +/****************************************/
23455 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam)
23456 +{
23457 + UNUSED(p_FmMacsecParam);
23458 + return NULL;
23459 +}
23460 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
23461 new file mode 100644
23462 index 00000000..623612ac
23463 --- /dev/null
23464 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
23465 @@ -0,0 +1,1031 @@
23466 +/*
23467 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23468 + *
23469 + * Redistribution and use in source and binary forms, with or without
23470 + * modification, are permitted provided that the following conditions are met:
23471 + * * Redistributions of source code must retain the above copyright
23472 + * notice, this list of conditions and the following disclaimer.
23473 + * * Redistributions in binary form must reproduce the above copyright
23474 + * notice, this list of conditions and the following disclaimer in the
23475 + * documentation and/or other materials provided with the distribution.
23476 + * * Neither the name of Freescale Semiconductor nor the
23477 + * names of its contributors may be used to endorse or promote products
23478 + * derived from this software without specific prior written permission.
23479 + *
23480 + *
23481 + * ALTERNATIVELY, this software may be distributed under the terms of the
23482 + * GNU General Public License ("GPL") as published by the Free Software
23483 + * Foundation, either version 2 of that License or (at your option) any
23484 + * later version.
23485 + *
23486 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23487 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23488 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23489 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23490 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23491 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23492 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23493 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23494 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23495 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23496 + */
23497 +
23498 +/******************************************************************************
23499 + @File fm_macsec.c
23500 +
23501 + @Description FM MACSEC driver routines implementation.
23502 +*//***************************************************************************/
23503 +
23504 +#include "std_ext.h"
23505 +#include "error_ext.h"
23506 +#include "xx_ext.h"
23507 +#include "string_ext.h"
23508 +#include "sprint_ext.h"
23509 +#include "fm_mac_ext.h"
23510 +
23511 +#include "fm_macsec_master.h"
23512 +
23513 +
23514 +extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
23515 +
23516 +
23517 +/****************************************/
23518 +/* static functions */
23519 +/****************************************/
23520 +static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec)
23521 +{
23522 + if (!p_FmMacsec->f_Exception)
23523 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
23524 +
23525 + return E_OK;
23526 +}
23527 +
23528 +static void UnimplementedIsr(t_Handle h_Arg, uint32_t id)
23529 +{
23530 + UNUSED(h_Arg); UNUSED(id);
23531 +
23532 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
23533 +}
23534 +
23535 +static void MacsecEventIsr(t_Handle h_FmMacsec)
23536 +{
23537 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23538 + uint32_t events,event,i;
23539 +
23540 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23541 +
23542 + events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr);
23543 + events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever);
23544 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events);
23545 +
23546 + for (i=0; i<NUM_OF_TX_SC; i++)
23547 + if (events & FM_MACSEC_EV_TX_SC_NEXT_PN(i))
23548 + {
23549 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_NORMAL, event);
23550 + p_FmMacsec->intrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i);
23551 + }
23552 +}
23553 +
23554 +static void MacsecErrorIsr(t_Handle h_FmMacsec)
23555 +{
23556 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23557 + uint32_t errors,error,i;
23558 +
23559 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23560 +
23561 + errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err);
23562 + errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer);
23563 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors);
23564 +
23565 + for (i=0; i<NUM_OF_TX_SC; i++)
23566 + if (errors & FM_MACSEC_EX_TX_SC(i))
23567 + {
23568 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_ERR, error);
23569 + p_FmMacsec->intrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i);
23570 + }
23571 +
23572 + if (errors & FM_MACSEC_EX_ECC)
23573 + {
23574 + uint8_t eccType;
23575 + uint32_t tmpReg;
23576 +
23577 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec);
23578 + ASSERT_COND(tmpReg & MECC_CAP);
23579 + eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT);
23580 +
23581 + if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC))
23582 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC);
23583 + else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC))
23584 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC);
23585 + else
23586 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg);
23587 + }
23588 +}
23589 +
23590 +static t_Error MacsecInit(t_Handle h_FmMacsec)
23591 +{
23592 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23593 + t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL;
23594 + uint32_t tmpReg,i,macId;
23595 +
23596 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23597 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23598 +
23599 + CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters);
23600 +
23601 + p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam;
23602 +
23603 + for (i=0;i<e_FM_MACSEC_EV_DUMMY_LAST;i++)
23604 + p_FmMacsec->intrMng[i].f_Isr = UnimplementedIsr;
23605 +
23606 + tmpReg = 0;
23607 + tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)|
23608 + (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) |
23609 + (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) |
23610 + (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) |
23611 + (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) |
23612 + (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) |
23613 + (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) |
23614 + (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) |
23615 + (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT);
23616 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
23617 +
23618 + tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac);
23619 + /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL.
23620 + * In addition, the SCI (8 bytes) overhead might be subtracted as well. */
23621 + tmpReg -= p_FmMacsecDriverParam->mflSubtract;
23622 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg);
23623 +
23624 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr);
23625 +
23626 + if (!p_FmMacsec->userExceptions)
23627 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23628 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23629 +
23630 + p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC;
23631 + if (p_FmMacsecDriverParam->reservedSc0)
23632 + p_FmMacsec->numRxScAvailable --;
23633 + p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC;
23634 +
23635 + XX_Free(p_FmMacsecDriverParam);
23636 + p_FmMacsec->p_FmMacsecDriverParam = NULL;
23637 +
23638 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23639 + FmRegisterIntr(p_FmMacsec->h_Fm,
23640 + e_FM_MOD_MACSEC,
23641 + (uint8_t)macId,
23642 + e_FM_INTR_TYPE_NORMAL,
23643 + MacsecEventIsr,
23644 + p_FmMacsec);
23645 +
23646 + FmRegisterIntr(p_FmMacsec->h_Fm,
23647 + e_FM_MOD_MACSEC,
23648 + 0,
23649 + e_FM_INTR_TYPE_ERR,
23650 + MacsecErrorIsr,
23651 + p_FmMacsec);
23652 +
23653 + return E_OK;
23654 +}
23655 +
23656 +static t_Error MacsecFree(t_Handle h_FmMacsec)
23657 +{
23658 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23659 + uint32_t macId;
23660 +
23661 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23662 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23663 +
23664 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23665 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23666 + e_FM_MOD_MACSEC,
23667 + (uint8_t)macId,
23668 + e_FM_INTR_TYPE_NORMAL);
23669 +
23670 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23671 + e_FM_MOD_MACSEC,
23672 + 0,
23673 + e_FM_INTR_TYPE_ERR);
23674 +
23675 + if (p_FmMacsec->rxScSpinLock)
23676 + XX_FreeSpinlock(p_FmMacsec->rxScSpinLock);
23677 + if (p_FmMacsec->txScSpinLock)
23678 + XX_FreeSpinlock(p_FmMacsec->txScSpinLock);
23679 +
23680 + XX_Free(p_FmMacsec);
23681 +
23682 + return E_OK;
23683 +}
23684 +
23685 +static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
23686 +{
23687 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23688 +
23689 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23690 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23691 +
23692 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode;
23693 +
23694 + return E_OK;
23695 +}
23696 +
23697 +static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23698 +{
23699 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23700 +
23701 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23702 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23703 +
23704 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled;
23705 +
23706 + return E_OK;
23707 +}
23708 +
23709 +static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23710 +{
23711 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23712 +
23713 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23714 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23715 +
23716 + p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled;
23717 +
23718 + return E_OK;
23719 +}
23720 +
23721 +static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23722 +{
23723 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23724 +
23725 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23726 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23727 +
23728 + p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled;
23729 +
23730 + return E_OK;
23731 +}
23732 +
23733 +static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
23734 +{
23735 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23736 +
23737 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23738 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23739 +
23740 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled;
23741 +
23742 + return E_OK;
23743 +}
23744 +
23745 +static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
23746 +{
23747 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23748 +
23749 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23750 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23751 +
23752 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode;
23753 +
23754 + return E_OK;
23755 +}
23756 +
23757 +static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
23758 +{
23759 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23760 +
23761 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23762 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23763 +
23764 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr;
23765 +
23766 + return E_OK;
23767 +}
23768 +
23769 +static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec)
23770 +{
23771 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23772 +
23773 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23774 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23775 +
23776 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE;
23777 +
23778 + return E_OK;
23779 +}
23780 +
23781 +static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec)
23782 +{
23783 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23784 +
23785 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23786 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23787 +
23788 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE;
23789 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE;
23790 +
23791 + return E_OK;
23792 +}
23793 +
23794 +static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23795 +{
23796 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23797 + uint32_t bitMask = 0;
23798 +
23799 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23800 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23801 +
23802 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23803 + if (bitMask)
23804 + {
23805 + if (enable)
23806 + p_FmMacsec->userExceptions |= bitMask;
23807 + else
23808 + p_FmMacsec->userExceptions &= ~bitMask;
23809 + }
23810 + else
23811 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23812 +
23813 + return E_OK;
23814 +}
23815 +
23816 +static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
23817 +{
23818 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23819 +
23820 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23821 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23822 +
23823 + *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1);
23824 +
23825 + return E_OK;
23826 +}
23827 +
23828 +static t_Error MacsecEnable(t_Handle h_FmMacsec)
23829 +{
23830 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23831 + uint32_t tmpReg;
23832 +
23833 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23834 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23835 +
23836 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23837 + tmpReg |= CFG_BYPN;
23838 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23839 +
23840 + return E_OK;
23841 +}
23842 +
23843 +static t_Error MacsecDisable(t_Handle h_FmMacsec)
23844 +{
23845 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23846 + uint32_t tmpReg;
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 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23852 + tmpReg &= ~CFG_BYPN;
23853 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23854 +
23855 + return E_OK;
23856 +}
23857 +
23858 +static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23859 +{
23860 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23861 + uint32_t bitMask;
23862 +
23863 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23864 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23865 +
23866 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23867 + if (bitMask)
23868 + {
23869 + if (enable)
23870 + p_FmMacsec->userExceptions |= bitMask;
23871 + else
23872 + p_FmMacsec->userExceptions &= ~bitMask;
23873 + }
23874 + else
23875 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23876 +
23877 + if (!p_FmMacsec->userExceptions)
23878 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23879 + else
23880 + p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC;
23881 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23882 +
23883 + return E_OK;
23884 +}
23885 +
23886 +static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver)
23887 +{
23888 + p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit;
23889 + p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree;
23890 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment;
23891 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment;
23892 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment;
23893 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment;
23894 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment;
23895 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment;
23896 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold;
23897 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable;
23898 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI;
23899 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException;
23900 + p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision;
23901 + p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable;
23902 + p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable;
23903 + p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException;
23904 +}
23905 +
23906 +/****************************************/
23907 +/* Inter-Module functions */
23908 +/****************************************/
23909 +
23910 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23911 + e_FmMacsecEventModules module,
23912 + uint8_t modId,
23913 + e_FmIntrType intrType,
23914 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23915 + t_Handle h_Arg)
23916 +{
23917 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23918 + uint8_t event= 0;
23919 +
23920 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23921 +
23922 + GET_MACSEC_MODULE_EVENT(module, modId, intrType, event);
23923 +
23924 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23925 + p_FmMacsec->intrMng[event].f_Isr = f_Isr;
23926 + p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg;
23927 +}
23928 +
23929 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23930 + e_FmMacsecEventModules module,
23931 + uint8_t modId,
23932 + e_FmIntrType intrType)
23933 +{
23934 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23935 + uint8_t event= 0;
23936 +
23937 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23938 +
23939 + GET_MACSEC_MODULE_EVENT(module, modId,intrType, event);
23940 +
23941 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23942 + p_FmMacsec->intrMng[event].f_Isr = NULL;
23943 + p_FmMacsec->intrMng[event].h_SrcHandle = NULL;
23944 +}
23945 +
23946 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds)
23947 +{
23948 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23949 + t_Error err = E_OK;
23950 + bool *p_ScTable;
23951 + uint32_t *p_ScAvailable,i;
23952 +
23953 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23954 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
23955 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
23956 +
23957 + if (type == e_SC_RX)
23958 + {
23959 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
23960 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
23961 + i = (NUM_OF_RX_SC - 1);
23962 + }
23963 + else
23964 + {
23965 + p_ScTable = (bool *)p_FmMacsec->txScTable;
23966 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
23967 + i = (NUM_OF_TX_SC - 1);
23968 +
23969 + }
23970 + if (*p_ScAvailable < numOfScs)
23971 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available"));
23972 +
23973 + if (isPtp)
23974 + {
23975 + i = 0;
23976 + if (p_ScTable[i])
23977 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available"));
23978 + }
23979 +
23980 + for (;numOfScs;i--)
23981 + {
23982 + if (p_ScTable[i])
23983 + continue;
23984 + numOfScs --;
23985 + (*p_ScAvailable)--;
23986 + p_ScIds[numOfScs] = i;
23987 + p_ScTable[i] = TRUE;
23988 + }
23989 +
23990 + return err;
23991 +}
23992 +
23993 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds)
23994 +{
23995 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23996 + t_Error err = E_OK;
23997 + bool *p_ScTable;
23998 + uint32_t *p_ScAvailable,maxNumOfSc,i;
23999 +
24000 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24001 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
24002 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
24003 +
24004 + if (type == e_SC_RX)
24005 + {
24006 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
24007 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
24008 + maxNumOfSc = NUM_OF_RX_SC;
24009 + }
24010 + else
24011 + {
24012 + p_ScTable = (bool *)p_FmMacsec->txScTable;
24013 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
24014 + maxNumOfSc = NUM_OF_TX_SC;
24015 + }
24016 +
24017 + if ((*p_ScAvailable + numOfScs) > maxNumOfSc)
24018 + RETURN_ERROR(MINOR, E_FULL, ("Too much SCs"));
24019 +
24020 + for (i=0;i<numOfScs;i++)
24021 + {
24022 + p_ScTable[p_ScIds[i]] = FALSE;
24023 + (*p_ScAvailable)++;
24024 + }
24025 +
24026 + return err;
24027 +
24028 +}
24029 +
24030 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable)
24031 +{
24032 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24033 + uint32_t tmpReg = 0;
24034 +
24035 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24036 +
24037 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
24038 + if (enable && (tmpReg & CFG_S0I))
24039 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode"));
24040 +
24041 + if (enable)
24042 + tmpReg |= CFG_S0I;
24043 + else
24044 + tmpReg &= ~CFG_S0I;
24045 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
24046 +
24047 + return E_OK;
24048 +}
24049 +
24050 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams)
24051 +{
24052 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24053 + t_Error err = E_OK;
24054 + uint32_t tmpReg = 0, intFlags;
24055 +
24056 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24057 + SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE);
24058 + SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24059 +
24060 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24061 +
24062 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId);
24063 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg);
24064 + if (tmpReg & RX_SCCFG_SCI_EN_MASK)
24065 + {
24066 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24067 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId));
24068 + }
24069 +
24070 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci));
24071 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci));
24072 + tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK);
24073 + tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK);
24074 + tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK);
24075 + tmpReg |= RX_SCCFG_SCI_EN_MASK;
24076 + tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT);
24077 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
24078 +
24079 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow);
24080 +
24081 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24082 +
24083 + return err;
24084 +}
24085 +
24086 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId)
24087 +{
24088 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24089 + t_Error err = E_OK;
24090 + uint32_t tmpReg = 0, intFlags;
24091 +
24092 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24093 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24094 +
24095 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24096 +
24097 + tmpReg &= ~RX_SCCFG_SCI_EN_MASK;
24098 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24099 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
24100 +
24101 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24102 +
24103 + return err;
24104 +}
24105 +
24106 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams)
24107 +{
24108 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24109 + t_Error err = E_OK;
24110 + uint32_t tmpReg = 0, intFlags;
24111 + bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE;
24112 +
24113 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24114 + SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE);
24115 + SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
24116 +
24117 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24118 +
24119 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId);
24120 +
24121 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24122 + if (tmpReg & TX_SCCFG_SCE_MASK)
24123 + {
24124 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24125 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId));
24126 + }
24127 +
24128 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci));
24129 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci));
24130 + alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG);
24131 + useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA);
24132 +
24133 + tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK);
24134 + tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK);
24135 + tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK);
24136 + tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK);
24137 + tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK);
24138 + tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK);
24139 + tmpReg |= TX_SCCFG_SCE_MASK;
24140 + tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT);
24141 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24142 +
24143 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24144 +
24145 + return err;
24146 +}
24147 +
24148 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId)
24149 +{
24150 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24151 + t_Error err = E_OK;
24152 + uint32_t tmpReg = 0, intFlags;
24153 +
24154 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24155 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
24156 +
24157 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24158 +
24159 + tmpReg &= ~TX_SCCFG_SCE_MASK;
24160 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24161 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24162 +
24163 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24164 +
24165 + return err;
24166 +}
24167 +
24168 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
24169 +{
24170 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24171 + t_Error err = E_OK;
24172 + uint32_t tmpReg = 0, intFlags;
24173 +
24174 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24175 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24176 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24177 +
24178 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24179 +
24180 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24181 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn);
24182 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn);
24183 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t));
24184 +
24185 + tmpReg |= RX_SACFG_ACTIVE;
24186 + tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK);
24187 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24188 +
24189 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24190 +
24191 + return err;
24192 +}
24193 +
24194 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key)
24195 +{
24196 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24197 + t_Error err = E_OK;
24198 + uint32_t tmpReg = 0, intFlags;
24199 +
24200 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24201 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24202 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24203 +
24204 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24205 +
24206 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24207 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn);
24208 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t));
24209 +
24210 + tmpReg |= TX_SACFG_ACTIVE;
24211 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
24212 +
24213 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24214 +
24215 + return err;
24216 +}
24217 +
24218 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
24219 +{
24220 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24221 + t_Error err = E_OK;
24222 + uint32_t tmpReg = 0, i, intFlags;
24223 +
24224 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24225 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24226 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24227 +
24228 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24229 +
24230 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24231 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0);
24232 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0);
24233 + for (i=0; i<4; i++)
24234 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0);
24235 +
24236 + tmpReg |= RX_SACFG_ACTIVE;
24237 + tmpReg &= ~RX_SACFG_EN_MASK;
24238 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24239 +
24240 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24241 +
24242 + return err;
24243 +}
24244 +
24245 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
24246 +{
24247 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24248 + t_Error err = E_OK;
24249 + uint32_t tmpReg = 0, i, intFlags;
24250 +
24251 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24252 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24253 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24254 +
24255 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24256 +
24257 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24258 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0);
24259 + for (i=0; i<4; i++)
24260 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0);
24261 +
24262 + tmpReg |= TX_SACFG_ACTIVE;
24263 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
24264 +
24265 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24266 +
24267 + return err;
24268 +}
24269 +
24270 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive)
24271 +{
24272 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24273 + t_Error err = E_OK;
24274 + uint32_t tmpReg = 0, intFlags;
24275 +
24276 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24277 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24278 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24279 +
24280 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24281 +
24282 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24283 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs);
24284 + if (enableReceive)
24285 + tmpReg |= RX_SACFG_EN_MASK;
24286 + else
24287 + tmpReg &= ~RX_SACFG_EN_MASK;
24288 +
24289 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24290 +
24291 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24292 +
24293 + return err;
24294 +}
24295 +
24296 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN)
24297 +{
24298 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24299 + t_Error err = E_OK;
24300 + uint32_t intFlags;
24301 +
24302 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24303 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24304 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24305 +
24306 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24307 +
24308 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24309 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN);
24310 +
24311 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24312 +
24313 + return err;
24314 +}
24315 +
24316 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN)
24317 +{
24318 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24319 + t_Error err = E_OK;
24320 + uint32_t intFlags;
24321 +
24322 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24323 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24324 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24325 +
24326 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24327 +
24328 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24329 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN);
24330 +
24331 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24332 +
24333 + return err;
24334 +}
24335 +
24336 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an)
24337 +{
24338 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24339 + t_Error err = E_OK;
24340 + uint32_t tmpReg = 0, intFlags;
24341 +
24342 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24343 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24344 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24345 +
24346 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24347 +
24348 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24349 +
24350 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24351 +
24352 + tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK);
24353 + tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK);
24354 +
24355 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24356 +
24357 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24358 +
24359 + return err;
24360 +}
24361 +
24362 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An)
24363 +{
24364 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24365 + t_Error err = E_OK;
24366 + uint32_t tmpReg = 0, intFlags;
24367 +
24368 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24369 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24370 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
24371 +
24372 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24373 +
24374 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24375 +
24376 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24377 +
24378 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24379 +
24380 + *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT);
24381 +
24382 + return err;
24383 +}
24384 +
24385 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable)
24386 +{
24387 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24388 + uint32_t bitMask;
24389 +
24390 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24391 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24392 +
24393 + GET_EXCEPTION_FLAG(bitMask, exception, scId);
24394 + if (bitMask)
24395 + {
24396 + if (enable)
24397 + p_FmMacsec->exceptions |= bitMask;
24398 + else
24399 + p_FmMacsec->exceptions &= ~bitMask;
24400 + }
24401 + else
24402 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
24403 +
24404 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
24405 +
24406 + return E_OK;
24407 +}
24408 +
24409 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable)
24410 +{
24411 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24412 + uint32_t bitMask;
24413 +
24414 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24415 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24416 +
24417 + GET_EVENT_FLAG(bitMask, event, scId);
24418 + if (bitMask)
24419 + {
24420 + if (enable)
24421 + p_FmMacsec->events |= bitMask;
24422 + else
24423 + p_FmMacsec->events &= ~bitMask;
24424 + }
24425 + else
24426 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
24427 +
24428 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events);
24429 +
24430 + return E_OK;
24431 +}
24432 +
24433 +/****************************************/
24434 +/* API Init unit functions */
24435 +/****************************************/
24436 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam)
24437 +{
24438 + t_FmMacsec *p_FmMacsec;
24439 + uint32_t macId;
24440 +
24441 + /* Allocate FM MACSEC structure */
24442 + p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec));
24443 + if (!p_FmMacsec)
24444 + {
24445 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure"));
24446 + return NULL;
24447 + }
24448 + memset(p_FmMacsec, 0, sizeof(t_FmMacsec));
24449 + InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver);
24450 +
24451 + /* Allocate the FM MACSEC driver's parameters structure */
24452 + p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam));
24453 + if (!p_FmMacsec->p_FmMacsecDriverParam)
24454 + {
24455 + XX_Free(p_FmMacsec);
24456 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters"));
24457 + return NULL;
24458 + }
24459 + memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam));
24460 +
24461 + /* Initialize FM MACSEC parameters which will be kept by the driver */
24462 + p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm;
24463 + p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac;
24464 + p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr);
24465 + p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception;
24466 + p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App;
24467 + p_FmMacsec->userExceptions = DEFAULT_userExceptions;
24468 + p_FmMacsec->exceptions = DEFAULT_exceptions;
24469 + p_FmMacsec->events = DEFAULT_events;
24470 + p_FmMacsec->rxScSpinLock = XX_InitSpinlock();
24471 + p_FmMacsec->txScSpinLock = XX_InitSpinlock();
24472 +
24473 + /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */
24474 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment;
24475 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment;
24476 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment;
24477 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment;
24478 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable;
24479 + p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP;
24480 + p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode;
24481 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr;
24482 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_sectagOverhead;
24483 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract = DEFAULT_mflSubtract;
24484 + /* build the FM MACSEC master IPC address */
24485 + memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE);
24486 + FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId);
24487 + if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master",
24488 + FmGetId(p_FmMacsec->h_Fm),macId) != 24)
24489 + {
24490 + XX_Free(p_FmMacsec->p_FmMacsecDriverParam);
24491 + XX_Free(p_FmMacsec);
24492 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
24493 + return NULL;
24494 + }
24495 + return p_FmMacsec;
24496 +}
24497 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
24498 new file mode 100644
24499 index 00000000..2296a0f1
24500 --- /dev/null
24501 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
24502 @@ -0,0 +1,479 @@
24503 +/*
24504 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24505 + *
24506 + * Redistribution and use in source and binary forms, with or without
24507 + * modification, are permitted provided that the following conditions are met:
24508 + * * Redistributions of source code must retain the above copyright
24509 + * notice, this list of conditions and the following disclaimer.
24510 + * * Redistributions in binary form must reproduce the above copyright
24511 + * notice, this list of conditions and the following disclaimer in the
24512 + * documentation and/or other materials provided with the distribution.
24513 + * * Neither the name of Freescale Semiconductor nor the
24514 + * names of its contributors may be used to endorse or promote products
24515 + * derived from this software without specific prior written permission.
24516 + *
24517 + *
24518 + * ALTERNATIVELY, this software may be distributed under the terms of the
24519 + * GNU General Public License ("GPL") as published by the Free Software
24520 + * Foundation, either version 2 of that License or (at your option) any
24521 + * later version.
24522 + *
24523 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24524 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24525 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24526 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24527 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24528 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24529 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24530 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24531 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24532 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24533 + */
24534 +
24535 +/******************************************************************************
24536 + @File fm_macsec_master.h
24537 +
24538 + @Description FM MACSEC internal structures and definitions.
24539 +*//***************************************************************************/
24540 +#ifndef __FM_MACSEC_MASTER_H
24541 +#define __FM_MACSEC_MASTER_H
24542 +
24543 +#include "error_ext.h"
24544 +#include "std_ext.h"
24545 +
24546 +#include "fm_macsec.h"
24547 +
24548 +
24549 +#define MACSEC_ICV_SIZE 16
24550 +#define MACSEC_SECTAG_SIZE 16
24551 +#define MACSEC_SCI_SIZE 8
24552 +#define MACSEC_FCS_SIZE 4
24553 +
24554 +/**************************************************************************//**
24555 + @Description Exceptions
24556 +*//***************************************************************************/
24557 +
24558 +#define FM_MACSEC_EX_TX_SC_0 0x80000000
24559 +#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc))
24560 +#define FM_MACSEC_EX_ECC 0x00000001
24561 +
24562 +#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \
24563 + case e_FM_MACSEC_EX_TX_SC: \
24564 + bitMask = FM_MACSEC_EX_TX_SC(id); break; \
24565 + case e_FM_MACSEC_EX_ECC: \
24566 + bitMask = FM_MACSEC_EX_ECC; break; \
24567 + default: bitMask = 0;break;}
24568 +
24569 +#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000
24570 +#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000
24571 +
24572 +#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
24573 + case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \
24574 + bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \
24575 + case e_FM_MACSEC_EX_MULTI_BIT_ECC: \
24576 + bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \
24577 + default: bitMask = 0;break;}
24578 +
24579 +/**************************************************************************//**
24580 + @Description Events
24581 +*//***************************************************************************/
24582 +
24583 +#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000
24584 +#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc))
24585 +
24586 +#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \
24587 + case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \
24588 + bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \
24589 + default: bitMask = 0;break;}
24590 +
24591 +/**************************************************************************//**
24592 + @Description Defaults
24593 +*//***************************************************************************/
24594 +#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\
24595 + FM_MACSEC_USER_EX_MULTI_BIT_ECC)
24596 +
24597 +#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\
24598 + FM_MACSEC_EX_TX_SC(1) |\
24599 + FM_MACSEC_EX_TX_SC(2) |\
24600 + FM_MACSEC_EX_TX_SC(3) |\
24601 + FM_MACSEC_EX_TX_SC(4) |\
24602 + FM_MACSEC_EX_TX_SC(5) |\
24603 + FM_MACSEC_EX_TX_SC(6) |\
24604 + FM_MACSEC_EX_TX_SC(7) |\
24605 + FM_MACSEC_EX_TX_SC(8) |\
24606 + FM_MACSEC_EX_TX_SC(9) |\
24607 + FM_MACSEC_EX_TX_SC(10) |\
24608 + FM_MACSEC_EX_TX_SC(11) |\
24609 + FM_MACSEC_EX_TX_SC(12) |\
24610 + FM_MACSEC_EX_TX_SC(13) |\
24611 + FM_MACSEC_EX_TX_SC(14) |\
24612 + FM_MACSEC_EX_TX_SC(15) |\
24613 + FM_MACSEC_EX_ECC )
24614 +
24615 +#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\
24616 + FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\
24617 + FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\
24618 + FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\
24619 + FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\
24620 + FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\
24621 + FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\
24622 + FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\
24623 + FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\
24624 + FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\
24625 + FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\
24626 + FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\
24627 + FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\
24628 + FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\
24629 + FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\
24630 + FM_MACSEC_EV_TX_SC_NEXT_PN(15) )
24631 +
24632 +#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH
24633 +#define DEFAULT_invalidTagsFrameTreatment FALSE
24634 +#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE
24635 +#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED
24636 +#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE
24637 +#define DEFAULT_onlyScbIsSetFrameTreatment FALSE
24638 +#define DEFAULT_keysUnreadable FALSE
24639 +#define DEFAULT_normalMode TRUE
24640 +#define DEFAULT_sc0ReservedForPTP FALSE
24641 +#define DEFAULT_initNextPn 1
24642 +#define DEFAULT_pnExhThr 0xffffffff
24643 +#define DEFAULT_sectagOverhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE)
24644 +#define DEFAULT_mflSubtract MACSEC_FCS_SIZE
24645 +
24646 +
24647 +/**************************************************************************//**
24648 + @Description Memory Mapped Registers
24649 +*//***************************************************************************/
24650 +
24651 +#if defined(__MWERKS__) && !defined(__GNUC__)
24652 +#pragma pack(push,1)
24653 +#endif /* defined(__MWERKS__) && ... */
24654 +
24655 +typedef _Packed struct
24656 +{
24657 + /* MACsec configuration */
24658 + volatile uint32_t cfg; /**< MACsec configuration */
24659 + volatile uint32_t et; /**< MACsec EtherType */
24660 + volatile uint8_t res1[56]; /**< reserved */
24661 + volatile uint32_t mfl; /**< Maximum Frame Length */
24662 + volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */
24663 + volatile uint8_t res2[56]; /**< reserved */
24664 + volatile uint32_t rxsca; /**< RX SC access select */
24665 + volatile uint8_t res3[60]; /**< reserved */
24666 + volatile uint32_t txsca; /**< TX SC access select */
24667 + volatile uint8_t res4[60]; /**< reserved */
24668 +
24669 + /* RX configuration, status and statistic */
24670 + volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */
24671 + volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */
24672 + volatile uint8_t res5[8]; /**< reserved */
24673 + volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */
24674 + volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */
24675 + volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */
24676 + volatile uint8_t res6[4]; /**< reserved */
24677 + volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */
24678 + volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */
24679 + volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */
24680 + volatile uint32_t rpw; /**< replayWindow */
24681 + volatile uint8_t res7[16]; /**< reserved */
24682 + volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */
24683 + volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */
24684 + volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */
24685 + volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */
24686 + volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */
24687 + volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */
24688 + volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */
24689 + volatile uint8_t res8[4]; /**< reserved */
24690 + volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */
24691 + volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */
24692 + _Packed struct
24693 + {
24694 + volatile uint32_t rxsacs; /**< RX Security Association configuration and status */
24695 + volatile uint32_t rxsanpn; /**< RX Security Association nextPN */
24696 + volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */
24697 + volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */
24698 + volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */
24699 + volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */
24700 + volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */
24701 + volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */
24702 + volatile uint8_t res9[8]; /**< reserved */
24703 + } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC];
24704 +
24705 + /* TX configuration, status and statistic */
24706 + volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */
24707 + volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */
24708 + volatile uint8_t res10[8]; /**< reserved */
24709 + volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */
24710 + volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */
24711 + volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */
24712 + volatile uint32_t opus; /**< OutPktsUntagged Statistic */
24713 + volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */
24714 + volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */
24715 + volatile uint32_t txsccfg; /**< TX Secure Channel configuration */
24716 + volatile uint32_t optls; /**< OutPktsTooLong Statistic */
24717 + volatile uint8_t res11[16]; /**< reserved */
24718 + volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */
24719 + volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */
24720 + volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */
24721 + volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */
24722 + volatile uint8_t res12[48]; /**< reserved */
24723 + _Packed struct
24724 + {
24725 + volatile uint32_t txsacs; /**< TX Security Association configuration and status */
24726 + volatile uint32_t txsanpn; /**< TX Security Association nextPN */
24727 + volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */
24728 + volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */
24729 + volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */
24730 + volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */
24731 + volatile uint8_t res13[16]; /**< reserved */
24732 + } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC];
24733 + volatile uint8_t res14[248]; /**< reserved */
24734 +
24735 + /* Global configuration and status */
24736 + volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */
24737 + volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */
24738 + volatile uint32_t evr; /**< MACsec Event Register */
24739 + volatile uint32_t ever; /**< MACsec Event Enable Register */
24740 + volatile uint32_t evfr; /**< MACsec Event Force Register */
24741 + volatile uint32_t err; /**< MACsec Error Register */
24742 + volatile uint32_t erer; /**< MACsec Error Enable Register */
24743 + volatile uint32_t erfr; /**< MACsec Error Force Register */
24744 + volatile uint8_t res15[40]; /**< reserved */
24745 + volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */
24746 + volatile uint32_t idle; /**< MACsec Idle status Register */
24747 + volatile uint8_t res16[184]; /**< reserved */
24748 + /* DEBUG */
24749 + volatile uint32_t rxec; /**< MACsec RX error capture Register */
24750 + volatile uint8_t res17[28]; /**< reserved */
24751 + volatile uint32_t txec; /**< MACsec TX error capture Register */
24752 + volatile uint8_t res18[220]; /**< reserved */
24753 +
24754 + /* Macsec Rx global statistic */
24755 + volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */
24756 + volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */
24757 + volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */
24758 + volatile uint8_t res19[4]; /**< reserved */
24759 + volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */
24760 + volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */
24761 + volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */
24762 + volatile uint8_t res20[4]; /**< reserved */
24763 + volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */
24764 + volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */
24765 + volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */
24766 + volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */
24767 + volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */
24768 + volatile uint32_t ipkays; /**< InPktsKaY Statistic */
24769 + volatile uint32_t ipbts; /**< InPktsBadTag Statistic */
24770 + volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */
24771 + volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */
24772 + volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */
24773 + volatile uint32_t iptls; /**< InPktsTooLong Statistic */
24774 + volatile uint8_t res21[52]; /**< reserved */
24775 +
24776 + /* Macsec Tx global statistic */
24777 + volatile uint32_t opds; /**< OutPktsDiscarded Statistic */
24778 +#if (DPAA_VERSION >= 11)
24779 + volatile uint8_t res22[124]; /**< reserved */
24780 + _Packed struct
24781 + {
24782 + volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */
24783 + volatile uint8_t res23[32]; /**< reserved */
24784 + } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC];
24785 + _Packed struct
24786 + {
24787 + volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */
24788 + volatile uint8_t res24[32]; /**< reserved */
24789 + } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC];
24790 +#endif /* (DPAA_VERSION >= 11) */
24791 +} _PackedType t_FmMacsecRegs;
24792 +
24793 +#if defined(__MWERKS__) && !defined(__GNUC__)
24794 +#pragma pack(pop)
24795 +#endif /* defined(__MWERKS__) && ... */
24796 +
24797 +
24798 +/**************************************************************************//**
24799 + @Description General defines
24800 +*//***************************************************************************/
24801 +
24802 +#define SCI_HIGH_MASK 0xffffffff00000000LL
24803 +#define SCI_LOW_MASK 0x00000000ffffffffLL
24804 +
24805 +#define LONG_SHIFT 32
24806 +
24807 +#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT)
24808 +#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK)
24809 +
24810 +/**************************************************************************//**
24811 + @Description Configuration defines
24812 +*//***************************************************************************/
24813 +
24814 +/* masks */
24815 +#define CFG_UECT 0x00000800
24816 +#define CFG_ESCBT 0x00000400
24817 +#define CFG_USFT 0x00000300
24818 +#define CFG_ITT 0x00000080
24819 +#define CFG_KFT 0x00000040
24820 +#define CFG_UFT 0x00000030
24821 +#define CFG_KSS 0x00000004
24822 +#define CFG_BYPN 0x00000002
24823 +#define CFG_S0I 0x00000001
24824 +
24825 +#define ET_TYPE 0x0000ffff
24826 +
24827 +#define MFL_MAX_LEN 0x0000ffff
24828 +
24829 +#define RXSCA_SC_SEL 0x0000000f
24830 +
24831 +#define TXSCA_SC_SEL 0x0000000f
24832 +
24833 +#define IP_REV_1_IP_ID 0xffff0000
24834 +#define IP_REV_1_IP_MJ 0x0000ff00
24835 +#define IP_REV_1_IP_MM 0x000000ff
24836 +
24837 +#define IP_REV_2_IP_INT 0x00ff0000
24838 +#define IP_REV_2_IP_ERR 0x0000ff00
24839 +#define IP_REV_2_IP_CFG 0x000000ff
24840 +
24841 +#define MECC_CAP 0x80000000
24842 +#define MECC_CET 0x40000000
24843 +#define MECC_SERCNT 0x00ff0000
24844 +#define MECC_MEMADDR 0x000001ff
24845 +
24846 +/* shifts */
24847 +#define CFG_UECT_SHIFT (31-20)
24848 +#define CFG_ESCBT_SHIFT (31-21)
24849 +#define CFG_USFT_SHIFT (31-23)
24850 +#define CFG_ITT_SHIFT (31-24)
24851 +#define CFG_KFT_SHIFT (31-25)
24852 +#define CFG_UFT_SHIFT (31-27)
24853 +#define CFG_KSS_SHIFT (31-29)
24854 +#define CFG_BYPN_SHIFT (31-30)
24855 +#define CFG_S0I_SHIFT (31-31)
24856 +
24857 +#define IP_REV_1_IP_ID_SHIFT (31-15)
24858 +#define IP_REV_1_IP_MJ_SHIFT (31-23)
24859 +#define IP_REV_1_IP_MM_SHIFT (31-31)
24860 +
24861 +#define IP_REV_2_IP_INT_SHIFT (31-15)
24862 +#define IP_REV_2_IP_ERR_SHIFT (31-23)
24863 +#define IP_REV_2_IP_CFG_SHIFT (31-31)
24864 +
24865 +#define MECC_CAP_SHIFT (31-0)
24866 +#define MECC_CET_SHIFT (31-1)
24867 +#define MECC_SERCNT_SHIFT (31-15)
24868 +#define MECC_MEMADDR_SHIFT (31-31)
24869 +
24870 +/**************************************************************************//**
24871 + @Description RX SC defines
24872 +*//***************************************************************************/
24873 +
24874 +/* masks */
24875 +#define RX_SCCFG_SCI_EN_MASK 0x00000800
24876 +#define RX_SCCFG_RP_MASK 0x00000400
24877 +#define RX_SCCFG_VF_MASK 0x00000300
24878 +#define RX_SCCFG_CO_MASK 0x0000003f
24879 +
24880 +/* shifts */
24881 +#define RX_SCCFG_SCI_EN_SHIFT (31-20)
24882 +#define RX_SCCFG_RP_SHIFT (31-21)
24883 +#define RX_SCCFG_VF_SHIFT (31-23)
24884 +#define RX_SCCFG_CO_SHIFT (31-31)
24885 +#define RX_SCCFG_CS_SHIFT (31-7)
24886 +
24887 +/**************************************************************************//**
24888 + @Description RX SA defines
24889 +*//***************************************************************************/
24890 +
24891 +/* masks */
24892 +#define RX_SACFG_ACTIVE 0x80000000
24893 +#define RX_SACFG_AN_MASK 0x00000006
24894 +#define RX_SACFG_EN_MASK 0x00000001
24895 +
24896 +/* shifts */
24897 +#define RX_SACFG_AN_SHIFT (31-30)
24898 +#define RX_SACFG_EN_SHIFT (31-31)
24899 +
24900 +/**************************************************************************//**
24901 + @Description TX SC defines
24902 +*//***************************************************************************/
24903 +
24904 +/* masks */
24905 +#define TX_SCCFG_AN_MASK 0x000c0000
24906 +#define TX_SCCFG_ASA_MASK 0x00020000
24907 +#define TX_SCCFG_SCE_MASK 0x00010000
24908 +#define TX_SCCFG_CO_MASK 0x00003f00
24909 +#define TX_SCCFG_CE_MASK 0x00000010
24910 +#define TX_SCCFG_PF_MASK 0x00000008
24911 +#define TX_SCCFG_AIS_MASK 0x00000004
24912 +#define TX_SCCFG_UES_MASK 0x00000002
24913 +#define TX_SCCFG_USCB_MASK 0x00000001
24914 +
24915 +/* shifts */
24916 +#define TX_SCCFG_AN_SHIFT (31-13)
24917 +#define TX_SCCFG_ASA_SHIFT (31-14)
24918 +#define TX_SCCFG_SCE_SHIFT (31-15)
24919 +#define TX_SCCFG_CO_SHIFT (31-23)
24920 +#define TX_SCCFG_CE_SHIFT (31-27)
24921 +#define TX_SCCFG_PF_SHIFT (31-28)
24922 +#define TX_SCCFG_AIS_SHIFT (31-29)
24923 +#define TX_SCCFG_UES_SHIFT (31-30)
24924 +#define TX_SCCFG_USCB_SHIFT (31-31)
24925 +#define TX_SCCFG_CS_SHIFT (31-7)
24926 +
24927 +/**************************************************************************//**
24928 + @Description TX SA defines
24929 +*//***************************************************************************/
24930 +
24931 +/* masks */
24932 +#define TX_SACFG_ACTIVE 0x80000000
24933 +
24934 +
24935 +typedef struct
24936 +{
24937 + void (*f_Isr) (t_Handle h_Arg, uint32_t id);
24938 + t_Handle h_SrcHandle;
24939 +} t_FmMacsecIntrSrc;
24940 +
24941 +typedef struct
24942 +{
24943 + e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode;
24944 + bool invalidTagsDeliverUncontrolled;
24945 + bool changedTextWithNoEncryptDeliverUncontrolled;
24946 + bool onlyScbIsSetDeliverUncontrolled;
24947 + bool encryptWithNoChangedTextDiscardUncontrolled;
24948 + e_FmMacsecUntagFrameTreatment untagTreatMode;
24949 + uint32_t pnExhThr;
24950 + bool keysUnreadable;
24951 + bool byPassMode;
24952 + bool reservedSc0;
24953 + uint32_t sectagOverhead;
24954 + uint32_t mflSubtract;
24955 +} t_FmMacsecDriverParam;
24956 +
24957 +typedef struct
24958 +{
24959 + t_FmMacsecControllerDriver fmMacsecControllerDriver;
24960 + t_Handle h_Fm;
24961 + t_FmMacsecRegs *p_FmMacsecRegs;
24962 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
24963 + char fmMacsecModuleName[MODULE_NAME_SIZE];
24964 + t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS];
24965 + uint32_t events;
24966 + uint32_t exceptions;
24967 + uint32_t userExceptions;
24968 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
24969 + t_Handle h_App; /**< A handle to an application layer object; This handle will
24970 + be passed by the driver upon calling the above callbacks */
24971 + bool rxScTable[NUM_OF_RX_SC];
24972 + uint32_t numRxScAvailable;
24973 + bool txScTable[NUM_OF_TX_SC];
24974 + uint32_t numTxScAvailable;
24975 + t_Handle rxScSpinLock;
24976 + t_Handle txScSpinLock;
24977 + t_FmMacsecDriverParam *p_FmMacsecDriverParam;
24978 +} t_FmMacsec;
24979 +
24980 +
24981 +#endif /* __FM_MACSEC_MASTER_H */
24982 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
24983 new file mode 100644
24984 index 00000000..7c72dc98
24985 --- /dev/null
24986 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
24987 @@ -0,0 +1,883 @@
24988 +/*
24989 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24990 + *
24991 + * Redistribution and use in source and binary forms, with or without
24992 + * modification, are permitted provided that the following conditions are met:
24993 + * * Redistributions of source code must retain the above copyright
24994 + * notice, this list of conditions and the following disclaimer.
24995 + * * Redistributions in binary form must reproduce the above copyright
24996 + * notice, this list of conditions and the following disclaimer in the
24997 + * documentation and/or other materials provided with the distribution.
24998 + * * Neither the name of Freescale Semiconductor nor the
24999 + * names of its contributors may be used to endorse or promote products
25000 + * derived from this software without specific prior written permission.
25001 + *
25002 + *
25003 + * ALTERNATIVELY, this software may be distributed under the terms of the
25004 + * GNU General Public License ("GPL") as published by the Free Software
25005 + * Foundation, either version 2 of that License or (at your option) any
25006 + * later version.
25007 + *
25008 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25009 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25010 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25011 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25012 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25013 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25014 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25015 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25016 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25017 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25018 + */
25019 +
25020 +/******************************************************************************
25021 + @File fm_macsec_secy.c
25022 +
25023 + @Description FM MACSEC SECY driver routines implementation.
25024 +*//***************************************************************************/
25025 +
25026 +#include "std_ext.h"
25027 +#include "error_ext.h"
25028 +#include "xx_ext.h"
25029 +#include "string_ext.h"
25030 +#include "sprint_ext.h"
25031 +
25032 +#include "fm_macsec_secy.h"
25033 +
25034 +
25035 +/****************************************/
25036 +/* static functions */
25037 +/****************************************/
25038 +static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
25039 +{
25040 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25041 +
25042 + UNUSED(id);
25043 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
25044 +
25045 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25046 + p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED);
25047 +}
25048 +
25049 +static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
25050 +{
25051 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25052 +
25053 + UNUSED(id);
25054 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
25055 +
25056 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25057 + p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN);
25058 +}
25059 +
25060 +static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY)
25061 +{
25062 + if (!p_FmMacsecSecY->f_Exception)
25063 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
25064 +
25065 + if (!p_FmMacsecSecY->f_Event)
25066 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided"));
25067 +
25068 + if (!p_FmMacsecSecY->numOfRxSc)
25069 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'"));
25070 +
25071 +
25072 + return E_OK;
25073 +}
25074 +
25075 +static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY,
25076 + macsecSCI_t sci,
25077 + e_FmMacsecSecYCipherSuite cipherSuite,
25078 + e_ScType type)
25079 +{
25080 + t_SecYSc *p_ScTable;
25081 + void *p_Params;
25082 + uint32_t numOfSc,i;
25083 + t_Error err = E_OK;
25084 + t_RxScParams rxScParams;
25085 + t_TxScParams txScParams;
25086 +
25087 + ASSERT_COND(p_FmMacsecSecY);
25088 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
25089 +
25090 + if (type == e_SC_RX)
25091 + {
25092 + memset(&rxScParams, 0, sizeof(rxScParams));
25093 + i = (NUM_OF_RX_SC - 1);
25094 + p_ScTable = p_FmMacsecSecY->p_RxSc;
25095 + numOfSc = p_FmMacsecSecY->numOfRxSc;
25096 + rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
25097 + rxScParams.replayProtect = p_FmMacsecSecY->replayProtect;
25098 + rxScParams.replayWindow = p_FmMacsecSecY->replayWindow;
25099 + rxScParams.validateFrames = p_FmMacsecSecY->validateFrames;
25100 + rxScParams.cipherSuite = cipherSuite;
25101 + p_Params = &rxScParams;
25102 + }
25103 + else
25104 + {
25105 + memset(&txScParams, 0, sizeof(txScParams));
25106 + i = (NUM_OF_TX_SC - 1);
25107 + p_ScTable = p_FmMacsecSecY->p_TxSc;
25108 + numOfSc = p_FmMacsecSecY->numOfTxSc;
25109 + txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode;
25110 + txScParams.protectFrames = p_FmMacsecSecY->protectFrames;
25111 + txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable;
25112 + txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
25113 + txScParams.cipherSuite = cipherSuite;
25114 + p_Params = &txScParams;
25115 + }
25116 +
25117 + for (i=0;i<numOfSc;i++)
25118 + if (!p_ScTable[i].inUse)
25119 + break;
25120 + if (i == numOfSc)
25121 + {
25122 + REPORT_ERROR(MAJOR, E_FULL, ("FM MACSEC SECY SC"));
25123 + return NULL;
25124 + }
25125 +
25126 + if (type == e_SC_RX)
25127 + {
25128 + ((t_RxScParams *)p_Params)->scId = p_ScTable[i].scId;
25129 + ((t_RxScParams *)p_Params)->sci = sci;
25130 + if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK)
25131 + {
25132 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
25133 + return NULL;
25134 + }
25135 + }
25136 + else
25137 + {
25138 + ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId;
25139 + ((t_TxScParams *)p_Params)->sci = sci;
25140 + if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK)
25141 + {
25142 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
25143 + return NULL;
25144 + }
25145 + }
25146 +
25147 + p_ScTable[i].inUse = TRUE;
25148 + return &p_ScTable[i];
25149 +}
25150 +
25151 +static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type)
25152 +{
25153 + t_Error err = E_OK;
25154 +
25155 + ASSERT_COND(p_FmMacsecSecY);
25156 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
25157 + ASSERT_COND(p_FmSecYSc);
25158 +
25159 + if (type == e_SC_RX)
25160 + {
25161 + if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
25162 + RETURN_ERROR(MINOR, err, NO_MSG);
25163 + }
25164 + else
25165 + if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
25166 + RETURN_ERROR(MINOR, err, NO_MSG);
25167 +
25168 + p_FmSecYSc->inUse = FALSE;
25169 +
25170 + return err;
25171 +}
25172 +
25173 +/****************************************/
25174 +/* API Init unit functions */
25175 +/****************************************/
25176 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam)
25177 +{
25178 + t_FmMacsecSecY *p_FmMacsecSecY;
25179 +
25180 + /* Allocate FM MACSEC structure */
25181 + p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY));
25182 + if (!p_FmMacsecSecY)
25183 + {
25184 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure"));
25185 + return NULL;
25186 + }
25187 + memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY));
25188 +
25189 + /* Allocate the FM MACSEC driver's parameters structure */
25190 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam));
25191 + if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam)
25192 + {
25193 + XX_Free(p_FmMacsecSecY);
25194 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters"));
25195 + return NULL;
25196 + }
25197 + memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam));
25198 +
25199 + /* Initialize FM MACSEC SECY parameters which will be kept by the driver */
25200 + p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec;
25201 + p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event;
25202 + p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception;
25203 + p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App;
25204 + p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable;
25205 + p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset;
25206 + p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames;
25207 + p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable;
25208 + p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow;
25209 + p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames;
25210 + p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode;
25211 + p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp;
25212 + p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels;
25213 + p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc;
25214 + p_FmMacsecSecY->exceptions = DEFAULT_exceptions;
25215 + p_FmMacsecSecY->events = DEFAULT_events;
25216 +
25217 + memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams,
25218 + &p_FmMacsecSecYParam->txScParams,
25219 + sizeof(t_FmMacsecSecYSCParams));
25220 + return p_FmMacsecSecY;
25221 +}
25222 +
25223 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY)
25224 +{
25225 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25226 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL;
25227 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j;
25228 + t_Error err;
25229 +
25230 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25231 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE);
25232 +
25233 + CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters);
25234 +
25235 + p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam;
25236 +
25237 + if ((p_FmMacsecSecY->isPointToPoint) &&
25238 + ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK))
25239 + RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point"));
25240 +
25241 + /* Rx Sc Allocation */
25242 + p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
25243 + if (!p_FmMacsecSecY->p_RxSc)
25244 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
25245 + memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
25246 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25247 + {
25248 + if (p_FmMacsecSecY->p_TxSc)
25249 + XX_Free(p_FmMacsecSecY->p_TxSc);
25250 + if (p_FmMacsecSecY->p_RxSc)
25251 + XX_Free(p_FmMacsecSecY->p_RxSc);
25252 + return ERROR_CODE(err);
25253 + }
25254 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25255 + {
25256 + p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i];
25257 + p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX;
25258 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
25259 + p_FmMacsecSecY->p_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25260 + }
25261 +
25262 + /* Tx Sc Allocation */
25263 + p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
25264 + if (!p_FmMacsecSecY->p_TxSc)
25265 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
25266 + memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
25267 +
25268 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25269 + {
25270 + if (p_FmMacsecSecY->p_TxSc)
25271 + XX_Free(p_FmMacsecSecY->p_TxSc);
25272 + if (p_FmMacsecSecY->p_RxSc)
25273 + XX_Free(p_FmMacsecSecY->p_RxSc);
25274 + return ERROR_CODE(err);
25275 + }
25276 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++)
25277 + {
25278 + p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i];
25279 + p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX;
25280 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
25281 + p_FmMacsecSecY->p_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25282 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
25283 + e_FM_MACSEC_MOD_SC_TX,
25284 + (uint8_t)txScIds[i],
25285 + e_FM_INTR_TYPE_ERR,
25286 + FmMacsecSecYExceptionsIsr,
25287 + p_FmMacsecSecY);
25288 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
25289 + e_FM_MACSEC_MOD_SC_TX,
25290 + (uint8_t)txScIds[i],
25291 + e_FM_INTR_TYPE_NORMAL,
25292 + FmMacsecSecYEventsIsr,
25293 + p_FmMacsecSecY);
25294 +
25295 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25296 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE);
25297 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25298 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE);
25299 + }
25300 +
25301 + FmMacsecSecYCreateSc(p_FmMacsecSecY,
25302 + p_FmMacsecSecYDriverParam->txScParams.sci,
25303 + p_FmMacsecSecYDriverParam->txScParams.cipherSuite,
25304 + e_SC_TX);
25305 + XX_Free(p_FmMacsecSecYDriverParam);
25306 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL;
25307 +
25308 + return E_OK;
25309 +}
25310 +
25311 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY)
25312 +{
25313 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25314 + t_Error err = E_OK;
25315 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i;
25316 +
25317 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25318 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25319 +
25320 + if (p_FmMacsecSecY->isPointToPoint)
25321 + FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE);
25322 + if (p_FmMacsecSecY->p_RxSc)
25323 + {
25324 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25325 + rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId;
25326 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25327 + return ERROR_CODE(err);
25328 + XX_Free(p_FmMacsecSecY->p_RxSc);
25329 + }
25330 + if (p_FmMacsecSecY->p_TxSc)
25331 + {
25332 + FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX);
25333 +
25334 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++) {
25335 + txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId;
25336 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25337 + e_FM_MACSEC_MOD_SC_TX,
25338 + (uint8_t)txScIds[i],
25339 + e_FM_INTR_TYPE_ERR);
25340 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25341 + e_FM_MACSEC_MOD_SC_TX,
25342 + (uint8_t)txScIds[i],
25343 + e_FM_INTR_TYPE_NORMAL);
25344 +
25345 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25346 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE);
25347 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25348 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE);
25349 + }
25350 +
25351 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25352 + return ERROR_CODE(err);
25353 + XX_Free(p_FmMacsecSecY->p_TxSc);
25354 + }
25355 +
25356 + XX_Free(p_FmMacsecSecY);
25357 +
25358 + return err;
25359 +}
25360 +
25361 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode)
25362 +{
25363 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25364 +
25365 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25366 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25367 +
25368 + p_FmMacsecSecY->sciInsertionMode = sciInsertionMode;
25369 +
25370 + return E_OK;
25371 +}
25372 +
25373 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames)
25374 +{
25375 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25376 +
25377 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25378 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25379 +
25380 + p_FmMacsecSecY->protectFrames = protectFrames;
25381 +
25382 + return E_OK;
25383 +}
25384 +
25385 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow)
25386 +{
25387 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25388 +
25389 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25390 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25391 +
25392 + p_FmMacsecSecY->replayProtect = replayProtect;
25393 + p_FmMacsecSecY->replayWindow = replayWindow;
25394 +
25395 + return E_OK;
25396 +}
25397 +
25398 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames)
25399 +{
25400 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25401 +
25402 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25403 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25404 +
25405 + p_FmMacsecSecY->validateFrames = validateFrames;
25406 +
25407 + return E_OK;
25408 +}
25409 +
25410 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset)
25411 +{
25412 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25413 +
25414 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25415 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25416 +
25417 + p_FmMacsecSecY->confidentialityEnable = confidentialityEnable;
25418 + p_FmMacsecSecY->confidentialityOffset = confidentialityOffset;
25419 +
25420 + return E_OK;
25421 +}
25422 +
25423 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY)
25424 +{
25425 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25426 +
25427 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25428 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25429 +
25430 + p_FmMacsecSecY->numOfRxSc = 1;
25431 + p_FmMacsecSecY->isPointToPoint = TRUE;
25432 + p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP;
25433 +
25434 + return E_OK;
25435 +}
25436 +
25437 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable)
25438 +{
25439 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25440 + uint32_t bitMask = 0;
25441 +
25442 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25443 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25444 +
25445 + GET_EXCEPTION_FLAG(bitMask, exception);
25446 + if (bitMask)
25447 + {
25448 + if (enable)
25449 + p_FmMacsecSecY->exceptions |= bitMask;
25450 + else
25451 + p_FmMacsecSecY->exceptions &= ~bitMask;
25452 + }
25453 + else
25454 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25455 +
25456 + return E_OK;
25457 +}
25458 +
25459 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25460 +{
25461 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25462 + uint32_t bitMask = 0;
25463 +
25464 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25465 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25466 +
25467 + GET_EVENT_FLAG(bitMask, event);
25468 + if (bitMask)
25469 + {
25470 + if (enable)
25471 + p_FmMacsecSecY->events |= bitMask;
25472 + else
25473 + p_FmMacsecSecY->events &= ~bitMask;
25474 + }
25475 + else
25476 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
25477 +
25478 + return E_OK;
25479 +}
25480 +
25481 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams)
25482 +{
25483 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25484 +
25485 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
25486 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
25487 + SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL);
25488 + SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
25489 +
25490 + return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX);
25491 +}
25492 +
25493 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
25494 +{
25495 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25496 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25497 +
25498 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25499 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25500 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25501 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25502 +
25503 + return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX);
25504 +}
25505 +
25506 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
25507 +{
25508 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25509 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25510 + t_Error err = E_OK;
25511 +
25512 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25513 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25514 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25515 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25516 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25517 +
25518 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25519 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an));
25520 +
25521 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK)
25522 + RETURN_ERROR(MINOR, err, NO_MSG);
25523 +
25524 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25525 + return err;
25526 +}
25527 +
25528 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25529 +{
25530 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25531 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25532 + t_Error err = E_OK;
25533 +
25534 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25535 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25536 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25537 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25538 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25539 +
25540 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25541 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25542 +
25543 + if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25544 + RETURN_ERROR(MINOR, err, NO_MSG);
25545 +
25546 + p_FmSecYSc->numOfSa--;
25547 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25548 + /* TODO - check if statistics need to be read*/
25549 + return err;
25550 +}
25551 +
25552 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25553 +{
25554 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25555 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25556 + t_Error err = E_OK;
25557 +
25558 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25559 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25560 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25561 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25562 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25563 +
25564 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25565 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25566 +
25567 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25568 + RETURN_ERROR(MINOR, err, NO_MSG);
25569 +
25570 + p_FmSecYSc->sa[an].active = TRUE;
25571 + return err;
25572 +}
25573 +
25574 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25575 +{
25576 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25577 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25578 + t_Error err = E_OK;
25579 +
25580 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25581 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25582 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25583 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25584 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25585 +
25586 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25587 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25588 +
25589 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25590 + RETURN_ERROR(MINOR, err, NO_MSG);
25591 +
25592 + p_FmSecYSc->sa[an].active = FALSE;
25593 + return err;
25594 +}
25595 +
25596 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN)
25597 +{
25598 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25599 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25600 + t_Error err = E_OK;
25601 +
25602 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25603 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25604 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25605 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25606 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25607 +
25608 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25609 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25610 +
25611 + if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK)
25612 + RETURN_ERROR(MINOR, err, NO_MSG);
25613 +
25614 + return err;
25615 +}
25616 +
25617 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN)
25618 +{
25619 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25620 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25621 + t_Error err = E_OK;
25622 +
25623 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25624 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25625 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25626 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25627 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25628 +
25629 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25630 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25631 +
25632 + if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK)
25633 + RETURN_ERROR(MINOR, err, NO_MSG);
25634 +
25635 + return err;
25636 +}
25637 +
25638 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key)
25639 +{
25640 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25641 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25642 + t_Error err = E_OK;
25643 +
25644 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25645 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25646 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25647 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25648 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25649 +
25650 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25651 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25652 +
25653 + if (p_FmSecYSc->sa[an].active)
25654 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25655 + RETURN_ERROR(MINOR, err, NO_MSG);
25656 +
25657 + /* TODO - statistics should be read */
25658 +
25659 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK)
25660 + RETURN_ERROR(MINOR, err, NO_MSG);
25661 +
25662 + if (p_FmSecYSc->sa[an].active)
25663 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25664 + RETURN_ERROR(MINOR, err, NO_MSG);
25665 + return err;
25666 +}
25667 +
25668 +
25669 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key)
25670 +{
25671 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25672 + t_SecYSc *p_FmSecYSc;
25673 + t_Error err = E_OK;
25674 +
25675 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25676 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25677 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25678 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25679 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25680 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25681 +
25682 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25683 + RETURN_ERROR(MINOR, err, ("An %d is already assigned",an));
25684 +
25685 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK)
25686 + RETURN_ERROR(MINOR, err, NO_MSG);
25687 +
25688 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25689 + return err;
25690 +}
25691 +
25692 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an)
25693 +{
25694 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25695 + t_SecYSc *p_FmSecYSc;
25696 + t_Error err = E_OK;
25697 +
25698 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25699 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25700 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25701 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25702 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25703 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25704 +
25705 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25706 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25707 +
25708 + if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25709 + RETURN_ERROR(MINOR, err, NO_MSG);
25710 +
25711 + p_FmSecYSc->numOfSa--;
25712 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25713 + /* TODO - check if statistics need to be read*/
25714 + return err;
25715 +}
25716 +
25717 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key)
25718 +{
25719 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25720 + t_SecYSc *p_FmSecYSc;
25721 + macsecAN_t currentAn;
25722 + t_Error err = E_OK;
25723 +
25724 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25725 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25726 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25727 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25728 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25729 + SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25730 +
25731 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25732 + p_FmSecYSc->scId,
25733 + &currentAn)) != E_OK)
25734 + RETURN_ERROR(MINOR, err, NO_MSG);
25735 +
25736 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25737 + p_FmSecYSc->scId,
25738 + p_FmSecYSc->sa[nextActiveAn].saId,
25739 + nextActiveAn)) != E_OK)
25740 + RETURN_ERROR(MINOR, err, NO_MSG);
25741 +
25742 + /* TODO - statistics should be read */
25743 +
25744 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK)
25745 + RETURN_ERROR(MINOR, err, NO_MSG);
25746 +
25747 + return err;
25748 +}
25749 +
25750 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an)
25751 +{
25752 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25753 + t_SecYSc *p_FmSecYSc;
25754 + t_Error err = E_OK;
25755 +
25756 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25757 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25758 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25759 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25760 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25761 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25762 +
25763 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25764 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25765 +
25766 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25767 + p_FmSecYSc->scId,
25768 + p_FmSecYSc->sa[an].saId,
25769 + an)) != E_OK)
25770 + RETURN_ERROR(MINOR, err, NO_MSG);
25771 +
25772 + return err;
25773 +}
25774 +
25775 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An)
25776 +{
25777 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25778 + t_SecYSc *p_FmSecYSc;
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(p_An, E_INVALID_HANDLE);
25787 +
25788 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25789 + p_FmSecYSc->scId,
25790 + p_An)) != E_OK)
25791 + RETURN_ERROR(MINOR, err, NO_MSG);
25792 +
25793 + return err;
25794 +}
25795 +
25796 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId)
25797 +{
25798 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25799 + t_Error err = E_OK;
25800 +
25801 + SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE);
25802 + SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE);
25803 + SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25804 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25805 +#ifdef DISABLE_SANITY_CHECKS
25806 + UNUSED(h_FmMacsecSecY);
25807 +#endif /* DISABLE_SANITY_CHECKS */
25808 +
25809 + *p_ScPhysId = p_FmSecYSc->scId;
25810 + return err;
25811 +}
25812 +
25813 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId)
25814 +{
25815 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25816 + t_SecYSc *p_FmSecYSc;
25817 + t_Error err = E_OK;
25818 +
25819 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25820 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25821 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25822 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25823 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25824 +
25825 + *p_ScPhysId = p_FmSecYSc->scId;
25826 + return err;
25827 +}
25828 +
25829 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable)
25830 +{
25831 + UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable);
25832 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25833 +}
25834 +
25835 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25836 +{
25837 + UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable);
25838 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25839 +}
25840 +
25841 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics)
25842 +{
25843 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25844 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25845 +}
25846 +
25847 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics)
25848 +{
25849 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics);
25850 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25851 +}
25852 +
25853 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics)
25854 +{
25855 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics);
25856 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25857 +}
25858 +
25859 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics)
25860 +{
25861 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25862 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25863 +}
25864 +
25865 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics)
25866 +{
25867 + UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics);
25868 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25869 +}
25870 +
25871 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
25872 new file mode 100644
25873 index 00000000..0cf624e6
25874 --- /dev/null
25875 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
25876 @@ -0,0 +1,144 @@
25877 +/*
25878 + * Copyright 2008-2015 Freescale Semiconductor Inc.
25879 + *
25880 + * Redistribution and use in source and binary forms, with or without
25881 + * modification, are permitted provided that the following conditions are met:
25882 + * * Redistributions of source code must retain the above copyright
25883 + * notice, this list of conditions and the following disclaimer.
25884 + * * Redistributions in binary form must reproduce the above copyright
25885 + * notice, this list of conditions and the following disclaimer in the
25886 + * documentation and/or other materials provided with the distribution.
25887 + * * Neither the name of Freescale Semiconductor nor the
25888 + * names of its contributors may be used to endorse or promote products
25889 + * derived from this software without specific prior written permission.
25890 + *
25891 + *
25892 + * ALTERNATIVELY, this software may be distributed under the terms of the
25893 + * GNU General Public License ("GPL") as published by the Free Software
25894 + * Foundation, either version 2 of that License or (at your option) any
25895 + * later version.
25896 + *
25897 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25898 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25899 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25900 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25901 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25902 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25903 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25904 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25905 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25906 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25907 + */
25908 +
25909 +/******************************************************************************
25910 + @File fm_macsec_secy.h
25911 +
25912 + @Description FM MACSEC SecY internal structures and definitions.
25913 +*//***************************************************************************/
25914 +#ifndef __FM_MACSEC_SECY_H
25915 +#define __FM_MACSEC_SECY_H
25916 +
25917 +#include "error_ext.h"
25918 +#include "std_ext.h"
25919 +
25920 +#include "fm_macsec.h"
25921 +
25922 +
25923 +/**************************************************************************//**
25924 + @Description Exceptions
25925 +*//***************************************************************************/
25926 +
25927 +#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000
25928 +
25929 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
25930 + case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \
25931 + bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \
25932 + default: bitMask = 0;break;}
25933 +
25934 +/**************************************************************************//**
25935 + @Description Events
25936 +*//***************************************************************************/
25937 +
25938 +#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000
25939 +
25940 +#define GET_EVENT_FLAG(bitMask, event) switch (event){ \
25941 + case e_FM_MACSEC_SECY_EV_NEXT_PN: \
25942 + bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \
25943 + default: bitMask = 0;break;}
25944 +
25945 +/**************************************************************************//**
25946 + @Description Defaults
25947 +*//***************************************************************************/
25948 +
25949 +#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25950 +#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN)
25951 +#define DEFAULT_numOfTxSc 1
25952 +#define DEFAULT_confidentialityEnable FALSE
25953 +#define DEFAULT_confidentialityOffset 0
25954 +#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG
25955 +#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
25956 +#define DEFAULT_replayEnable FALSE
25957 +#define DEFAULT_replayWindow 0
25958 +#define DEFAULT_protectFrames TRUE
25959 +#define DEFAULT_ptp FALSE
25960 +
25961 +/**************************************************************************//**
25962 + @Description General defines
25963 +*//***************************************************************************/
25964 +
25965 +#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC
25966 +
25967 +
25968 +typedef struct {
25969 + e_ScSaId saId;
25970 + bool active;
25971 + union {
25972 + t_FmMacsecSecYRxSaStatistics rxSaStatistics;
25973 + t_FmMacsecSecYTxSaStatistics txSaStatistics;
25974 + };
25975 +} t_SecYSa;
25976 +
25977 +typedef struct {
25978 + bool inUse;
25979 + uint32_t scId;
25980 + e_ScType type;
25981 + uint8_t numOfSa;
25982 + t_SecYSa sa[MAX_NUM_OF_SA_PER_SC];
25983 + union {
25984 + t_FmMacsecSecYRxScStatistics rxScStatistics;
25985 + t_FmMacsecSecYTxScStatistics txScStatistics;
25986 + };
25987 +} t_SecYSc;
25988 +
25989 +typedef struct {
25990 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
25991 +} t_FmMacsecSecYDriverParam;
25992 +
25993 +typedef struct {
25994 + t_Handle h_FmMacsec;
25995 + bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection
25996 + FALSE - no confidentiality protection, only integrity protection*/
25997 + uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection
25998 + common values are 0, 30, and 50 */
25999 + bool replayProtect; /**< replay protection function mode */
26000 + uint32_t replayWindow; /**< the size of the replay window */
26001 + e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */
26002 + e_FmMacsecSciInsertionMode sciInsertionMode;
26003 + bool protectFrames;
26004 + bool isPointToPoint;
26005 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */
26006 + uint32_t numOfRxSc; /**< Number of receive channels */
26007 + uint32_t numOfTxSc; /**< Number of transmit channels */
26008 + t_SecYSc *p_RxSc;
26009 + t_SecYSc *p_TxSc;
26010 + uint32_t events;
26011 + uint32_t exceptions;
26012 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */
26013 + t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */
26014 + t_Handle h_App;
26015 + t_FmMacsecSecYStatistics statistics;
26016 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam;
26017 +} t_FmMacsecSecY;
26018 +
26019 +
26020 +#endif /* __FM_MACSEC_SECY_H */
26021 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
26022 new file mode 100644
26023 index 00000000..619f6608
26024 --- /dev/null
26025 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
26026 @@ -0,0 +1,23 @@
26027 +#
26028 +# Makefile for the Freescale Ethernet controllers
26029 +#
26030 +ccflags-y += -DVERSION=\"\"
26031 +#
26032 +#Include netcomm SW specific definitions
26033 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
26034 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
26035 +
26036 +ccflags-y += -I$(NCSW_FM_INC)
26037 +
26038 +
26039 +obj-y += fsl-ncsw-PFM1.o
26040 +
26041 +fsl-ncsw-PFM1-objs := fm.o fm_muram.o fman.o
26042 +
26043 +obj-y += MAC/
26044 +obj-y += Pcd/
26045 +obj-y += SP/
26046 +obj-y += Port/
26047 +obj-y += HC/
26048 +obj-y += Rtc/
26049 +obj-y += MACSEC/
26050 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
26051 new file mode 100644
26052 index 00000000..62fbd73c
26053 --- /dev/null
26054 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
26055 @@ -0,0 +1,26 @@
26056 +#
26057 +# Makefile for the Freescale Ethernet controllers
26058 +#
26059 +ccflags-y += -DVERSION=\"\"
26060 +#
26061 +#Include netcomm SW specific definitions
26062 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
26063 +
26064 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
26065 +
26066 +ccflags-y += -I$(NCSW_FM_INC)
26067 +
26068 +obj-y += fsl-ncsw-Pcd.o
26069 +
26070 +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
26071 +
26072 +ifeq ($(CONFIG_FMAN_V3H),y)
26073 +fsl-ncsw-Pcd-objs += fm_replic.o
26074 +endif
26075 +ifeq ($(CONFIG_FMAN_V3L),y)
26076 +fsl-ncsw-Pcd-objs += fm_replic.o
26077 +endif
26078 +ifeq ($(CONFIG_FMAN_ARM),y)
26079 +fsl-ncsw-Pcd-objs += fm_replic.o
26080 +endif
26081 +
26082 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
26083 new file mode 100644
26084 index 00000000..335ee681
26085 --- /dev/null
26086 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
26087 @@ -0,0 +1,360 @@
26088 +/*
26089 + * Copyright 2008-2012 Freescale Semiconductor Inc.
26090 + *
26091 + * Redistribution and use in source and binary forms, with or without
26092 + * modification, are permitted provided that the following conditions are met:
26093 + * * Redistributions of source code must retain the above copyright
26094 + * notice, this list of conditions and the following disclaimer.
26095 + * * Redistributions in binary form must reproduce the above copyright
26096 + * notice, this list of conditions and the following disclaimer in the
26097 + * documentation and/or other materials provided with the distribution.
26098 + * * Neither the name of Freescale Semiconductor nor the
26099 + * names of its contributors may be used to endorse or promote products
26100 + * derived from this software without specific prior written permission.
26101 + *
26102 + *
26103 + * ALTERNATIVELY, this software may be distributed under the terms of the
26104 + * GNU General Public License ("GPL") as published by the Free Software
26105 + * Foundation, either version 2 of that License or (at your option) any
26106 + * later version.
26107 + *
26108 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26109 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26110 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26111 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26112 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26113 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26114 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26115 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26116 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26117 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26118 + */
26119 +
26120 +
26121 + /**************************************************************************//**
26122 + @File crc64.h
26123 +
26124 + @Description brief This file contains the CRC64 Table, and __inline__
26125 + functions used for calculating crc.
26126 +*//***************************************************************************/
26127 +#ifndef __CRC64_H
26128 +#define __CRC64_H
26129 +
26130 +#include "std_ext.h"
26131 +
26132 +
26133 +#define BITS_PER_BYTE 8
26134 +
26135 +#define CRC64_EXPON_ECMA_182 0xC96C5795D7870F42ULL
26136 +#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL
26137 +
26138 +#define CRC64_BYTE_MASK 0xFF
26139 +#define CRC64_TABLE_ENTRIES ( 1 << BITS_PER_BYTE )
26140 +#define CRC64_ODD_MASK 1
26141 +
26142 +
26143 +/**
26144 + \brief '64 bit crc' Table
26145 + */
26146 +struct crc64_t {
26147 + uint64_t initial; /**< Initial seed */
26148 + uint64_t table[CRC64_TABLE_ENTRIES]; /**< CRC table entries */
26149 +};
26150 +
26151 +
26152 +static struct crc64_t CRC64_ECMA_182 = {
26153 + CRC64_DEFAULT_INITVAL,
26154 + {
26155 + 0x0000000000000000ULL,
26156 + 0xb32e4cbe03a75f6fULL,
26157 + 0xf4843657a840a05bULL,
26158 + 0x47aa7ae9abe7ff34ULL,
26159 + 0x7bd0c384ff8f5e33ULL,
26160 + 0xc8fe8f3afc28015cULL,
26161 + 0x8f54f5d357cffe68ULL,
26162 + 0x3c7ab96d5468a107ULL,
26163 + 0xf7a18709ff1ebc66ULL,
26164 + 0x448fcbb7fcb9e309ULL,
26165 + 0x0325b15e575e1c3dULL,
26166 + 0xb00bfde054f94352ULL,
26167 + 0x8c71448d0091e255ULL,
26168 + 0x3f5f08330336bd3aULL,
26169 + 0x78f572daa8d1420eULL,
26170 + 0xcbdb3e64ab761d61ULL,
26171 + 0x7d9ba13851336649ULL,
26172 + 0xceb5ed8652943926ULL,
26173 + 0x891f976ff973c612ULL,
26174 + 0x3a31dbd1fad4997dULL,
26175 + 0x064b62bcaebc387aULL,
26176 + 0xb5652e02ad1b6715ULL,
26177 + 0xf2cf54eb06fc9821ULL,
26178 + 0x41e11855055bc74eULL,
26179 + 0x8a3a2631ae2dda2fULL,
26180 + 0x39146a8fad8a8540ULL,
26181 + 0x7ebe1066066d7a74ULL,
26182 + 0xcd905cd805ca251bULL,
26183 + 0xf1eae5b551a2841cULL,
26184 + 0x42c4a90b5205db73ULL,
26185 + 0x056ed3e2f9e22447ULL,
26186 + 0xb6409f5cfa457b28ULL,
26187 + 0xfb374270a266cc92ULL,
26188 + 0x48190ecea1c193fdULL,
26189 + 0x0fb374270a266cc9ULL,
26190 + 0xbc9d3899098133a6ULL,
26191 + 0x80e781f45de992a1ULL,
26192 + 0x33c9cd4a5e4ecdceULL,
26193 + 0x7463b7a3f5a932faULL,
26194 + 0xc74dfb1df60e6d95ULL,
26195 + 0x0c96c5795d7870f4ULL,
26196 + 0xbfb889c75edf2f9bULL,
26197 + 0xf812f32ef538d0afULL,
26198 + 0x4b3cbf90f69f8fc0ULL,
26199 + 0x774606fda2f72ec7ULL,
26200 + 0xc4684a43a15071a8ULL,
26201 + 0x83c230aa0ab78e9cULL,
26202 + 0x30ec7c140910d1f3ULL,
26203 + 0x86ace348f355aadbULL,
26204 + 0x3582aff6f0f2f5b4ULL,
26205 + 0x7228d51f5b150a80ULL,
26206 + 0xc10699a158b255efULL,
26207 + 0xfd7c20cc0cdaf4e8ULL,
26208 + 0x4e526c720f7dab87ULL,
26209 + 0x09f8169ba49a54b3ULL,
26210 + 0xbad65a25a73d0bdcULL,
26211 + 0x710d64410c4b16bdULL,
26212 + 0xc22328ff0fec49d2ULL,
26213 + 0x85895216a40bb6e6ULL,
26214 + 0x36a71ea8a7ace989ULL,
26215 + 0x0adda7c5f3c4488eULL,
26216 + 0xb9f3eb7bf06317e1ULL,
26217 + 0xfe5991925b84e8d5ULL,
26218 + 0x4d77dd2c5823b7baULL,
26219 + 0x64b62bcaebc387a1ULL,
26220 + 0xd7986774e864d8ceULL,
26221 + 0x90321d9d438327faULL,
26222 + 0x231c512340247895ULL,
26223 + 0x1f66e84e144cd992ULL,
26224 + 0xac48a4f017eb86fdULL,
26225 + 0xebe2de19bc0c79c9ULL,
26226 + 0x58cc92a7bfab26a6ULL,
26227 + 0x9317acc314dd3bc7ULL,
26228 + 0x2039e07d177a64a8ULL,
26229 + 0x67939a94bc9d9b9cULL,
26230 + 0xd4bdd62abf3ac4f3ULL,
26231 + 0xe8c76f47eb5265f4ULL,
26232 + 0x5be923f9e8f53a9bULL,
26233 + 0x1c4359104312c5afULL,
26234 + 0xaf6d15ae40b59ac0ULL,
26235 + 0x192d8af2baf0e1e8ULL,
26236 + 0xaa03c64cb957be87ULL,
26237 + 0xeda9bca512b041b3ULL,
26238 + 0x5e87f01b11171edcULL,
26239 + 0x62fd4976457fbfdbULL,
26240 + 0xd1d305c846d8e0b4ULL,
26241 + 0x96797f21ed3f1f80ULL,
26242 + 0x2557339fee9840efULL,
26243 + 0xee8c0dfb45ee5d8eULL,
26244 + 0x5da24145464902e1ULL,
26245 + 0x1a083bacedaefdd5ULL,
26246 + 0xa9267712ee09a2baULL,
26247 + 0x955cce7fba6103bdULL,
26248 + 0x267282c1b9c65cd2ULL,
26249 + 0x61d8f8281221a3e6ULL,
26250 + 0xd2f6b4961186fc89ULL,
26251 + 0x9f8169ba49a54b33ULL,
26252 + 0x2caf25044a02145cULL,
26253 + 0x6b055fede1e5eb68ULL,
26254 + 0xd82b1353e242b407ULL,
26255 + 0xe451aa3eb62a1500ULL,
26256 + 0x577fe680b58d4a6fULL,
26257 + 0x10d59c691e6ab55bULL,
26258 + 0xa3fbd0d71dcdea34ULL,
26259 + 0x6820eeb3b6bbf755ULL,
26260 + 0xdb0ea20db51ca83aULL,
26261 + 0x9ca4d8e41efb570eULL,
26262 + 0x2f8a945a1d5c0861ULL,
26263 + 0x13f02d374934a966ULL,
26264 + 0xa0de61894a93f609ULL,
26265 + 0xe7741b60e174093dULL,
26266 + 0x545a57dee2d35652ULL,
26267 + 0xe21ac88218962d7aULL,
26268 + 0x5134843c1b317215ULL,
26269 + 0x169efed5b0d68d21ULL,
26270 + 0xa5b0b26bb371d24eULL,
26271 + 0x99ca0b06e7197349ULL,
26272 + 0x2ae447b8e4be2c26ULL,
26273 + 0x6d4e3d514f59d312ULL,
26274 + 0xde6071ef4cfe8c7dULL,
26275 + 0x15bb4f8be788911cULL,
26276 + 0xa6950335e42fce73ULL,
26277 + 0xe13f79dc4fc83147ULL,
26278 + 0x521135624c6f6e28ULL,
26279 + 0x6e6b8c0f1807cf2fULL,
26280 + 0xdd45c0b11ba09040ULL,
26281 + 0x9aefba58b0476f74ULL,
26282 + 0x29c1f6e6b3e0301bULL,
26283 + 0xc96c5795d7870f42ULL,
26284 + 0x7a421b2bd420502dULL,
26285 + 0x3de861c27fc7af19ULL,
26286 + 0x8ec62d7c7c60f076ULL,
26287 + 0xb2bc941128085171ULL,
26288 + 0x0192d8af2baf0e1eULL,
26289 + 0x4638a2468048f12aULL,
26290 + 0xf516eef883efae45ULL,
26291 + 0x3ecdd09c2899b324ULL,
26292 + 0x8de39c222b3eec4bULL,
26293 + 0xca49e6cb80d9137fULL,
26294 + 0x7967aa75837e4c10ULL,
26295 + 0x451d1318d716ed17ULL,
26296 + 0xf6335fa6d4b1b278ULL,
26297 + 0xb199254f7f564d4cULL,
26298 + 0x02b769f17cf11223ULL,
26299 + 0xb4f7f6ad86b4690bULL,
26300 + 0x07d9ba1385133664ULL,
26301 + 0x4073c0fa2ef4c950ULL,
26302 + 0xf35d8c442d53963fULL,
26303 + 0xcf273529793b3738ULL,
26304 + 0x7c0979977a9c6857ULL,
26305 + 0x3ba3037ed17b9763ULL,
26306 + 0x888d4fc0d2dcc80cULL,
26307 + 0x435671a479aad56dULL,
26308 + 0xf0783d1a7a0d8a02ULL,
26309 + 0xb7d247f3d1ea7536ULL,
26310 + 0x04fc0b4dd24d2a59ULL,
26311 + 0x3886b22086258b5eULL,
26312 + 0x8ba8fe9e8582d431ULL,
26313 + 0xcc0284772e652b05ULL,
26314 + 0x7f2cc8c92dc2746aULL,
26315 + 0x325b15e575e1c3d0ULL,
26316 + 0x8175595b76469cbfULL,
26317 + 0xc6df23b2dda1638bULL,
26318 + 0x75f16f0cde063ce4ULL,
26319 + 0x498bd6618a6e9de3ULL,
26320 + 0xfaa59adf89c9c28cULL,
26321 + 0xbd0fe036222e3db8ULL,
26322 + 0x0e21ac88218962d7ULL,
26323 + 0xc5fa92ec8aff7fb6ULL,
26324 + 0x76d4de52895820d9ULL,
26325 + 0x317ea4bb22bfdfedULL,
26326 + 0x8250e80521188082ULL,
26327 + 0xbe2a516875702185ULL,
26328 + 0x0d041dd676d77eeaULL,
26329 + 0x4aae673fdd3081deULL,
26330 + 0xf9802b81de97deb1ULL,
26331 + 0x4fc0b4dd24d2a599ULL,
26332 + 0xfceef8632775faf6ULL,
26333 + 0xbb44828a8c9205c2ULL,
26334 + 0x086ace348f355aadULL,
26335 + 0x34107759db5dfbaaULL,
26336 + 0x873e3be7d8faa4c5ULL,
26337 + 0xc094410e731d5bf1ULL,
26338 + 0x73ba0db070ba049eULL,
26339 + 0xb86133d4dbcc19ffULL,
26340 + 0x0b4f7f6ad86b4690ULL,
26341 + 0x4ce50583738cb9a4ULL,
26342 + 0xffcb493d702be6cbULL,
26343 + 0xc3b1f050244347ccULL,
26344 + 0x709fbcee27e418a3ULL,
26345 + 0x3735c6078c03e797ULL,
26346 + 0x841b8ab98fa4b8f8ULL,
26347 + 0xadda7c5f3c4488e3ULL,
26348 + 0x1ef430e13fe3d78cULL,
26349 + 0x595e4a08940428b8ULL,
26350 + 0xea7006b697a377d7ULL,
26351 + 0xd60abfdbc3cbd6d0ULL,
26352 + 0x6524f365c06c89bfULL,
26353 + 0x228e898c6b8b768bULL,
26354 + 0x91a0c532682c29e4ULL,
26355 + 0x5a7bfb56c35a3485ULL,
26356 + 0xe955b7e8c0fd6beaULL,
26357 + 0xaeffcd016b1a94deULL,
26358 + 0x1dd181bf68bdcbb1ULL,
26359 + 0x21ab38d23cd56ab6ULL,
26360 + 0x9285746c3f7235d9ULL,
26361 + 0xd52f0e859495caedULL,
26362 + 0x6601423b97329582ULL,
26363 + 0xd041dd676d77eeaaULL,
26364 + 0x636f91d96ed0b1c5ULL,
26365 + 0x24c5eb30c5374ef1ULL,
26366 + 0x97eba78ec690119eULL,
26367 + 0xab911ee392f8b099ULL,
26368 + 0x18bf525d915feff6ULL,
26369 + 0x5f1528b43ab810c2ULL,
26370 + 0xec3b640a391f4fadULL,
26371 + 0x27e05a6e926952ccULL,
26372 + 0x94ce16d091ce0da3ULL,
26373 + 0xd3646c393a29f297ULL,
26374 + 0x604a2087398eadf8ULL,
26375 + 0x5c3099ea6de60cffULL,
26376 + 0xef1ed5546e415390ULL,
26377 + 0xa8b4afbdc5a6aca4ULL,
26378 + 0x1b9ae303c601f3cbULL,
26379 + 0x56ed3e2f9e224471ULL,
26380 + 0xe5c372919d851b1eULL,
26381 + 0xa26908783662e42aULL,
26382 + 0x114744c635c5bb45ULL,
26383 + 0x2d3dfdab61ad1a42ULL,
26384 + 0x9e13b115620a452dULL,
26385 + 0xd9b9cbfcc9edba19ULL,
26386 + 0x6a978742ca4ae576ULL,
26387 + 0xa14cb926613cf817ULL,
26388 + 0x1262f598629ba778ULL,
26389 + 0x55c88f71c97c584cULL,
26390 + 0xe6e6c3cfcadb0723ULL,
26391 + 0xda9c7aa29eb3a624ULL,
26392 + 0x69b2361c9d14f94bULL,
26393 + 0x2e184cf536f3067fULL,
26394 + 0x9d36004b35545910ULL,
26395 + 0x2b769f17cf112238ULL,
26396 + 0x9858d3a9ccb67d57ULL,
26397 + 0xdff2a94067518263ULL,
26398 + 0x6cdce5fe64f6dd0cULL,
26399 + 0x50a65c93309e7c0bULL,
26400 + 0xe388102d33392364ULL,
26401 + 0xa4226ac498dedc50ULL,
26402 + 0x170c267a9b79833fULL,
26403 + 0xdcd7181e300f9e5eULL,
26404 + 0x6ff954a033a8c131ULL,
26405 + 0x28532e49984f3e05ULL,
26406 + 0x9b7d62f79be8616aULL,
26407 + 0xa707db9acf80c06dULL,
26408 + 0x14299724cc279f02ULL,
26409 + 0x5383edcd67c06036ULL,
26410 + 0xe0ada17364673f59ULL
26411 + }
26412 +};
26413 +
26414 +
26415 +/**
26416 + \brief Initializes the crc seed
26417 + */
26418 +static __inline__ uint64_t crc64_init(void)
26419 +{
26420 + return CRC64_ECMA_182.initial;
26421 +}
26422 +
26423 +/**
26424 + \brief Computes 64 bit the crc
26425 + \param[in] data Pointer to the Data in the frame
26426 + \param[in] len Length of the Data
26427 + \param[in] crc seed
26428 + \return calculated crc
26429 + */
26430 +static __inline__ uint64_t crc64_compute(void const *data,
26431 + uint32_t len,
26432 + uint64_t seed)
26433 +{
26434 + uint32_t i;
26435 + uint64_t crc = seed;
26436 + uint8_t *bdata = (uint8_t *) data;
26437 +
26438 + for (i = 0; i < len; i++)
26439 + crc =
26440 + CRC64_ECMA_182.
26441 + table[(crc ^ *bdata++) & CRC64_BYTE_MASK] ^ (crc >> 8);
26442 +
26443 + return crc;
26444 +}
26445 +
26446 +
26447 +#endif /* __CRC64_H */
26448 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
26449 new file mode 100644
26450 index 00000000..17c933b4
26451 --- /dev/null
26452 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
26453 @@ -0,0 +1,7582 @@
26454 +/*
26455 + * Copyright 2008-2012 Freescale Semiconductor Inc.
26456 + *
26457 + * Redistribution and use in source and binary forms, with or without
26458 + * modification, are permitted provided that the following conditions are met:
26459 + * * Redistributions of source code must retain the above copyright
26460 + * notice, this list of conditions and the following disclaimer.
26461 + * * Redistributions in binary form must reproduce the above copyright
26462 + * notice, this list of conditions and the following disclaimer in the
26463 + * documentation and/or other materials provided with the distribution.
26464 + * * Neither the name of Freescale Semiconductor nor the
26465 + * names of its contributors may be used to endorse or promote products
26466 + * derived from this software without specific prior written permission.
26467 + *
26468 + *
26469 + * ALTERNATIVELY, this software may be distributed under the terms of the
26470 + * GNU General Public License ("GPL") as published by the Free Software
26471 + * Foundation, either version 2 of that License or (at your option) any
26472 + * later version.
26473 + *
26474 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26475 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26476 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26477 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26478 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26479 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26480 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26481 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26482 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26483 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26484 + */
26485 +
26486 +
26487 +/******************************************************************************
26488 + @File fm_cc.c
26489 +
26490 + @Description FM Coarse Classifier implementation
26491 + *//***************************************************************************/
26492 +#include <linux/math64.h>
26493 +#include "std_ext.h"
26494 +#include "error_ext.h"
26495 +#include "string_ext.h"
26496 +#include "debug_ext.h"
26497 +#include "fm_pcd_ext.h"
26498 +#include "fm_muram_ext.h"
26499 +
26500 +#include "fm_common.h"
26501 +#include "fm_pcd.h"
26502 +#include "fm_hc.h"
26503 +#include "fm_cc.h"
26504 +#include "crc64.h"
26505 +
26506 +/****************************************/
26507 +/* static functions */
26508 +/****************************************/
26509 +
26510 +
26511 +static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree)
26512 +{
26513 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26514 +
26515 + ASSERT_COND(h_FmPcdCcTree);
26516 +
26517 + if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock))
26518 + return E_OK;
26519 +
26520 + return ERROR_CODE(E_BUSY);
26521 +}
26522 +
26523 +static void CcRootReleaseLock(t_Handle h_FmPcdCcTree)
26524 +{
26525 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26526 +
26527 + ASSERT_COND(h_FmPcdCcTree);
26528 +
26529 + FmPcdLockUnlock(p_FmPcdCcTree->p_Lock);
26530 +}
26531 +
26532 +static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add)
26533 +{
26534 + uint32_t intFlags;
26535 +
26536 + ASSERT_COND(p_CcNode);
26537 +
26538 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26539 +
26540 + if (add)
26541 + p_CcNode->owners++;
26542 + else
26543 + {
26544 + ASSERT_COND(p_CcNode->owners);
26545 + p_CcNode->owners--;
26546 + }
26547 +
26548 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26549 +}
26550 +
26551 +static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List)
26552 +{
26553 + t_FmPcdStatsObj *p_StatsObj = NULL;
26554 + t_List *p_Next;
26555 +
26556 + if (!LIST_IsEmpty(p_List))
26557 + {
26558 + p_Next = LIST_FIRST(p_List);
26559 + p_StatsObj = LIST_OBJECT(p_Next, t_FmPcdStatsObj, node);
26560 + ASSERT_COND(p_StatsObj);
26561 + LIST_DelAndInit(p_Next);
26562 + }
26563 +
26564 + return p_StatsObj;
26565 +}
26566 +
26567 +static __inline__ void EnqueueStatsObj(t_List *p_List,
26568 + t_FmPcdStatsObj *p_StatsObj)
26569 +{
26570 + LIST_AddToTail(&p_StatsObj->node, p_List);
26571 +}
26572 +
26573 +static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram)
26574 +{
26575 + t_FmPcdStatsObj *p_StatsObj;
26576 +
26577 + while (!LIST_IsEmpty(p_List))
26578 + {
26579 + p_StatsObj = DequeueStatsObj(p_List);
26580 + ASSERT_COND(p_StatsObj);
26581 +
26582 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26583 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26584 +
26585 + XX_Free(p_StatsObj);
26586 + }
26587 +}
26588 +
26589 +static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode)
26590 +{
26591 + t_FmPcdStatsObj* p_StatsObj;
26592 + t_Handle h_FmMuram;
26593 +
26594 + ASSERT_COND(p_CcNode);
26595 +
26596 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26597 + upon node initialization */
26598 + if (p_CcNode->maxNumOfKeys)
26599 + {
26600 + p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst);
26601 +
26602 + /* Clean statistics counters & ADs */
26603 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26604 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26605 + }
26606 + else
26607 + {
26608 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26609 + ASSERT_COND(h_FmMuram);
26610 +
26611 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
26612 + if (!p_StatsObj)
26613 + {
26614 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object"));
26615 + return NULL;
26616 + }
26617 +
26618 + p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem(
26619 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26620 + if (!p_StatsObj->h_StatsAd)
26621 + {
26622 + XX_Free(p_StatsObj);
26623 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs"));
26624 + return NULL;
26625 + }
26626 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26627 +
26628 + p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
26629 + h_FmMuram, p_CcNode->countersArraySize,
26630 + FM_PCD_CC_AD_TABLE_ALIGN);
26631 + if (!p_StatsObj->h_StatsCounters)
26632 + {
26633 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26634 + XX_Free(p_StatsObj);
26635 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters"));
26636 + return NULL;
26637 + }
26638 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26639 + }
26640 +
26641 + return p_StatsObj;
26642 +}
26643 +
26644 +static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj)
26645 +{
26646 + t_Handle h_FmMuram;
26647 +
26648 + ASSERT_COND(p_CcNode);
26649 + ASSERT_COND(p_StatsObj);
26650 +
26651 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26652 + upon node initialization and now will be enqueued back to the list */
26653 + if (p_CcNode->maxNumOfKeys)
26654 + {
26655 + /* Clean statistics counters */
26656 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26657 +
26658 + /* Clean statistics ADs */
26659 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26660 +
26661 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
26662 + }
26663 + else
26664 + {
26665 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26666 + ASSERT_COND(h_FmMuram);
26667 +
26668 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26669 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26670 +
26671 + XX_Free(p_StatsObj);
26672 + }
26673 +}
26674 +
26675 +static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd,
26676 + uint32_t statsCountersAddr)
26677 +{
26678 + uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK);
26679 +
26680 + WRITE_UINT32(p_StatsAd->statsTableAddr, tmp);
26681 +}
26682 +
26683 +
26684 +static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26685 + t_Handle h_Ad, uint64_t physicalMuramBase)
26686 +{
26687 + t_AdOfTypeStats *p_StatsAd;
26688 + uint32_t statsCountersAddr, nextActionAddr, tmp;
26689 +#if (DPAA_VERSION >= 11)
26690 + uint32_t frameLengthRangesAddr;
26691 +#endif /* (DPAA_VERSION >= 11) */
26692 +
26693 + p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd;
26694 +
26695 + tmp = FM_PCD_AD_STATS_TYPE;
26696 +
26697 +#if (DPAA_VERSION >= 11)
26698 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26699 + {
26700 + frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys(
26701 + p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase));
26702 + tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK);
26703 + }
26704 +#endif /* (DPAA_VERSION >= 11) */
26705 + WRITE_UINT32(p_StatsAd->profileTableAddr, tmp);
26706 +
26707 + nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase));
26708 + tmp = 0;
26709 + tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT)
26710 + & FM_PCD_AD_STATS_NEXT_ACTION_MASK);
26711 + tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE);
26712 +
26713 +#if (DPAA_VERSION >= 11)
26714 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26715 + tmp |= FM_PCD_AD_STATS_FLR_EN;
26716 +#endif /* (DPAA_VERSION >= 11) */
26717 +
26718 + WRITE_UINT32(p_StatsAd->nextActionIndx, tmp);
26719 +
26720 + statsCountersAddr = (uint32_t)((XX_VirtToPhys(
26721 + p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase));
26722 + SetStatsCounters(p_StatsAd, statsCountersAddr);
26723 +}
26724 +
26725 +static void FillAdOfTypeContLookup(t_Handle h_Ad,
26726 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26727 + t_Handle h_FmPcd, t_Handle p_CcNode,
26728 + t_Handle h_Manip, t_Handle h_FrmReplic)
26729 +{
26730 + t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode;
26731 + t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad;
26732 + t_Handle h_TmpAd;
26733 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
26734 + uint32_t tmpReg32;
26735 + t_Handle p_AdNewPtr = NULL;
26736 +
26737 + UNUSED(h_Manip);
26738 + UNUSED(h_FrmReplic);
26739 +
26740 + /* there are 3 cases handled in this routine of building a "Continue lookup" type AD.
26741 + * Case 1: No Manip. The action descriptor is built within the match table.
26742 + * p_AdResult = p_AdNewPtr;
26743 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
26744 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
26745 + * initialized and returned here.
26746 + * p_AdResult (within the match table) will be initialized after
26747 + * this routine returns and point to the existing AD.
26748 + * Case 3: Manip exists. The action descriptor is built within the match table.
26749 + * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr.
26750 + */
26751 +
26752 + /* As default, the "new" ptr is the current one. i.e. the content of the result
26753 + * AD will be written into the match table itself (case (1))*/
26754 + p_AdNewPtr = p_AdContLookup;
26755 +
26756 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
26757 + if (p_FmPcdCcStatsParams)
26758 + {
26759 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
26760 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
26761 +
26762 + /* Swapping addresses between statistics Ad and the current lookup AD */
26763 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
26764 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
26765 + h_Ad = h_TmpAd;
26766 +
26767 + p_AdNewPtr = h_Ad;
26768 + p_AdContLookup = h_Ad;
26769 +
26770 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
26771 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
26772 + }
26773 +
26774 +#if DPAA_VERSION >= 11
26775 + if (h_Manip && h_FrmReplic)
26776 + FmPcdManipUpdateAdContLookupForCc(
26777 + h_Manip,
26778 + h_Ad,
26779 + &p_AdNewPtr,
26780 + (uint32_t)((XX_VirtToPhys(
26781 + FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic))
26782 + - p_FmPcd->physicalMuramBase)));
26783 + else
26784 + if (h_FrmReplic)
26785 + FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr);
26786 + else
26787 +#endif /* (DPAA_VERSION >= 11) */
26788 + if (h_Manip)
26789 + FmPcdManipUpdateAdContLookupForCc(
26790 + h_Manip,
26791 + h_Ad,
26792 + &p_AdNewPtr,
26793 +
26794 +#ifdef FM_CAPWAP_SUPPORT
26795 + /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/
26796 + (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase))
26797 +#else /* not FM_CAPWAP_SUPPORT */
26798 + (uint32_t)((XX_VirtToPhys(p_Node->h_Ad)
26799 + - p_FmPcd->physicalMuramBase))
26800 +#endif /* not FM_CAPWAP_SUPPORT */
26801 + );
26802 +
26803 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
26804 + if (p_AdNewPtr)
26805 + {
26806 + /* cases (1) & (2) */
26807 + tmpReg32 = 0;
26808 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
26809 + tmpReg32 |=
26810 + p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) :
26811 + 0;
26812 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable)
26813 + - p_FmPcd->physicalMuramBase);
26814 + WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
26815 +
26816 + tmpReg32 = 0;
26817 + tmpReg32 |= p_Node->numOfKeys << 24;
26818 + tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
26819 + tmpReg32 |=
26820 + p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys(
26821 + p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) :
26822 + 0;
26823 + WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
26824 +
26825 + tmpReg32 = 0;
26826 + tmpReg32 |= p_Node->prsArrayOffset << 24;
26827 + tmpReg32 |= p_Node->offset << 16;
26828 + tmpReg32 |= p_Node->parseCode;
26829 + WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
26830 +
26831 + MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask,
26832 + CC_GLBL_MASK_SIZE);
26833 + }
26834 +}
26835 +
26836 +static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode)
26837 +{
26838 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
26839 + uint32_t intFlags;
26840 +
26841 + ASSERT_COND(p_CcNode);
26842 +
26843 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26844 +
26845 + if (!p_CcNode->h_Ad)
26846 + {
26847 + if (p_CcNode->maxNumOfKeys)
26848 + p_CcNode->h_Ad = p_CcNode->h_TmpAd;
26849 + else
26850 + p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem(
26851 + ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram,
26852 + FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26853 +
26854 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26855 +
26856 + if (!p_CcNode->h_Ad)
26857 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
26858 + ("MURAM allocation for CC action descriptor"));
26859 +
26860 + MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26861 +
26862 + FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd,
26863 + p_CcNode, NULL, NULL);
26864 + }
26865 + else
26866 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26867 +
26868 + return E_OK;
26869 +}
26870 +
26871 +static t_Error SetRequiredAction1(
26872 + t_Handle h_FmPcd, uint32_t requiredAction,
26873 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
26874 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
26875 +{
26876 + t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
26877 + uint32_t tmpReg32;
26878 + t_Error err;
26879 + t_FmPcdCcNode *p_CcNode;
26880 + int i = 0;
26881 + uint16_t tmp = 0;
26882 + uint16_t profileId;
26883 + uint8_t relativeSchemeId, physicalSchemeId;
26884 + t_CcNodeInformation ccNodeInfo;
26885 +
26886 + for (i = 0; i < numOfEntries; i++)
26887 + {
26888 + if (i == 0)
26889 + h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
26890 + else
26891 + h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
26892 +
26893 + switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine)
26894 + {
26895 + case (e_FM_PCD_CC):
26896 + if (requiredAction)
26897 + {
26898 + p_CcNode =
26899 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
26900 + ASSERT_COND(p_CcNode);
26901 + if (p_CcNode->shadowAction == requiredAction)
26902 + break;
26903 + if ((requiredAction & UPDATE_CC_WITH_TREE)
26904 + && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE))
26905 + {
26906 +
26907 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26908 + ccNodeInfo.h_CcNode = h_Tree;
26909 + EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst,
26910 + &ccNodeInfo, NULL);
26911 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26912 + UPDATE_CC_WITH_TREE;
26913 + }
26914 + if ((requiredAction & UPDATE_CC_SHADOW_CLEAR)
26915 + && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR))
26916 + {
26917 +
26918 + p_CcNode->shadowAction = 0;
26919 + }
26920 +
26921 + if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE)
26922 + && !(p_CcNode->shadowAction
26923 + & UPDATE_CC_WITH_DELETE_TREE))
26924 + {
26925 + DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst,
26926 + h_Tree, NULL);
26927 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26928 + UPDATE_CC_WITH_DELETE_TREE;
26929 + }
26930 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
26931 + != e_FM_PCD_INVALID)
26932 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
26933 + else
26934 + tmp = p_CcNode->numOfKeys;
26935 + err = SetRequiredAction1(h_FmPcd, requiredAction,
26936 + p_CcNode->keyAndNextEngineParams,
26937 + p_CcNode->h_AdTable, tmp, h_Tree);
26938 + if (err != E_OK)
26939 + return err;
26940 + if (requiredAction != UPDATE_CC_SHADOW_CLEAR)
26941 + p_CcNode->shadowAction |= requiredAction;
26942 + }
26943 + break;
26944 +
26945 + case (e_FM_PCD_KG):
26946 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26947 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26948 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26949 + {
26950 + physicalSchemeId =
26951 + FmPcdKgGetSchemeId(
26952 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme);
26953 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(
26954 + h_FmPcd, physicalSchemeId);
26955 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
26956 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
26957 + if (!FmPcdKgIsSchemeValidSw(
26958 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme))
26959 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
26960 + ("Invalid direct scheme."));
26961 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
26962 + RETURN_ERROR(
26963 + MAJOR, E_INVALID_STATE,
26964 + ("For this action scheme has to be direct."));
26965 + err =
26966 + FmPcdKgCcGetSetParams(
26967 + h_FmPcd,
26968 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme,
26969 + requiredAction, 0);
26970 + if (err != E_OK)
26971 + RETURN_ERROR(MAJOR, err, NO_MSG);
26972 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26973 + requiredAction;
26974 + }
26975 + break;
26976 +
26977 + case (e_FM_PCD_PLCR):
26978 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26979 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26980 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26981 + {
26982 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
26983 + RETURN_ERROR(
26984 + MAJOR,
26985 + E_NOT_SUPPORTED,
26986 + ("In this initialization only overrideFqid can be initialized"));
26987 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
26988 + RETURN_ERROR(
26989 + MAJOR,
26990 + E_NOT_SUPPORTED,
26991 + ("In this initialization only overrideFqid can be initialized"));
26992 + err =
26993 + FmPcdPlcrGetAbsoluteIdByProfileParams(
26994 + h_FmPcd,
26995 + e_FM_PCD_PLCR_SHARED,
26996 + NULL,
26997 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId,
26998 + &profileId);
26999 + if (err != E_OK)
27000 + RETURN_ERROR(MAJOR, err, NO_MSG);
27001 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId,
27002 + requiredAction);
27003 + if (err != E_OK)
27004 + RETURN_ERROR(MAJOR, err, NO_MSG);
27005 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
27006 + requiredAction;
27007 + }
27008 + break;
27009 +
27010 + case (e_FM_PCD_DONE):
27011 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
27012 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
27013 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
27014 + {
27015 + tmpReg32 = GET_UINT32(p_AdTmp->nia);
27016 + if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
27017 + != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
27018 + RETURN_ERROR(
27019 + MAJOR,
27020 + E_INVALID_STATE,
27021 + ("Next engine was previously assigned not as PCD_DONE"));
27022 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
27023 + WRITE_UINT32(p_AdTmp->nia, tmpReg32);
27024 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
27025 + requiredAction;
27026 + }
27027 + break;
27028 +
27029 + default:
27030 + break;
27031 + }
27032 + }
27033 +
27034 + return E_OK;
27035 +}
27036 +
27037 +static t_Error SetRequiredAction(
27038 + t_Handle h_FmPcd, uint32_t requiredAction,
27039 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
27040 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
27041 +{
27042 + t_Error err = SetRequiredAction1(h_FmPcd, requiredAction,
27043 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
27044 + numOfEntries, h_Tree);
27045 + if (err != E_OK)
27046 + return err;
27047 + return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR,
27048 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
27049 + numOfEntries, h_Tree);
27050 +}
27051 +
27052 +static t_Error ReleaseModifiedDataStructure(
27053 + t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst,
27054 + t_List *h_FmPcdNewPointersLst,
27055 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27056 + bool useShadowStructs)
27057 +{
27058 + t_List *p_Pos;
27059 + t_Error err = E_OK;
27060 + t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation;
27061 + t_Handle h_Muram;
27062 + t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode;
27063 + t_List *p_UpdateLst;
27064 + uint32_t intFlags;
27065 +
27066 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
27067 + SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode,
27068 + E_INVALID_HANDLE);
27069 + SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE);
27070 + SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE);
27071 +
27072 + /* We don't update subtree of the new node with new tree because it was done in the previous stage */
27073 + if (p_AdditionalParams->h_NodeForAdd)
27074 + {
27075 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd;
27076 +
27077 + if (!p_AdditionalParams->tree)
27078 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
27079 + else
27080 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
27081 +
27082 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27083 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
27084 + p_FmPcdCcNextNode->h_Spinlock);
27085 +
27086 + if (p_CcNodeInformation)
27087 + p_CcNodeInformation->index++;
27088 + else
27089 + {
27090 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
27091 + ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode;
27092 + ccNodeInfo.index = 1;
27093 + EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo,
27094 + p_FmPcdCcNextNode->h_Spinlock);
27095 + }
27096 + if (p_AdditionalParams->h_ManipForAdd)
27097 + {
27098 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27099 + FmPcdManipGetNodeLstPointedOnThisManip(
27100 + p_AdditionalParams->h_ManipForAdd),
27101 + p_AdditionalParams->h_CurrentNode,
27102 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd));
27103 +
27104 + if (p_CcNodeInformation)
27105 + p_CcNodeInformation->index++;
27106 + else
27107 + {
27108 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
27109 + ccNodeInfo.h_CcNode =
27110 + (t_Handle)p_AdditionalParams->h_CurrentNode;
27111 + ccNodeInfo.index = 1;
27112 + EnqueueNodeInfoToRelevantLst(
27113 + FmPcdManipGetNodeLstPointedOnThisManip(
27114 + p_AdditionalParams->h_ManipForAdd),
27115 + &ccNodeInfo,
27116 + FmPcdManipGetSpinlock(
27117 + p_AdditionalParams->h_ManipForAdd));
27118 + }
27119 + }
27120 + }
27121 +
27122 + if (p_AdditionalParams->h_NodeForRmv)
27123 + {
27124 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv;
27125 +
27126 + if (!p_AdditionalParams->tree)
27127 + {
27128 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
27129 + p_FmPcdCcWorkingOnNode =
27130 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
27131 +
27132 + for (p_Pos = LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst);
27133 + p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos =
27134 + LIST_NEXT(p_Pos))
27135 + {
27136 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
27137 +
27138 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
27139 +
27140 + err =
27141 + SetRequiredAction(
27142 + h_FmPcd,
27143 + UPDATE_CC_WITH_DELETE_TREE,
27144 + &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
27145 + PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
27146 + 1, p_CcNodeInformation->h_CcNode);
27147 + }
27148 + }
27149 + else
27150 + {
27151 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
27152 +
27153 + err =
27154 + SetRequiredAction(
27155 + h_FmPcd,
27156 + UPDATE_CC_WITH_DELETE_TREE,
27157 + &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
27158 + UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
27159 + 1, p_AdditionalParams->h_CurrentNode);
27160 + }
27161 + if (err)
27162 + return err;
27163 +
27164 + /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage
27165 + Update ccPrevNodesLst or ccTreeIdLst of the removed node
27166 + Update of the node owner */
27167 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27168 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
27169 + p_FmPcdCcNextNode->h_Spinlock);
27170 +
27171 + ASSERT_COND(p_CcNodeInformation);
27172 + ASSERT_COND(p_CcNodeInformation->index);
27173 +
27174 + p_CcNodeInformation->index--;
27175 +
27176 + if (p_CcNodeInformation->index == 0)
27177 + DequeueNodeInfoFromRelevantLst(p_UpdateLst,
27178 + p_AdditionalParams->h_CurrentNode,
27179 + p_FmPcdCcNextNode->h_Spinlock);
27180 +
27181 + UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
27182 +
27183 + if (p_AdditionalParams->h_ManipForRmv)
27184 + {
27185 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27186 + FmPcdManipGetNodeLstPointedOnThisManip(
27187 + p_AdditionalParams->h_ManipForRmv),
27188 + p_AdditionalParams->h_CurrentNode,
27189 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv));
27190 +
27191 + ASSERT_COND(p_CcNodeInformation);
27192 + ASSERT_COND(p_CcNodeInformation->index);
27193 +
27194 + p_CcNodeInformation->index--;
27195 +
27196 + if (p_CcNodeInformation->index == 0)
27197 + DequeueNodeInfoFromRelevantLst(
27198 + FmPcdManipGetNodeLstPointedOnThisManip(
27199 + p_AdditionalParams->h_ManipForRmv),
27200 + p_AdditionalParams->h_CurrentNode,
27201 + FmPcdManipGetSpinlock(
27202 + p_AdditionalParams->h_ManipForRmv));
27203 + }
27204 + }
27205 +
27206 + if (p_AdditionalParams->h_ManipForRmv)
27207 + FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE);
27208 +
27209 + if (p_AdditionalParams->p_StatsObjForRmv)
27210 + PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode),
27211 + p_AdditionalParams->p_StatsObjForRmv);
27212 +
27213 +#if (DPAA_VERSION >= 11)
27214 + if (p_AdditionalParams->h_FrmReplicForRmv)
27215 + FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv,
27216 + FALSE/* remove */);
27217 +#endif /* (DPAA_VERSION >= 11) */
27218 +
27219 + if (!useShadowStructs)
27220 + {
27221 + h_Muram = FmPcdGetMuramHandle(h_FmPcd);
27222 + ASSERT_COND(h_Muram);
27223 +
27224 + if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow)
27225 + || (!p_AdditionalParams->tree
27226 + && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys))
27227 + {
27228 + /* We release new AD which was allocated and updated for copy from to actual AD */
27229 + for (p_Pos = LIST_FIRST(h_FmPcdNewPointersLst);
27230 + p_Pos != (h_FmPcdNewPointersLst); p_Pos = LIST_NEXT(p_Pos))
27231 + {
27232 +
27233 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
27234 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
27235 + FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
27236 + }
27237 + }
27238 +
27239 + /* Free Old data structure if it has to be freed - new data structure was allocated*/
27240 + if (p_AdditionalParams->p_AdTableOld)
27241 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld);
27242 +
27243 + if (p_AdditionalParams->p_KeysMatchTableOld)
27244 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld);
27245 + }
27246 +
27247 + /* Update current modified node with changed fields if it's required*/
27248 + if (!p_AdditionalParams->tree)
27249 + {
27250 + if (p_AdditionalParams->p_AdTableNew)
27251 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable =
27252 + p_AdditionalParams->p_AdTableNew;
27253 +
27254 + if (p_AdditionalParams->p_KeysMatchTableNew)
27255 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable =
27256 + p_AdditionalParams->p_KeysMatchTableNew;
27257 +
27258 + /* Locking node's spinlock before updating 'keys and next engine' structure,
27259 + as it maybe used to retrieve keys statistics */
27260 + intFlags =
27261 + XX_LockIntrSpinlock(
27262 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock);
27263 +
27264 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys =
27265 + p_AdditionalParams->numOfKeys;
27266 +
27267 + memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
27268 + &p_AdditionalParams->keyAndNextEngineParams,
27269 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS));
27270 +
27271 + XX_UnlockIntrSpinlock(
27272 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock,
27273 + intFlags);
27274 + }
27275 + else
27276 + {
27277 + uint8_t numEntries =
27278 + ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries;
27279 + ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS);
27280 + memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
27281 + &p_AdditionalParams->keyAndNextEngineParams,
27282 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries);
27283 + }
27284 +
27285 + ReleaseLst(h_FmPcdOldPointersLst);
27286 + ReleaseLst(h_FmPcdNewPointersLst);
27287 +
27288 + XX_Free(p_AdditionalParams);
27289 +
27290 + return E_OK;
27291 +}
27292 +
27293 +static t_Handle BuildNewAd(
27294 + t_Handle h_Ad,
27295 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
27296 + t_FmPcdCcNode *p_CcNode,
27297 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
27298 +{
27299 + t_FmPcdCcNode *p_FmPcdCcNodeTmp;
27300 + t_Handle h_OrigAd = NULL;
27301 +
27302 + p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
27303 + if (!p_FmPcdCcNodeTmp)
27304 + {
27305 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
27306 + return NULL;
27307 + }
27308 + memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
27309 +
27310 + p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
27311 + p_FmPcdCcNodeTmp->h_KeysMatchTable =
27312 + p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
27313 + p_FmPcdCcNodeTmp->h_AdTable =
27314 + p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
27315 +
27316 + p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask;
27317 + p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode;
27318 + p_FmPcdCcNodeTmp->offset = p_CcNode->offset;
27319 + p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset;
27320 + p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow;
27321 + p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction;
27322 + p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction;
27323 + p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize;
27324 + p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask;
27325 +
27326 + if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
27327 + {
27328 + if (p_FmPcdCcNextEngineParams->h_Manip)
27329 + {
27330 + h_OrigAd = p_CcNode->h_Ad;
27331 + if (AllocAndFillAdForContLookupManip(
27332 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
27333 + != E_OK)
27334 + {
27335 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
27336 + XX_Free(p_FmPcdCcNodeTmp);
27337 + return NULL;
27338 + }
27339 + }
27340 + FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27341 + h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL);
27342 + }
27343 +
27344 +#if (DPAA_VERSION >= 11)
27345 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR)
27346 + && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic))
27347 + {
27348 + FillAdOfTypeContLookup(
27349 + h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27350 + p_FmPcdCcNextEngineParams->h_Manip,
27351 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
27352 + }
27353 +#endif /* (DPAA_VERSION >= 11) */
27354 +
27355 + XX_Free(p_FmPcdCcNodeTmp);
27356 +
27357 + return E_OK;
27358 +}
27359 +
27360 +static t_Error DynamicChangeHc(
27361 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27362 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27363 + bool useShadowStructs)
27364 +{
27365 + t_List *p_PosOld, *p_PosNew;
27366 + uint32_t oldAdAddrOffset, newAdAddrOffset;
27367 + uint16_t i = 0;
27368 + t_Error err = E_OK;
27369 + uint8_t numOfModifiedPtr;
27370 +
27371 + ASSERT_COND(h_FmPcd);
27372 + ASSERT_COND(h_OldPointersLst);
27373 + ASSERT_COND(h_NewPointersLst);
27374 +
27375 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27376 +
27377 + if (numOfModifiedPtr)
27378 + {
27379 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27380 + p_PosOld = LIST_FIRST(h_OldPointersLst);
27381 +
27382 + /* Retrieve address of new AD */
27383 + newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27384 + p_PosNew);
27385 + if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27386 + {
27387 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27388 + h_NewPointersLst,
27389 + p_AdditionalParams, useShadowStructs);
27390 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address"));
27391 + }
27392 +
27393 + for (i = 0; i < numOfModifiedPtr; i++)
27394 + {
27395 + /* Retrieve address of current AD */
27396 + oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27397 + p_PosOld);
27398 + if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27399 + {
27400 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27401 + h_NewPointersLst,
27402 + p_AdditionalParams,
27403 + useShadowStructs);
27404 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address"));
27405 + }
27406 +
27407 + /* Invoke host command to copy from new AD to old AD */
27408 + err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc,
27409 + oldAdAddrOffset, newAdAddrOffset);
27410 + if (err)
27411 + {
27412 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27413 + h_NewPointersLst,
27414 + p_AdditionalParams,
27415 + useShadowStructs);
27416 + RETURN_ERROR(
27417 + MAJOR,
27418 + err,
27419 + ("For part of nodes changes are done - situation is danger"));
27420 + }
27421 +
27422 + p_PosOld = LIST_NEXT(p_PosOld);
27423 + }
27424 + }
27425 + return E_OK;
27426 +}
27427 +
27428 +static t_Error DoDynamicChange(
27429 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27430 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27431 + bool useShadowStructs)
27432 +{
27433 + t_FmPcdCcNode *p_CcNode =
27434 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
27435 + t_List *p_PosNew;
27436 + t_CcNodeInformation *p_CcNodeInfo;
27437 + t_FmPcdCcNextEngineParams nextEngineParams;
27438 + t_Handle h_Ad;
27439 + uint32_t keySize;
27440 + t_Error err = E_OK;
27441 + uint8_t numOfModifiedPtr;
27442 +
27443 + ASSERT_COND(h_FmPcd);
27444 +
27445 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
27446 +
27447 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27448 +
27449 + if (numOfModifiedPtr)
27450 + {
27451 +
27452 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27453 +
27454 + /* Invoke host-command to copy from the new Ad to existing Ads */
27455 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27456 + p_AdditionalParams, useShadowStructs);
27457 + if (err)
27458 + RETURN_ERROR(MAJOR, err, NO_MSG);
27459 +
27460 + if (useShadowStructs)
27461 + {
27462 + /* When the host-command above has ended, the old structures are 'free'and we can update
27463 + them by copying from the new shadow structures. */
27464 + if (p_CcNode->lclMask)
27465 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
27466 + else
27467 + keySize = p_CcNode->ccKeySizeAccExtraction;
27468 +
27469 + MemCpy8(p_AdditionalParams->p_KeysMatchTableOld,
27470 + p_AdditionalParams->p_KeysMatchTableNew,
27471 + p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t));
27472 +
27473 + MemCpy8(
27474 + p_AdditionalParams->p_AdTableOld,
27475 + p_AdditionalParams->p_AdTableNew,
27476 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
27477 + * FM_PCD_CC_AD_ENTRY_SIZE));
27478 +
27479 + /* Retrieve the address of the allocated Ad */
27480 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew);
27481 + h_Ad = p_CcNodeInfo->h_CcNode;
27482 +
27483 + /* Build a new Ad that holds the old (now updated) structures */
27484 + p_AdditionalParams->p_KeysMatchTableNew =
27485 + p_AdditionalParams->p_KeysMatchTableOld;
27486 + p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld;
27487 +
27488 + nextEngineParams.nextEngine = e_FM_PCD_CC;
27489 + nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode;
27490 +
27491 + BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams);
27492 +
27493 + /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */
27494 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27495 + p_AdditionalParams, useShadowStructs);
27496 + if (err)
27497 + RETURN_ERROR(MAJOR, err, NO_MSG);
27498 + }
27499 + }
27500 +
27501 + err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27502 + h_NewPointersLst,
27503 + p_AdditionalParams, useShadowStructs);
27504 + if (err)
27505 + RETURN_ERROR(MAJOR, err, NO_MSG);
27506 +
27507 + return E_OK;
27508 +}
27509 +
27510 +#ifdef FM_CAPWAP_SUPPORT
27511 +static bool IsCapwapApplSpecific(t_Handle h_Node)
27512 +{
27513 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node;
27514 + bool isManipForCapwapApplSpecificBuild = FALSE;
27515 + int i = 0;
27516 +
27517 + ASSERT_COND(h_Node);
27518 + /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/
27519 + for (i = 0; i < p_CcNode->numOfKeys; i++)
27520 + {
27521 + if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip &&
27522 + FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip))
27523 + {
27524 + isManipForCapwapApplSpecificBuild = TRUE;
27525 + break;
27526 + }
27527 + }
27528 + return isManipForCapwapApplSpecificBuild;
27529 +
27530 +}
27531 +#endif /* FM_CAPWAP_SUPPORT */
27532 +
27533 +static t_Error CcUpdateParam(
27534 + t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort,
27535 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams,
27536 + uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level,
27537 + t_Handle h_FmTree, bool modify)
27538 +{
27539 + t_FmPcdCcNode *p_CcNode;
27540 + t_Error err;
27541 + uint16_t tmp = 0;
27542 + int i = 0;
27543 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
27544 +
27545 + level++;
27546 +
27547 + if (p_CcTree->h_IpReassemblyManip)
27548 + {
27549 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27550 + p_CcTree->h_IpReassemblyManip, NULL, validate,
27551 + level, h_FmTree, modify);
27552 + if (err)
27553 + RETURN_ERROR(MAJOR, err, NO_MSG);
27554 + }
27555 +
27556 + if (p_CcTree->h_CapwapReassemblyManip)
27557 + {
27558 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27559 + p_CcTree->h_CapwapReassemblyManip, NULL, validate,
27560 + level, h_FmTree, modify);
27561 + if (err)
27562 + RETURN_ERROR(MAJOR, err, NO_MSG);
27563 + }
27564 +
27565 + if (numOfEntries)
27566 + {
27567 + for (i = 0; i < numOfEntries; i++)
27568 + {
27569 + if (i == 0)
27570 + h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
27571 + else
27572 + h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
27573 +
27574 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine
27575 + == e_FM_PCD_CC)
27576 + {
27577 + p_CcNode =
27578 + p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
27579 + ASSERT_COND(p_CcNode);
27580 +
27581 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27582 + {
27583 + err =
27584 + FmPcdManipUpdate(
27585 + h_FmPcd,
27586 + NULL,
27587 + h_FmPort,
27588 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27589 + h_Ad, validate, level, h_FmTree, modify);
27590 + if (err)
27591 + RETURN_ERROR(MAJOR, err, NO_MSG);
27592 + }
27593 +
27594 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
27595 + != e_FM_PCD_INVALID)
27596 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
27597 + else
27598 + tmp = p_CcNode->numOfKeys;
27599 +
27600 + err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
27601 + p_CcNode->keyAndNextEngineParams, tmp,
27602 + p_CcNode->h_AdTable, validate, level,
27603 + h_FmTree, modify);
27604 + if (err)
27605 + RETURN_ERROR(MAJOR, err, NO_MSG);
27606 + }
27607 + else
27608 + {
27609 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27610 + {
27611 + err =
27612 + FmPcdManipUpdate(
27613 + h_FmPcd,
27614 + NULL,
27615 + h_FmPort,
27616 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27617 + h_Ad, validate, level, h_FmTree, modify);
27618 + if (err)
27619 + RETURN_ERROR(MAJOR, err, NO_MSG);
27620 + }
27621 + }
27622 + }
27623 + }
27624 +
27625 + return E_OK;
27626 +}
27627 +
27628 +static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
27629 +{
27630 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
27631 + {
27632 + case (e_FM_PCD_ACTION_EXACT_MATCH):
27633 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27634 + {
27635 + case (e_FM_PCD_EXTRACT_FROM_KEY):
27636 + return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
27637 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27638 + return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
27639 + default:
27640 + return CC_PRIVATE_INFO_NONE;
27641 + }
27642 +
27643 + case (e_FM_PCD_ACTION_INDEXED_LOOKUP):
27644 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27645 + {
27646 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27647 + return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
27648 + case (e_FM_PCD_EXTRACT_FROM_FLOW_ID):
27649 + return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
27650 + default:
27651 + return CC_PRIVATE_INFO_NONE;
27652 + }
27653 +
27654 + default:
27655 + break;
27656 + }
27657 +
27658 + return CC_PRIVATE_INFO_NONE;
27659 +}
27660 +
27661 +static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(
27662 + t_List *p_List)
27663 +{
27664 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27665 +
27666 + if (!LIST_IsEmpty(p_List))
27667 + {
27668 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
27669 + LIST_DelAndInit(&p_CcNodeInfo->node);
27670 + }
27671 +
27672 + return p_CcNodeInfo;
27673 +}
27674 +
27675 +void ReleaseLst(t_List *p_List)
27676 +{
27677 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27678 +
27679 + if (!LIST_IsEmpty(p_List))
27680 + {
27681 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27682 + while (p_CcNodeInfo)
27683 + {
27684 + XX_Free(p_CcNodeInfo);
27685 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27686 + }
27687 + }
27688 +
27689 + LIST_Del(p_List);
27690 +}
27691 +
27692 +static void DeleteNode(t_FmPcdCcNode *p_CcNode)
27693 +{
27694 + uint32_t i;
27695 +
27696 + if (!p_CcNode)
27697 + return;
27698 +
27699 + if (p_CcNode->p_GlblMask)
27700 + {
27701 + XX_Free(p_CcNode->p_GlblMask);
27702 + p_CcNode->p_GlblMask = NULL;
27703 + }
27704 +
27705 + if (p_CcNode->h_KeysMatchTable)
27706 + {
27707 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27708 + p_CcNode->h_KeysMatchTable);
27709 + p_CcNode->h_KeysMatchTable = NULL;
27710 + }
27711 +
27712 + if (p_CcNode->h_AdTable)
27713 + {
27714 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27715 + p_CcNode->h_AdTable);
27716 + p_CcNode->h_AdTable = NULL;
27717 + }
27718 +
27719 + if (p_CcNode->h_Ad)
27720 + {
27721 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27722 + p_CcNode->h_Ad);
27723 + p_CcNode->h_Ad = NULL;
27724 + p_CcNode->h_TmpAd = NULL;
27725 + }
27726 +
27727 + if (p_CcNode->h_StatsFLRs)
27728 + {
27729 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27730 + p_CcNode->h_StatsFLRs);
27731 + p_CcNode->h_StatsFLRs = NULL;
27732 + }
27733 +
27734 + if (p_CcNode->h_Spinlock)
27735 + {
27736 + XX_FreeSpinlock(p_CcNode->h_Spinlock);
27737 + p_CcNode->h_Spinlock = NULL;
27738 + }
27739 +
27740 + /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */
27741 + if (p_CcNode->isHashBucket
27742 + && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE))
27743 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters =
27744 + p_CcNode->h_PrivMissStatsCounters;
27745 +
27746 + /* Releasing all currently used statistics objects, including 'miss' entry */
27747 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
27748 + if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj)
27749 + PutStatsObj(p_CcNode,
27750 + p_CcNode->keyAndNextEngineParams[i].p_StatsObj);
27751 +
27752 + if (!LIST_IsEmpty(&p_CcNode->availableStatsLst))
27753 + {
27754 + t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
27755 + ASSERT_COND(h_FmMuram);
27756 +
27757 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
27758 + }
27759 +
27760 + LIST_Del(&p_CcNode->availableStatsLst);
27761 +
27762 + ReleaseLst(&p_CcNode->availableStatsLst);
27763 + ReleaseLst(&p_CcNode->ccPrevNodesLst);
27764 + ReleaseLst(&p_CcNode->ccTreeIdLst);
27765 + ReleaseLst(&p_CcNode->ccTreesLst);
27766 +
27767 + XX_Free(p_CcNode);
27768 +}
27769 +
27770 +static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
27771 +{
27772 + if (p_FmPcdTree)
27773 + {
27774 + if (p_FmPcdTree->ccTreeBaseAddr)
27775 + {
27776 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd),
27777 + UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
27778 + p_FmPcdTree->ccTreeBaseAddr = 0;
27779 + }
27780 +
27781 + ReleaseLst(&p_FmPcdTree->fmPortsLst);
27782 +
27783 + XX_Free(p_FmPcdTree);
27784 + }
27785 +}
27786 +
27787 +static void GetCcExtractKeySize(uint8_t parseCodeRealSize,
27788 + uint8_t *parseCodeCcSize)
27789 +{
27790 + if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
27791 + *parseCodeCcSize = 1;
27792 + else
27793 + if (parseCodeRealSize == 2)
27794 + *parseCodeCcSize = 2;
27795 + else
27796 + if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4))
27797 + *parseCodeCcSize = 4;
27798 + else
27799 + if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8))
27800 + *parseCodeCcSize = 8;
27801 + else
27802 + if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16))
27803 + *parseCodeCcSize = 16;
27804 + else
27805 + if ((parseCodeRealSize > 16)
27806 + && (parseCodeRealSize <= 24))
27807 + *parseCodeCcSize = 24;
27808 + else
27809 + if ((parseCodeRealSize > 24)
27810 + && (parseCodeRealSize <= 32))
27811 + *parseCodeCcSize = 32;
27812 + else
27813 + if ((parseCodeRealSize > 32)
27814 + && (parseCodeRealSize <= 40))
27815 + *parseCodeCcSize = 40;
27816 + else
27817 + if ((parseCodeRealSize > 40)
27818 + && (parseCodeRealSize <= 48))
27819 + *parseCodeCcSize = 48;
27820 + else
27821 + if ((parseCodeRealSize > 48)
27822 + && (parseCodeRealSize <= 56))
27823 + *parseCodeCcSize = 56;
27824 + else
27825 + *parseCodeCcSize = 0;
27826 +}
27827 +
27828 +static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field,
27829 + uint8_t *parseCodeRealSize)
27830 +{
27831 + switch (hdr)
27832 + {
27833 + case (HEADER_TYPE_ETH):
27834 + switch (field.eth)
27835 + {
27836 + case (NET_HEADER_FIELD_ETH_DA):
27837 + *parseCodeRealSize = 6;
27838 + break;
27839 +
27840 + case (NET_HEADER_FIELD_ETH_SA):
27841 + *parseCodeRealSize = 6;
27842 + break;
27843 +
27844 + case (NET_HEADER_FIELD_ETH_TYPE):
27845 + *parseCodeRealSize = 2;
27846 + break;
27847 +
27848 + default:
27849 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27850 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27851 + break;
27852 + }
27853 + break;
27854 +
27855 + case (HEADER_TYPE_PPPoE):
27856 + switch (field.pppoe)
27857 + {
27858 + case (NET_HEADER_FIELD_PPPoE_PID):
27859 + *parseCodeRealSize = 2;
27860 + break;
27861 +
27862 + default:
27863 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27864 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27865 + break;
27866 + }
27867 + break;
27868 +
27869 + case (HEADER_TYPE_VLAN):
27870 + switch (field.vlan)
27871 + {
27872 + case (NET_HEADER_FIELD_VLAN_TCI):
27873 + *parseCodeRealSize = 2;
27874 + break;
27875 +
27876 + default:
27877 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
27878 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27879 + break;
27880 + }
27881 + break;
27882 +
27883 + case (HEADER_TYPE_MPLS):
27884 + switch (field.mpls)
27885 + {
27886 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
27887 + *parseCodeRealSize = 4;
27888 + break;
27889 +
27890 + default:
27891 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
27892 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27893 + break;
27894 + }
27895 + break;
27896 +
27897 + case (HEADER_TYPE_IPv4):
27898 + switch (field.ipv4)
27899 + {
27900 + case (NET_HEADER_FIELD_IPv4_DST_IP):
27901 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
27902 + *parseCodeRealSize = 4;
27903 + break;
27904 +
27905 + case (NET_HEADER_FIELD_IPv4_TOS):
27906 + case (NET_HEADER_FIELD_IPv4_PROTO):
27907 + *parseCodeRealSize = 1;
27908 + break;
27909 +
27910 + case (NET_HEADER_FIELD_IPv4_DST_IP
27911 + | NET_HEADER_FIELD_IPv4_SRC_IP):
27912 + *parseCodeRealSize = 8;
27913 + break;
27914 +
27915 + case (NET_HEADER_FIELD_IPv4_TTL):
27916 + *parseCodeRealSize = 1;
27917 + break;
27918 +
27919 + default:
27920 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
27921 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27922 + break;
27923 + }
27924 + break;
27925 +
27926 + case (HEADER_TYPE_IPv6):
27927 + switch (field.ipv6)
27928 + {
27929 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
27930 + | NET_HEADER_FIELD_IPv6_TC):
27931 + *parseCodeRealSize = 4;
27932 + break;
27933 +
27934 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
27935 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
27936 + *parseCodeRealSize = 1;
27937 + break;
27938 +
27939 + case (NET_HEADER_FIELD_IPv6_DST_IP):
27940 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
27941 + *parseCodeRealSize = 16;
27942 + break;
27943 +
27944 + default:
27945 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27946 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27947 + break;
27948 + }
27949 + break;
27950 +
27951 + case (HEADER_TYPE_IP):
27952 + switch (field.ip)
27953 + {
27954 + case (NET_HEADER_FIELD_IP_DSCP):
27955 + case (NET_HEADER_FIELD_IP_PROTO):
27956 + *parseCodeRealSize = 1;
27957 + break;
27958 +
27959 + default:
27960 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27961 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27962 + break;
27963 + }
27964 + break;
27965 +
27966 + case (HEADER_TYPE_GRE):
27967 + switch (field.gre)
27968 + {
27969 + case (NET_HEADER_FIELD_GRE_TYPE):
27970 + *parseCodeRealSize = 2;
27971 + break;
27972 +
27973 + default:
27974 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
27975 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27976 + break;
27977 + }
27978 + break;
27979 +
27980 + case (HEADER_TYPE_MINENCAP):
27981 + switch (field.minencap)
27982 + {
27983 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
27984 + *parseCodeRealSize = 1;
27985 + break;
27986 +
27987 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
27988 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
27989 + *parseCodeRealSize = 4;
27990 + break;
27991 +
27992 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
27993 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
27994 + *parseCodeRealSize = 8;
27995 + break;
27996 +
27997 + default:
27998 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
27999 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
28000 + break;
28001 + }
28002 + break;
28003 +
28004 + case (HEADER_TYPE_TCP):
28005 + switch (field.tcp)
28006 + {
28007 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
28008 + case (NET_HEADER_FIELD_TCP_PORT_DST):
28009 + *parseCodeRealSize = 2;
28010 + break;
28011 +
28012 + case (NET_HEADER_FIELD_TCP_PORT_SRC
28013 + | NET_HEADER_FIELD_TCP_PORT_DST):
28014 + *parseCodeRealSize = 4;
28015 + break;
28016 +
28017 + default:
28018 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
28019 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
28020 + break;
28021 + }
28022 + break;
28023 +
28024 + case (HEADER_TYPE_UDP):
28025 + switch (field.udp)
28026 + {
28027 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
28028 + case (NET_HEADER_FIELD_UDP_PORT_DST):
28029 + *parseCodeRealSize = 2;
28030 + break;
28031 +
28032 + case (NET_HEADER_FIELD_UDP_PORT_SRC
28033 + | NET_HEADER_FIELD_UDP_PORT_DST):
28034 + *parseCodeRealSize = 4;
28035 + break;
28036 +
28037 + default:
28038 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
28039 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
28040 + break;
28041 + }
28042 + break;
28043 +
28044 + default:
28045 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
28046 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
28047 + break;
28048 + }
28049 +}
28050 +
28051 +t_Error ValidateNextEngineParams(
28052 + t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
28053 + e_FmPcdCcStatsMode statsMode)
28054 +{
28055 + uint16_t absoluteProfileId;
28056 + t_Error err = E_OK;
28057 + uint8_t relativeSchemeId;
28058 +
28059 + if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE)
28060 + && (p_FmPcdCcNextEngineParams->statisticsEn))
28061 + RETURN_ERROR(
28062 + MAJOR,
28063 + E_CONFLICT,
28064 + ("Statistics are requested for a key, but statistics mode was set"
28065 + "to 'NONE' upon initialization"));
28066 +
28067 + switch (p_FmPcdCcNextEngineParams->nextEngine)
28068 + {
28069 + case (e_FM_PCD_INVALID):
28070 + err = E_NOT_SUPPORTED;
28071 + break;
28072 +
28073 + case (e_FM_PCD_DONE):
28074 + if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action
28075 + == e_FM_PCD_ENQ_FRAME)
28076 + && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
28077 + {
28078 + if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
28079 + RETURN_ERROR(
28080 + MAJOR,
28081 + E_CONFLICT,
28082 + ("When overrideFqid is set, newFqid must not be zero"));
28083 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid
28084 + & ~0x00FFFFFF)
28085 + RETURN_ERROR(
28086 + MAJOR, E_INVALID_VALUE,
28087 + ("fqidForCtrlFlow must be between 1 and 2^24-1"));
28088 + }
28089 + break;
28090 +
28091 + case (e_FM_PCD_KG):
28092 + relativeSchemeId =
28093 + FmPcdKgGetRelativeSchemeId(
28094 + h_FmPcd,
28095 + FmPcdKgGetSchemeId(
28096 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme));
28097 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
28098 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
28099 + if (!FmPcdKgIsSchemeValidSw(
28100 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme))
28101 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28102 + ("not valid schemeIndex in KG next engine param"));
28103 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
28104 + RETURN_ERROR(
28105 + MAJOR,
28106 + E_INVALID_STATE,
28107 + ("CC Node may point only to a scheme that is always direct."));
28108 + break;
28109 +
28110 + case (e_FM_PCD_PLCR):
28111 + if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
28112 + {
28113 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
28114 + if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
28115 + {
28116 + err =
28117 + FmPcdPlcrGetAbsoluteIdByProfileParams(
28118 + h_FmPcd,
28119 + e_FM_PCD_PLCR_SHARED,
28120 + NULL,
28121 + p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId,
28122 + &absoluteProfileId);
28123 + if (err)
28124 + RETURN_ERROR(MAJOR, err,
28125 + ("Shared profile offset is out of range"));
28126 + if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
28127 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28128 + ("Invalid profile"));
28129 + }
28130 + }
28131 + break;
28132 +
28133 + case (e_FM_PCD_HASH):
28134 + p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC;
28135 + case (e_FM_PCD_CC):
28136 + if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
28137 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
28138 + ("handler to next Node is NULL"));
28139 + break;
28140 +
28141 +#if (DPAA_VERSION >= 11)
28142 + case (e_FM_PCD_FR):
28143 + if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
28144 + err = E_NOT_SUPPORTED;
28145 + break;
28146 +#endif /* (DPAA_VERSION >= 11) */
28147 +
28148 + default:
28149 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28150 + ("Next engine is not correct"));
28151 + }
28152 +
28153 +
28154 + return err;
28155 +}
28156 +
28157 +static uint8_t GetGenParseCode(e_FmPcdExtractFrom src,
28158 + uint32_t offset, bool glblMask,
28159 + uint8_t *parseArrayOffset, bool fromIc,
28160 + ccPrivateInfo_t icCode)
28161 +{
28162 + if (!fromIc)
28163 + {
28164 + switch (src)
28165 + {
28166 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
28167 + if (glblMask)
28168 + return CC_PC_GENERIC_WITH_MASK;
28169 + else
28170 + return CC_PC_GENERIC_WITHOUT_MASK;
28171 +
28172 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
28173 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
28174 + if (offset)
28175 + return CC_PR_OFFSET;
28176 + else
28177 + return CC_PR_WITHOUT_OFFSET;
28178 +
28179 + default:
28180 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
28181 + return CC_PC_ILLEGAL;
28182 + }
28183 + }
28184 + else
28185 + {
28186 + switch (icCode)
28187 + {
28188 + case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
28189 + *parseArrayOffset = 0x50;
28190 + return CC_PC_GENERIC_IC_GMASK;
28191 +
28192 + case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
28193 + *parseArrayOffset = 0x48;
28194 + return CC_PC_GENERIC_IC_GMASK;
28195 +
28196 + case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
28197 + *parseArrayOffset = 0x48;
28198 + return CC_PC_GENERIC_IC_HASH_INDEXED;
28199 +
28200 + case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
28201 + *parseArrayOffset = 0x16;
28202 + return CC_PC_GENERIC_IC_HASH_INDEXED;
28203 +
28204 + default:
28205 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
28206 + break;
28207 + }
28208 + }
28209 +
28210 + return CC_PC_ILLEGAL;
28211 +}
28212 +
28213 +static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index,
28214 + t_FmPcdFields field)
28215 +{
28216 + switch (hdr)
28217 + {
28218 + case (HEADER_TYPE_NONE):
28219 + ASSERT_COND(FALSE);
28220 + return CC_PC_ILLEGAL;
28221 +
28222 + case (HEADER_TYPE_ETH):
28223 + switch (field.eth)
28224 + {
28225 + case (NET_HEADER_FIELD_ETH_DA):
28226 + return CC_PC_FF_MACDST;
28227 + case (NET_HEADER_FIELD_ETH_SA):
28228 + return CC_PC_FF_MACSRC;
28229 + case (NET_HEADER_FIELD_ETH_TYPE):
28230 + return CC_PC_FF_ETYPE;
28231 + default:
28232 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28233 + return CC_PC_ILLEGAL;
28234 + }
28235 +
28236 + case (HEADER_TYPE_VLAN):
28237 + switch (field.vlan)
28238 + {
28239 + case (NET_HEADER_FIELD_VLAN_TCI):
28240 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28241 + || (index == e_FM_PCD_HDR_INDEX_1))
28242 + return CC_PC_FF_TCI1;
28243 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28244 + return CC_PC_FF_TCI2;
28245 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28246 + return CC_PC_ILLEGAL;
28247 + default:
28248 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28249 + return CC_PC_ILLEGAL;
28250 + }
28251 +
28252 + case (HEADER_TYPE_MPLS):
28253 + switch (field.mpls)
28254 + {
28255 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
28256 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28257 + || (index == e_FM_PCD_HDR_INDEX_1))
28258 + return CC_PC_FF_MPLS1;
28259 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28260 + return CC_PC_FF_MPLS_LAST;
28261 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
28262 + return CC_PC_ILLEGAL;
28263 + default:
28264 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28265 + return CC_PC_ILLEGAL;
28266 + }
28267 +
28268 + case (HEADER_TYPE_IPv4):
28269 + switch (field.ipv4)
28270 + {
28271 + case (NET_HEADER_FIELD_IPv4_DST_IP):
28272 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28273 + || (index == e_FM_PCD_HDR_INDEX_1))
28274 + return CC_PC_FF_IPV4DST1;
28275 + if (index == e_FM_PCD_HDR_INDEX_2)
28276 + return CC_PC_FF_IPV4DST2;
28277 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28278 + return CC_PC_ILLEGAL;
28279 + case (NET_HEADER_FIELD_IPv4_TOS):
28280 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28281 + || (index == e_FM_PCD_HDR_INDEX_1))
28282 + return CC_PC_FF_IPV4IPTOS_TC1;
28283 + if (index == e_FM_PCD_HDR_INDEX_2)
28284 + return CC_PC_FF_IPV4IPTOS_TC2;
28285 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28286 + return CC_PC_ILLEGAL;
28287 + case (NET_HEADER_FIELD_IPv4_PROTO):
28288 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28289 + || (index == e_FM_PCD_HDR_INDEX_1))
28290 + return CC_PC_FF_IPV4PTYPE1;
28291 + if (index == e_FM_PCD_HDR_INDEX_2)
28292 + return CC_PC_FF_IPV4PTYPE2;
28293 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28294 + return CC_PC_ILLEGAL;
28295 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
28296 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28297 + || (index == e_FM_PCD_HDR_INDEX_1))
28298 + return CC_PC_FF_IPV4SRC1;
28299 + if (index == e_FM_PCD_HDR_INDEX_2)
28300 + return CC_PC_FF_IPV4SRC2;
28301 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28302 + return CC_PC_ILLEGAL;
28303 + case (NET_HEADER_FIELD_IPv4_SRC_IP
28304 + | NET_HEADER_FIELD_IPv4_DST_IP):
28305 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28306 + || (index == e_FM_PCD_HDR_INDEX_1))
28307 + return CC_PC_FF_IPV4SRC1_IPV4DST1;
28308 + if (index == e_FM_PCD_HDR_INDEX_2)
28309 + return CC_PC_FF_IPV4SRC2_IPV4DST2;
28310 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28311 + return CC_PC_ILLEGAL;
28312 + case (NET_HEADER_FIELD_IPv4_TTL):
28313 + return CC_PC_FF_IPV4TTL;
28314 + default:
28315 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28316 + return CC_PC_ILLEGAL;
28317 + }
28318 +
28319 + case (HEADER_TYPE_IPv6):
28320 + switch (field.ipv6)
28321 + {
28322 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
28323 + | NET_HEADER_FIELD_IPv6_TC):
28324 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28325 + || (index == e_FM_PCD_HDR_INDEX_1))
28326 + return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
28327 + if (index == e_FM_PCD_HDR_INDEX_2)
28328 + return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
28329 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28330 + return CC_PC_ILLEGAL;
28331 +
28332 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
28333 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28334 + || (index == e_FM_PCD_HDR_INDEX_1))
28335 + return CC_PC_FF_IPV6PTYPE1;
28336 + if (index == e_FM_PCD_HDR_INDEX_2)
28337 + return CC_PC_FF_IPV6PTYPE2;
28338 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28339 + return CC_PC_FF_IPPID;
28340 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28341 + return CC_PC_ILLEGAL;
28342 +
28343 + case (NET_HEADER_FIELD_IPv6_DST_IP):
28344 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28345 + || (index == e_FM_PCD_HDR_INDEX_1))
28346 + return CC_PC_FF_IPV6DST1;
28347 + if (index == e_FM_PCD_HDR_INDEX_2)
28348 + return CC_PC_FF_IPV6DST2;
28349 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28350 + return CC_PC_ILLEGAL;
28351 +
28352 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
28353 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28354 + || (index == e_FM_PCD_HDR_INDEX_1))
28355 + return CC_PC_FF_IPV6SRC1;
28356 + if (index == e_FM_PCD_HDR_INDEX_2)
28357 + return CC_PC_FF_IPV6SRC2;
28358 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28359 + return CC_PC_ILLEGAL;
28360 +
28361 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
28362 + return CC_PC_FF_IPV6HOP_LIMIT;
28363 +
28364 + default:
28365 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28366 + return CC_PC_ILLEGAL;
28367 + }
28368 +
28369 + case (HEADER_TYPE_IP):
28370 + switch (field.ip)
28371 + {
28372 + case (NET_HEADER_FIELD_IP_DSCP):
28373 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28374 + || (index == e_FM_PCD_HDR_INDEX_1))
28375 + return CC_PC_FF_IPDSCP;
28376 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28377 + return CC_PC_ILLEGAL;
28378 +
28379 + case (NET_HEADER_FIELD_IP_PROTO):
28380 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28381 + return CC_PC_FF_IPPID;
28382 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28383 + return CC_PC_ILLEGAL;
28384 +
28385 + default:
28386 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28387 + return CC_PC_ILLEGAL;
28388 + }
28389 +
28390 + case (HEADER_TYPE_GRE):
28391 + switch (field.gre)
28392 + {
28393 + case (NET_HEADER_FIELD_GRE_TYPE):
28394 + return CC_PC_FF_GREPTYPE;
28395 +
28396 + default:
28397 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28398 + return CC_PC_ILLEGAL;
28399 + }
28400 +
28401 + case (HEADER_TYPE_MINENCAP):
28402 + switch (field.minencap)
28403 + {
28404 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
28405 + return CC_PC_FF_MINENCAP_PTYPE;
28406 +
28407 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
28408 + return CC_PC_FF_MINENCAP_IPDST;
28409 +
28410 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
28411 + return CC_PC_FF_MINENCAP_IPSRC;
28412 +
28413 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
28414 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
28415 + return CC_PC_FF_MINENCAP_IPSRC_IPDST;
28416 +
28417 + default:
28418 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28419 + return CC_PC_ILLEGAL;
28420 + }
28421 +
28422 + case (HEADER_TYPE_TCP):
28423 + switch (field.tcp)
28424 + {
28425 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
28426 + return CC_PC_FF_L4PSRC;
28427 +
28428 + case (NET_HEADER_FIELD_TCP_PORT_DST):
28429 + return CC_PC_FF_L4PDST;
28430 +
28431 + case (NET_HEADER_FIELD_TCP_PORT_DST
28432 + | NET_HEADER_FIELD_TCP_PORT_SRC):
28433 + return CC_PC_FF_L4PSRC_L4PDST;
28434 +
28435 + default:
28436 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28437 + return CC_PC_ILLEGAL;
28438 + }
28439 +
28440 + case (HEADER_TYPE_PPPoE):
28441 + switch (field.pppoe)
28442 + {
28443 + case (NET_HEADER_FIELD_PPPoE_PID):
28444 + return CC_PC_FF_PPPPID;
28445 +
28446 + default:
28447 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28448 + return CC_PC_ILLEGAL;
28449 + }
28450 +
28451 + case (HEADER_TYPE_UDP):
28452 + switch (field.udp)
28453 + {
28454 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
28455 + return CC_PC_FF_L4PSRC;
28456 +
28457 + case (NET_HEADER_FIELD_UDP_PORT_DST):
28458 + return CC_PC_FF_L4PDST;
28459 +
28460 + case (NET_HEADER_FIELD_UDP_PORT_DST
28461 + | NET_HEADER_FIELD_UDP_PORT_SRC):
28462 + return CC_PC_FF_L4PSRC_L4PDST;
28463 +
28464 + default:
28465 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28466 + return CC_PC_ILLEGAL;
28467 + }
28468 +
28469 + default:
28470 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28471 + return CC_PC_ILLEGAL;
28472 + }
28473 +}
28474 +
28475 +static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex,
28476 + uint32_t offset, bool glblMask,
28477 + uint8_t *parseArrayOffset)
28478 +{
28479 + bool offsetRelevant = FALSE;
28480 +
28481 + if (offset)
28482 + offsetRelevant = TRUE;
28483 +
28484 + switch (hdr)
28485 + {
28486 + case (HEADER_TYPE_NONE):
28487 + ASSERT_COND(FALSE);
28488 + return CC_PC_ILLEGAL;
28489 +
28490 + case (HEADER_TYPE_ETH):
28491 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
28492 + break;
28493 +
28494 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
28495 + if (offset || glblMask)
28496 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
28497 + else
28498 + return CC_PC_PR_SHIM1;
28499 + break;
28500 +
28501 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
28502 + if (offset || glblMask)
28503 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
28504 + else
28505 + return CC_PC_PR_SHIM2;
28506 + break;
28507 +
28508 + case (HEADER_TYPE_LLC_SNAP):
28509 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
28510 + break;
28511 +
28512 + case (HEADER_TYPE_PPPoE):
28513 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
28514 + break;
28515 +
28516 + case (HEADER_TYPE_MPLS):
28517 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28518 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28519 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
28520 + else
28521 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28522 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
28523 + else
28524 + {
28525 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
28526 + return CC_PC_ILLEGAL;
28527 + }
28528 + break;
28529 +
28530 + case (HEADER_TYPE_IPv4):
28531 + case (HEADER_TYPE_IPv6):
28532 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28533 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28534 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
28535 + else
28536 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
28537 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
28538 + else
28539 + {
28540 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
28541 + return CC_PC_ILLEGAL;
28542 + }
28543 + break;
28544 +
28545 + case (HEADER_TYPE_MINENCAP):
28546 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
28547 + break;
28548 +
28549 + case (HEADER_TYPE_GRE):
28550 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
28551 + break;
28552 +
28553 + case (HEADER_TYPE_TCP):
28554 + case (HEADER_TYPE_UDP):
28555 + case (HEADER_TYPE_IPSEC_AH):
28556 + case (HEADER_TYPE_IPSEC_ESP):
28557 + case (HEADER_TYPE_DCCP):
28558 + case (HEADER_TYPE_SCTP):
28559 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
28560 + break;
28561 +
28562 + default:
28563 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
28564 + return CC_PC_ILLEGAL;
28565 + }
28566 +
28567 + if (offsetRelevant)
28568 + return CC_PR_OFFSET;
28569 + else
28570 + return CC_PR_WITHOUT_OFFSET;
28571 +}
28572 +
28573 +static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field,
28574 + uint32_t offset, uint8_t *parseArrayOffset,
28575 + e_FmPcdHdrIndex hdrIndex)
28576 +{
28577 + bool offsetRelevant = FALSE;
28578 +
28579 + if (offset)
28580 + offsetRelevant = TRUE;
28581 +
28582 + switch (hdr)
28583 + {
28584 + case (HEADER_TYPE_NONE):
28585 + ASSERT_COND(FALSE);
28586 + break;
28587 + case (HEADER_TYPE_ETH):
28588 + switch (field.eth)
28589 + {
28590 + case (NET_HEADER_FIELD_ETH_TYPE):
28591 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
28592 + break;
28593 +
28594 + default:
28595 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28596 + return CC_PC_ILLEGAL;
28597 + }
28598 + break;
28599 +
28600 + case (HEADER_TYPE_VLAN):
28601 + switch (field.vlan)
28602 + {
28603 + case (NET_HEADER_FIELD_VLAN_TCI):
28604 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28605 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28606 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
28607 + else
28608 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28609 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
28610 + break;
28611 +
28612 + default:
28613 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28614 + return CC_PC_ILLEGAL;
28615 + }
28616 + break;
28617 +
28618 + default:
28619 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
28620 + return CC_PC_ILLEGAL;
28621 + }
28622 +
28623 + if (offsetRelevant)
28624 + return CC_PR_OFFSET;
28625 + else
28626 + return CC_PR_WITHOUT_OFFSET;
28627 +}
28628 +
28629 +static void FillAdOfTypeResult(t_Handle h_Ad,
28630 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
28631 + t_FmPcd *p_FmPcd,
28632 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
28633 +{
28634 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad;
28635 + t_Handle h_TmpAd;
28636 + uint32_t tmp = 0, tmpNia = 0;
28637 + uint16_t profileId;
28638 + t_Handle p_AdNewPtr = NULL;
28639 + t_Error err = E_OK;
28640 +
28641 + /* There are 3 cases handled in this routine of building a "result" type AD.
28642 + * Case 1: No Manip. The action descriptor is built within the match table.
28643 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
28644 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
28645 + * initialized and returned here.
28646 + * p_AdResult (within the match table) will be initialized after
28647 + * this routine returns and point to the existing AD.
28648 + * Case 3: Manip exists. The action descriptor is built within the match table.
28649 + * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr.
28650 + *
28651 + * If statistics were enabled and the statistics mode of this node requires
28652 + * a statistics Ad, it will be placed after the result Ad and before the
28653 + * manip Ad, if manip Ad exists here.
28654 + */
28655 +
28656 + /* As default, the "new" ptr is the current one. i.e. the content of the result
28657 + * AD will be written into the match table itself (case (1))*/
28658 + p_AdNewPtr = p_AdResult;
28659 +
28660 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
28661 + if (p_FmPcdCcStatsParams)
28662 + {
28663 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
28664 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
28665 +
28666 + /* Swapping addresses between statistics Ad and the current lookup AD addresses */
28667 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
28668 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
28669 + h_Ad = h_TmpAd;
28670 +
28671 + p_AdNewPtr = h_Ad;
28672 + p_AdResult = h_Ad;
28673 +
28674 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
28675 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
28676 + }
28677 +
28678 + /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */
28679 + if (p_CcNextEngineParams->h_Manip)
28680 + FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip,
28681 + p_CcNextEngineParams, h_Ad, &p_AdNewPtr);
28682 +
28683 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
28684 + if (p_AdNewPtr)
28685 + {
28686 + /* case (1) and (2) */
28687 + switch (p_CcNextEngineParams->nextEngine)
28688 + {
28689 + case (e_FM_PCD_DONE):
28690 + if (p_CcNextEngineParams->params.enqueueParams.action
28691 + == e_FM_PCD_ENQ_FRAME)
28692 + {
28693 + if (p_CcNextEngineParams->params.enqueueParams.overrideFqid)
28694 + {
28695 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28696 + tmp |=
28697 + p_CcNextEngineParams->params.enqueueParams.newFqid;
28698 +#if (DPAA_VERSION >= 11)
28699 + tmp |=
28700 + (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId
28701 + & FM_PCD_AD_RESULT_VSP_MASK)
28702 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28703 +#endif /* (DPAA_VERSION >= 11) */
28704 + }
28705 + else
28706 + {
28707 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28708 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28709 + }
28710 + }
28711 +
28712 + if (p_CcNextEngineParams->params.enqueueParams.action
28713 + == e_FM_PCD_DROP_FRAME)
28714 + tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
28715 + else
28716 + tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
28717 + break;
28718 +
28719 + case (e_FM_PCD_KG):
28720 + if (p_CcNextEngineParams->params.kgParams.overrideFqid)
28721 + {
28722 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28723 + tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
28724 +#if (DPAA_VERSION >= 11)
28725 + tmp |=
28726 + (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId
28727 + & FM_PCD_AD_RESULT_VSP_MASK)
28728 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28729 +#endif /* (DPAA_VERSION >= 11) */
28730 + }
28731 + else
28732 + {
28733 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28734 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28735 + }
28736 + tmpNia = NIA_KG_DIRECT;
28737 + tmpNia |= NIA_ENG_KG;
28738 + tmpNia |= NIA_KG_CC_EN;
28739 + tmpNia |= FmPcdKgGetSchemeId(
28740 + p_CcNextEngineParams->params.kgParams.h_DirectScheme);
28741 + break;
28742 +
28743 + case (e_FM_PCD_PLCR):
28744 + if (p_CcNextEngineParams->params.plcrParams.overrideParams)
28745 + {
28746 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28747 +
28748 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
28749 + if (p_CcNextEngineParams->params.plcrParams.sharedProfile)
28750 + {
28751 + tmpNia |= NIA_PLCR_ABSOLUTE;
28752 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(
28753 + (t_Handle)p_FmPcd,
28754 + e_FM_PCD_PLCR_SHARED,
28755 + NULL,
28756 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId,
28757 + &profileId);
28758 +
28759 + if (err != E_OK) {
28760 + REPORT_ERROR(MAJOR, err, NO_MSG);
28761 + return;
28762 + }
28763 +
28764 + }
28765 + else
28766 + profileId =
28767 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28768 +
28769 + tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
28770 +#if (DPAA_VERSION >= 11)
28771 + tmp |=
28772 + (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId
28773 + & FM_PCD_AD_RESULT_VSP_MASK)
28774 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28775 +#endif /* (DPAA_VERSION >= 11) */
28776 + WRITE_UINT32(
28777 + p_AdResult->plcrProfile,
28778 + (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
28779 + }
28780 + else
28781 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28782 +
28783 + tmpNia |=
28784 + NIA_ENG_PLCR
28785 + | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28786 + break;
28787 +
28788 + default:
28789 + return;
28790 + }WRITE_UINT32(p_AdResult->fqid, tmp);
28791 +
28792 + if (p_CcNextEngineParams->h_Manip)
28793 + {
28794 + tmp = GET_UINT32(p_AdResult->plcrProfile);
28795 + tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr)
28796 + - (p_FmPcd->physicalMuramBase)) >> 4;
28797 + WRITE_UINT32(p_AdResult->plcrProfile, tmp);
28798 +
28799 + tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
28800 + tmpNia |= FM_PCD_AD_RESULT_NADEN;
28801 + }
28802 +
28803 +#if (DPAA_VERSION >= 11)
28804 + tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE;
28805 +#endif /* (DPAA_VERSION >= 11) */
28806 + WRITE_UINT32(p_AdResult->nia, tmpNia);
28807 + }
28808 +}
28809 +
28810 +static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams,
28811 + t_Handle h_FmPort, t_Handle h_FmTree,
28812 + bool validate)
28813 +{
28814 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
28815 +
28816 + return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
28817 + p_CcTree->keyAndNextEngineParams,
28818 + p_CcTree->numOfEntries,
28819 + UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0,
28820 + h_FmTree, FALSE);
28821 +}
28822 +
28823 +
28824 +static void ReleaseNewNodeCommonPart(
28825 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28826 +{
28827 + if (p_AdditionalInfo->p_AdTableNew)
28828 + FM_MURAM_FreeMem(
28829 + FmPcdGetMuramHandle(
28830 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28831 + p_AdditionalInfo->p_AdTableNew);
28832 +
28833 + if (p_AdditionalInfo->p_KeysMatchTableNew)
28834 + FM_MURAM_FreeMem(
28835 + FmPcdGetMuramHandle(
28836 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28837 + p_AdditionalInfo->p_KeysMatchTableNew);
28838 +}
28839 +
28840 +static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize,
28841 + uint8_t *p_Mask)
28842 +{
28843 + uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize;
28844 +
28845 + if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4)
28846 + && !p_CcNode->lclMask)
28847 + {
28848 + if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1)
28849 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
28850 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
28851 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
28852 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
28853 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
28854 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
28855 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
28856 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2))
28857 + {
28858 + p_CcNode->glblMaskSize = 0;
28859 + p_CcNode->lclMask = TRUE;
28860 + }
28861 + else
28862 + {
28863 + memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize);
28864 + p_CcNode->glblMaskUpdated = TRUE;
28865 + p_CcNode->glblMaskSize = 4;
28866 + }
28867 + }
28868 + else
28869 + if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask)
28870 + {
28871 + if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0)
28872 + {
28873 + p_CcNode->lclMask = TRUE;
28874 + p_CcNode->glblMaskSize = 0;
28875 + }
28876 + }
28877 + else
28878 + if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4))
28879 + {
28880 + uint32_t tmpMask = 0xffffffff;
28881 + if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0)
28882 + {
28883 + p_CcNode->lclMask = TRUE;
28884 + p_CcNode->glblMaskSize = 0;
28885 + }
28886 + }
28887 + else
28888 + if (p_Mask)
28889 + {
28890 + p_CcNode->lclMask = TRUE;
28891 + p_CcNode->glblMaskSize = 0;
28892 + }
28893 +
28894 + /* In static mode (maxNumOfKeys > 0), local mask is supported
28895 + only is mask support was enabled at initialization */
28896 + if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask)
28897 + {
28898 + p_CcNode->lclMask = FALSE;
28899 + p_CcNode->glblMaskSize = prvGlblMaskSize;
28900 + return ERROR_CODE(E_NOT_SUPPORTED);
28901 + }
28902 +
28903 + return E_OK;
28904 +}
28905 +
28906 +static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree)
28907 +{
28908 + t_FmPcd *p_FmPcd;
28909 + t_Handle h_Ad;
28910 +
28911 + if (isTree)
28912 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28913 + else
28914 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28915 +
28916 + if ((isTree && p_FmPcd->p_CcShadow)
28917 + || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys))
28918 + {
28919 + /* The allocated shadow is divided as follows:
28920 + 0 . . . 16 . . .
28921 + ---------------------------------------------------
28922 + | Shadow | Shadow Keys | Shadow Next |
28923 + | Ad | Match Table | Engine Table |
28924 + | (16 bytes) | (maximal size) | (maximal size) |
28925 + ---------------------------------------------------
28926 + */
28927 + if (!p_FmPcd->p_CcShadow)
28928 + {
28929 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
28930 + return NULL;
28931 + }
28932 +
28933 + h_Ad = p_FmPcd->p_CcShadow;
28934 + }
28935 + else
28936 + {
28937 + h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
28938 + FM_PCD_CC_AD_ENTRY_SIZE,
28939 + FM_PCD_CC_AD_TABLE_ALIGN);
28940 + if (!h_Ad)
28941 + {
28942 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor"));
28943 + return NULL;
28944 + }
28945 + }
28946 +
28947 + return h_Ad;
28948 +}
28949 +
28950 +static t_Error BuildNewNodeCommonPart(
28951 + t_FmPcdCcNode *p_CcNode, int *size,
28952 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28953 +{
28954 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
28955 +
28956 + if (p_CcNode->lclMask)
28957 + *size = 2 * p_CcNode->ccKeySizeAccExtraction;
28958 + else
28959 + *size = p_CcNode->ccKeySizeAccExtraction;
28960 +
28961 + if (p_CcNode->maxNumOfKeys == 0)
28962 + {
28963 + p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(
28964 + FmPcdGetMuramHandle(p_FmPcd),
28965 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
28966 + * FM_PCD_CC_AD_ENTRY_SIZE),
28967 + FM_PCD_CC_AD_TABLE_ALIGN);
28968 + if (!p_AdditionalInfo->p_AdTableNew)
28969 + RETURN_ERROR(
28970 + MAJOR, E_NO_MEMORY,
28971 + ("MURAM allocation for CC node action descriptors table"));
28972 +
28973 + p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem(
28974 + FmPcdGetMuramHandle(p_FmPcd),
28975 + (uint32_t)(*size * sizeof(uint8_t)
28976 + * (p_AdditionalInfo->numOfKeys + 1)),
28977 + FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
28978 + if (!p_AdditionalInfo->p_KeysMatchTableNew)
28979 + {
28980 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
28981 + p_AdditionalInfo->p_AdTableNew);
28982 + p_AdditionalInfo->p_AdTableNew = NULL;
28983 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
28984 + ("MURAM allocation for CC node key match table"));
28985 + }
28986 +
28987 + MemSet8(
28988 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
28989 + 0,
28990 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
28991 + * FM_PCD_CC_AD_ENTRY_SIZE));
28992 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
28993 + *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
28994 + }
28995 + else
28996 + {
28997 + /* The allocated shadow is divided as follows:
28998 + 0 . . . 16 . . .
28999 + ---------------------------------------------------
29000 + | Shadow | Shadow Keys | Shadow Next |
29001 + | Ad | Match Table | Engine Table |
29002 + | (16 bytes) | (maximal size) | (maximal size) |
29003 + ---------------------------------------------------
29004 + */
29005 +
29006 + if (!p_FmPcd->p_CcShadow)
29007 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
29008 +
29009 + p_AdditionalInfo->p_KeysMatchTableNew =
29010 + PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE);
29011 + p_AdditionalInfo->p_AdTableNew =
29012 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize);
29013 +
29014 + MemSet8(
29015 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
29016 + 0,
29017 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
29018 + * FM_PCD_CC_AD_ENTRY_SIZE));
29019 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
29020 + (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys));
29021 + }
29022 +
29023 + p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable;
29024 + p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable;
29025 +
29026 + return E_OK;
29027 +}
29028 +
29029 +static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(
29030 + t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
29031 + t_FmPcdCcKeyParams *p_KeyParams,
29032 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
29033 +{
29034 + t_Error err = E_OK;
29035 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29036 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29037 + int size;
29038 + int i = 0, j = 0;
29039 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
29040 + uint32_t requiredAction = 0;
29041 + bool prvLclMask;
29042 + t_CcNodeInformation *p_CcNodeInformation;
29043 + t_FmPcdCcStatsParams statsParams = { 0 };
29044 + t_List *p_Pos;
29045 + t_FmPcdStatsObj *p_StatsObj;
29046 +
29047 + /* Check that new NIA is legal */
29048 + err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams,
29049 + p_CcNode->statisticsMode);
29050 + if (err)
29051 + RETURN_ERROR(MAJOR, err, NO_MSG);
29052 +
29053 + prvLclMask = p_CcNode->lclMask;
29054 +
29055 + /* Check that new key is not require update of localMask */
29056 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction,
29057 + p_KeyParams->p_Mask);
29058 + if (err)
29059 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29060 +
29061 + /* Update internal data structure with new next engine for the given index */
29062 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
29063 + &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
29064 +
29065 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key,
29066 + p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction);
29067 +
29068 + if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29069 + == e_FM_PCD_CC)
29070 + && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29071 + {
29072 + err =
29073 + AllocAndFillAdForContLookupManip(
29074 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode);
29075 + if (err)
29076 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29077 + }
29078 +
29079 + if (p_KeyParams->p_Mask)
29080 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask,
29081 + p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction);
29082 + else
29083 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
29084 + p_CcNode->userSizeOfExtraction);
29085 +
29086 + /* Update numOfKeys */
29087 + if (add)
29088 + p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1);
29089 + else
29090 + p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys;
29091 +
29092 + /* Allocate new tables in MURAM: keys match table and action descriptors table */
29093 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29094 + if (err)
29095 + RETURN_ERROR(MAJOR, err, NO_MSG);
29096 +
29097 + /* Check that manip is legal and what requiredAction is necessary for this manip */
29098 + if (p_KeyParams->ccNextEngineParams.h_Manip)
29099 + {
29100 + err = FmPcdManipCheckParamsForCcNextEngine(
29101 + &p_KeyParams->ccNextEngineParams, &requiredAction);
29102 + if (err)
29103 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29104 + }
29105 +
29106 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
29107 + requiredAction;
29108 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
29109 + UPDATE_CC_WITH_TREE;
29110 +
29111 + /* Update new Ad and new Key Table according to new requirement */
29112 + i = 0;
29113 + for (j = 0; j < p_AdditionalInfo->numOfKeys; j++)
29114 + {
29115 + p_AdTableNewTmp =
29116 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
29117 +
29118 + if (j == keyIndex)
29119 + {
29120 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
29121 + {
29122 + /* Allocate a statistics object that holds statistics AD and counters.
29123 + - For added key - New statistics AD and counters pointer need to be allocated
29124 + new statistics object. If statistics were enabled, we need to replace the
29125 + existing descriptor with a new descriptor with nullified counters.
29126 + */
29127 + p_StatsObj = GetStatsObj(p_CcNode);
29128 + ASSERT_COND(p_StatsObj);
29129 +
29130 + /* Store allocated statistics object */
29131 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
29132 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29133 + p_StatsObj;
29134 +
29135 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
29136 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
29137 +#if (DPAA_VERSION >= 11)
29138 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
29139 +
29140 +#endif /* (DPAA_VERSION >= 11) */
29141 +
29142 + /* Building action descriptor for the received new key */
29143 + NextStepAd(p_AdTableNewTmp, &statsParams,
29144 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
29145 + }
29146 + else
29147 + {
29148 + /* Building action descriptor for the received new key */
29149 + NextStepAd(p_AdTableNewTmp, NULL,
29150 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
29151 + }
29152 +
29153 + /* Copy the received new key into keys match table */
29154 + p_KeysMatchTableNewTmp =
29155 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t));
29156 +
29157 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key,
29158 + p_CcNode->userSizeOfExtraction);
29159 +
29160 + /* Update mask for the received new key */
29161 + if (p_CcNode->lclMask)
29162 + {
29163 + if (p_KeyParams->p_Mask)
29164 + {
29165 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29166 + p_CcNode->ccKeySizeAccExtraction),
29167 + p_KeyParams->p_Mask,
29168 + p_CcNode->userSizeOfExtraction);
29169 + }
29170 + else
29171 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29172 + {
29173 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29174 + p_CcNode->ccKeySizeAccExtraction),
29175 + 0xff, p_CcNode->userSizeOfExtraction);
29176 + }
29177 + else
29178 + {
29179 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29180 + p_CcNode->ccKeySizeAccExtraction),
29181 + p_CcNode->p_GlblMask,
29182 + p_CcNode->userSizeOfExtraction);
29183 + }
29184 + }
29185 +
29186 + /* If key modification requested, the old entry is omitted and replaced by the new parameters */
29187 + if (!add)
29188 + i++;
29189 + }
29190 + else
29191 + {
29192 + /* Copy existing action descriptors to the newly allocated Ad table */
29193 + p_AdTableOldTmp =
29194 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29195 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp,
29196 + FM_PCD_CC_AD_ENTRY_SIZE);
29197 +
29198 + /* Copy existing keys and their masks to the newly allocated keys match table */
29199 + p_KeysMatchTableNewTmp =
29200 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29201 + p_KeysMatchTableOldTmp =
29202 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t));
29203 +
29204 + if (p_CcNode->lclMask)
29205 + {
29206 + if (prvLclMask)
29207 + {
29208 + MemCpy8(
29209 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29210 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29211 + p_CcNode->ccKeySizeAccExtraction);
29212 + }
29213 + else
29214 + {
29215 + p_KeysMatchTableOldTmp =
29216 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29217 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29218 +
29219 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29220 + {
29221 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29222 + p_CcNode->ccKeySizeAccExtraction),
29223 + 0xff, p_CcNode->userSizeOfExtraction);
29224 + }
29225 + else
29226 + {
29227 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29228 + p_CcNode->ccKeySizeAccExtraction),
29229 + p_CcNode->p_GlblMask,
29230 + p_CcNode->userSizeOfExtraction);
29231 + }
29232 + }
29233 + }
29234 +
29235 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29236 + p_CcNode->ccKeySizeAccExtraction);
29237 +
29238 + i++;
29239 + }
29240 + }
29241 +
29242 + /* Miss action descriptor */
29243 + p_AdTableNewTmp =
29244 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29245 + p_AdTableOldTmp =
29246 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE);
29247 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29248 +
29249 + if (!LIST_IsEmpty(&p_CcNode->ccTreesLst))
29250 + {
29251 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
29252 + {
29253 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29254 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29255 + /* Update the manipulation which has to be updated from parameters of the port */
29256 + /* It's has to be updated with restrictions defined in the function */
29257 + err =
29258 + SetRequiredAction(
29259 + p_CcNode->h_FmPcd,
29260 + p_CcNode->shadowAction
29261 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29262 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29263 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
29264 + 1, p_CcNodeInformation->h_CcNode);
29265 + if (err)
29266 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29267 +
29268 + err =
29269 + CcUpdateParam(
29270 + p_CcNode->h_FmPcd,
29271 + NULL,
29272 + NULL,
29273 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29274 + 1,
29275 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
29276 + TRUE, p_CcNodeInformation->index,
29277 + p_CcNodeInformation->h_CcNode, TRUE);
29278 + if (err)
29279 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29280 + }
29281 + }
29282 +
29283 + if (p_CcNode->lclMask)
29284 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
29285 +
29286 + if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
29287 + p_AdditionalInfo->h_NodeForAdd =
29288 + p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
29289 + if (p_KeyParams->ccNextEngineParams.h_Manip)
29290 + p_AdditionalInfo->h_ManipForAdd =
29291 + p_KeyParams->ccNextEngineParams.h_Manip;
29292 +
29293 +#if (DPAA_VERSION >= 11)
29294 + if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR)
29295 + && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic))
29296 + p_AdditionalInfo->h_FrmReplicForAdd =
29297 + p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic;
29298 +#endif /* (DPAA_VERSION >= 11) */
29299 +
29300 + if (!add)
29301 + {
29302 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29303 + == e_FM_PCD_CC)
29304 + p_AdditionalInfo->h_NodeForRmv =
29305 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29306 +
29307 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29308 + p_AdditionalInfo->h_ManipForRmv =
29309 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29310 +
29311 + /* If statistics were previously enabled, store the old statistics object to be released */
29312 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29313 + {
29314 + p_AdditionalInfo->p_StatsObjForRmv =
29315 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29316 + }
29317 +
29318 +#if (DPAA_VERSION >= 11)
29319 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29320 + == e_FM_PCD_FR)
29321 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29322 + p_AdditionalInfo->h_FrmReplicForRmv =
29323 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29324 +#endif /* (DPAA_VERSION >= 11) */
29325 + }
29326 +
29327 + return E_OK;
29328 +}
29329 +
29330 +static t_Error BuildNewNodeRemoveKey(
29331 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
29332 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29333 +{
29334 + int i = 0, j = 0;
29335 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29336 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29337 + int size;
29338 + t_Error err = E_OK;
29339 +
29340 + /*save new numOfKeys*/
29341 + p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1);
29342 +
29343 + /*function which allocates in the memory new KeyTbl, AdTbl*/
29344 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29345 + if (err)
29346 + RETURN_ERROR(MAJOR, err, NO_MSG);
29347 +
29348 + /*update new Ad and new Key Table according to new requirement*/
29349 + for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++)
29350 + {
29351 + if (j == keyIndex)
29352 + j++;
29353 +
29354 + if (j == p_CcNode->numOfKeys)
29355 + break;
29356 + p_AdTableNewTmp =
29357 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29358 + p_AdTableOldTmp =
29359 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29360 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29361 +
29362 + p_KeysMatchTableOldTmp =
29363 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t));
29364 + p_KeysMatchTableNewTmp =
29365 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t));
29366 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29367 + size * sizeof(uint8_t));
29368 + }
29369 +
29370 + p_AdTableNewTmp =
29371 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29372 + p_AdTableOldTmp =
29373 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29374 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29375 +
29376 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29377 + == e_FM_PCD_CC)
29378 + p_AdditionalInfo->h_NodeForRmv =
29379 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29380 +
29381 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29382 + p_AdditionalInfo->h_ManipForRmv =
29383 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29384 +
29385 + /* If statistics were previously enabled, store the old statistics object to be released */
29386 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29387 + {
29388 + p_AdditionalInfo->p_StatsObjForRmv =
29389 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29390 + }
29391 +
29392 +#if (DPAA_VERSION >= 11)
29393 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29394 + == e_FM_PCD_FR)
29395 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29396 + p_AdditionalInfo->h_FrmReplicForRmv =
29397 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29398 +#endif /* (DPAA_VERSION >= 11) */
29399 +
29400 + return E_OK;
29401 +}
29402 +
29403 +static t_Error BuildNewNodeModifyKey(
29404 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key,
29405 + uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29406 +{
29407 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
29408 + t_Error err = E_OK;
29409 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29410 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29411 + int size;
29412 + int i = 0, j = 0;
29413 + bool prvLclMask;
29414 + t_FmPcdStatsObj *p_StatsObj, tmpStatsObj;
29415 + p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys;
29416 +
29417 + prvLclMask = p_CcNode->lclMask;
29418 +
29419 + /* Check that new key is not require update of localMask */
29420 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask);
29421 + if (err)
29422 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29423 +
29424 + /* Update internal data structure with new next engine for the given index */
29425 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key,
29426 + p_CcNode->userSizeOfExtraction);
29427 +
29428 + if (p_Mask)
29429 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask,
29430 + p_CcNode->userSizeOfExtraction);
29431 + else
29432 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
29433 + p_CcNode->userSizeOfExtraction);
29434 +
29435 + /*function which build in the memory new KeyTbl, AdTbl*/
29436 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29437 + if (err)
29438 + RETURN_ERROR(MAJOR, err, NO_MSG);
29439 +
29440 + /*fill the New AdTable and New KeyTable*/
29441 + for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
29442 + {
29443 + p_AdTableNewTmp =
29444 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
29445 + p_AdTableOldTmp =
29446 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29447 +
29448 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29449 +
29450 + if (j == keyIndex)
29451 + {
29452 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
29453 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29454 + {
29455 + /* As statistics were enabled, we need to update the existing
29456 + statistics descriptor with a new nullified counters. */
29457 + p_StatsObj = GetStatsObj(p_CcNode);
29458 + ASSERT_COND(p_StatsObj);
29459 +
29460 + SetStatsCounters(
29461 + p_AdTableNewTmp,
29462 + (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters)
29463 + - p_FmPcd->physicalMuramBase)));
29464 +
29465 + tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd;
29466 + tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters;
29467 +
29468 + /* As we need to replace only the counters, we build a new statistics
29469 + object that holds the old AD and the new counters - this will be the
29470 + currently used statistics object.
29471 + The newly allocated AD is not required and may be released back to
29472 + the available objects with the previous counters pointer. */
29473 + p_StatsObj->h_StatsAd =
29474 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29475 +
29476 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd =
29477 + tmpStatsObj.h_StatsAd;
29478 +
29479 + /* Store allocated statistics object */
29480 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29481 + p_StatsObj;
29482 +
29483 + /* As statistics were previously enabled, store the old statistics object to be released */
29484 + p_AdditionalInfo->p_StatsObjForRmv =
29485 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29486 + }
29487 +
29488 + p_KeysMatchTableNewTmp =
29489 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29490 +
29491 + MemCpy8(p_KeysMatchTableNewTmp, p_Key,
29492 + p_CcNode->userSizeOfExtraction);
29493 +
29494 + if (p_CcNode->lclMask)
29495 + {
29496 + if (p_Mask)
29497 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29498 + p_CcNode->ccKeySizeAccExtraction),
29499 + p_Mask, p_CcNode->userSizeOfExtraction);
29500 + else
29501 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29502 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29503 + p_CcNode->ccKeySizeAccExtraction),
29504 + 0xff, p_CcNode->userSizeOfExtraction);
29505 + else
29506 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29507 + p_CcNode->ccKeySizeAccExtraction),
29508 + p_CcNode->p_GlblMask,
29509 + p_CcNode->userSizeOfExtraction);
29510 + }
29511 + }
29512 + else
29513 + {
29514 + p_KeysMatchTableNewTmp =
29515 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29516 + p_KeysMatchTableOldTmp =
29517 + PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t));
29518 +
29519 + if (p_CcNode->lclMask)
29520 + {
29521 + if (prvLclMask)
29522 + MemCpy8(
29523 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29524 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29525 + p_CcNode->userSizeOfExtraction);
29526 + else
29527 + {
29528 + p_KeysMatchTableOldTmp =
29529 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29530 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29531 +
29532 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29533 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29534 + p_CcNode->ccKeySizeAccExtraction),
29535 + 0xff, p_CcNode->userSizeOfExtraction);
29536 + else
29537 + MemCpy8(
29538 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29539 + p_CcNode->p_GlblMask,
29540 + p_CcNode->userSizeOfExtraction);
29541 + }
29542 + }
29543 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29544 + p_CcNode->ccKeySizeAccExtraction);
29545 + }
29546 + }
29547 +
29548 + p_AdTableNewTmp =
29549 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29550 + p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE);
29551 +
29552 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29553 +
29554 + return E_OK;
29555 +}
29556 +
29557 +static t_Error BuildNewNodeModifyNextEngine(
29558 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29559 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst,
29560 + t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29561 +{
29562 + t_Error err = E_OK;
29563 + uint32_t requiredAction = 0;
29564 + t_List *p_Pos;
29565 + t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
29566 + t_Handle p_Ad;
29567 + t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
29568 + t_FmPcdCcTree *p_FmPcdCcTree = NULL;
29569 + t_FmPcdStatsObj *p_StatsObj;
29570 + t_FmPcdCcStatsParams statsParams = { 0 };
29571 +
29572 + ASSERT_COND(p_CcNextEngineParams);
29573 +
29574 + /* check that new NIA is legal */
29575 + if (!p_AdditionalInfo->tree)
29576 + err = ValidateNextEngineParams(
29577 + h_FmPcd, p_CcNextEngineParams,
29578 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode);
29579 + else
29580 + /* Statistics are not supported for CC root */
29581 + err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams,
29582 + e_FM_PCD_CC_STATS_MODE_NONE);
29583 + if (err)
29584 + RETURN_ERROR(MAJOR, err, NO_MSG);
29585 +
29586 + /* Update internal data structure for next engine per index (index - key) */
29587 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
29588 + p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
29589 +
29590 + /* Check that manip is legal and what requiredAction is necessary for this manip */
29591 + if (p_CcNextEngineParams->h_Manip)
29592 + {
29593 + err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams,
29594 + &requiredAction);
29595 + if (err)
29596 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29597 + }
29598 +
29599 + if (!p_AdditionalInfo->tree)
29600 + {
29601 + p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29602 + p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys;
29603 + p_Ad = p_FmPcdCcNode1->h_AdTable;
29604 +
29605 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29606 + == e_FM_PCD_CC)
29607 + p_AdditionalInfo->h_NodeForRmv =
29608 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29609 +
29610 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29611 + p_AdditionalInfo->h_ManipForRmv =
29612 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29613 +
29614 +#if (DPAA_VERSION >= 11)
29615 + if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29616 + == e_FM_PCD_FR)
29617 + && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29618 + p_AdditionalInfo->h_FrmReplicForRmv =
29619 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29620 +#endif /* (DPAA_VERSION >= 11) */
29621 + }
29622 + else
29623 + {
29624 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29625 + p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
29626 +
29627 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29628 + == e_FM_PCD_CC)
29629 + p_AdditionalInfo->h_NodeForRmv =
29630 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29631 +
29632 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29633 + p_AdditionalInfo->h_ManipForRmv =
29634 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29635 +
29636 +#if (DPAA_VERSION >= 11)
29637 + if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29638 + == e_FM_PCD_FR)
29639 + && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29640 + p_AdditionalInfo->h_FrmReplicForRmv =
29641 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29642 +#endif /* (DPAA_VERSION >= 11) */
29643 + }
29644 +
29645 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29646 + && p_CcNextEngineParams->h_Manip)
29647 + {
29648 + err = AllocAndFillAdForContLookupManip(
29649 + p_CcNextEngineParams->params.ccParams.h_CcNode);
29650 + if (err)
29651 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29652 + }
29653 +
29654 + ASSERT_COND(p_Ad);
29655 +
29656 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29657 + ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
29658 +
29659 + /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its
29660 + nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled,
29661 + only the actual Nia-Ad should be modified. */
29662 + if ((!p_AdditionalInfo->tree)
29663 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29664 + && (p_CcNextEngineParams->statisticsEn))
29665 + ccNodeInfo.h_CcNode =
29666 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29667 +
29668 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29669 +
29670 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29671 + p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree);
29672 + if (!p_Ad)
29673 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
29674 + ("MURAM allocation for CC node action descriptor"));
29675 + MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
29676 +
29677 + /* If statistics were not enabled before, but requested now - Allocate a statistics
29678 + object that holds statistics AD and counters. */
29679 + if ((!p_AdditionalInfo->tree)
29680 + && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29681 + && (p_CcNextEngineParams->statisticsEn))
29682 + {
29683 + p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree);
29684 + ASSERT_COND(p_StatsObj);
29685 +
29686 + /* Store allocated statistics object */
29687 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29688 + p_StatsObj;
29689 +
29690 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
29691 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
29692 +
29693 +#if (DPAA_VERSION >= 11)
29694 + statsParams.h_StatsFLRs =
29695 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs;
29696 +
29697 +#endif /* (DPAA_VERSION >= 11) */
29698 +
29699 + NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd);
29700 + }
29701 + else
29702 + NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd);
29703 +
29704 + ccNodeInfo.h_CcNode = p_Ad;
29705 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
29706 +
29707 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
29708 + requiredAction;
29709 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
29710 + UPDATE_CC_WITH_TREE;
29711 +
29712 + if (!p_AdditionalInfo->tree)
29713 + {
29714 + ASSERT_COND(p_FmPcdCcNode1);
29715 + if (!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
29716 + {
29717 + LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
29718 + {
29719 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29720 +
29721 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29722 + /* Update the manipulation which has to be updated from parameters of the port
29723 + it's has to be updated with restrictions defined in the function */
29724 +
29725 + err =
29726 + SetRequiredAction(
29727 + p_FmPcdCcNode1->h_FmPcd,
29728 + p_FmPcdCcNode1->shadowAction
29729 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29730 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29731 + p_Ad, 1, p_CcNodeInformation->h_CcNode);
29732 + if (err)
29733 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29734 +
29735 + err = CcUpdateParam(
29736 + p_FmPcdCcNode1->h_FmPcd, NULL, NULL,
29737 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1,
29738 + p_Ad, TRUE, p_CcNodeInformation->index,
29739 + p_CcNodeInformation->h_CcNode, TRUE);
29740 + if (err)
29741 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29742 + }
29743 + }
29744 + }
29745 + else
29746 + {
29747 + ASSERT_COND(p_FmPcdCcTree);
29748 +
29749 + err =
29750 + SetRequiredAction(
29751 + h_FmPcd,
29752 + p_FmPcdCcTree->requiredAction
29753 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29754 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29755 + p_Ad, 1, (t_Handle)p_FmPcdCcTree);
29756 + if (err)
29757 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29758 +
29759 + err = CcUpdateParam(h_FmPcd, NULL, NULL,
29760 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29761 + 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
29762 + if (err)
29763 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29764 + }
29765 +
29766 + if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29767 + p_AdditionalInfo->h_NodeForAdd =
29768 + p_CcNextEngineParams->params.ccParams.h_CcNode;
29769 + if (p_CcNextEngineParams->h_Manip)
29770 + p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip;
29771 +
29772 + /* If statistics were previously enabled, but now are disabled,
29773 + store the old statistics object to be released */
29774 + if ((!p_AdditionalInfo->tree)
29775 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29776 + && (!p_CcNextEngineParams->statisticsEn))
29777 + {
29778 + p_AdditionalInfo->p_StatsObjForRmv =
29779 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj;
29780 +
29781 +
29782 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL;
29783 + }
29784 +#if (DPAA_VERSION >= 11)
29785 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR)
29786 + && (p_CcNextEngineParams->params.frParams.h_FrmReplic))
29787 + p_AdditionalInfo->h_FrmReplicForAdd =
29788 + p_CcNextEngineParams->params.frParams.h_FrmReplic;
29789 +#endif /* (DPAA_VERSION >= 11) */
29790 +
29791 + return E_OK;
29792 +}
29793 +
29794 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(
29795 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29796 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29797 +{
29798 + t_CcNodeInformation *p_CcNodeInformation;
29799 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL;
29800 + t_List *p_Pos;
29801 + int i = 0;
29802 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
29803 + t_CcNodeInformation ccNodeInfo;
29804 +
29805 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
29806 + {
29807 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29808 + p_NodePtrOnCurrentMdfNode =
29809 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
29810 +
29811 + ASSERT_COND(p_NodePtrOnCurrentMdfNode);
29812 +
29813 + /* Search in the previous node which exact index points on this current modified node for getting AD */
29814 + for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
29815 + {
29816 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29817 + == e_FM_PCD_CC)
29818 + {
29819 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29820 + == (t_Handle)p_CrntMdfNode)
29821 + {
29822 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
29823 + p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad;
29824 + else
29825 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj)
29826 + p_AdTablePtOnCrntCurrentMdfNode =
29827 + p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
29828 + else
29829 + p_AdTablePtOnCrntCurrentMdfNode =
29830 + PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
29831 +
29832 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29833 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
29834 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29835 +
29836 + if (!(*p_NextEngineParams))
29837 + *p_NextEngineParams =
29838 + &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29839 + }
29840 + }
29841 + }
29842 +
29843 + ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
29844 + }
29845 +}
29846 +
29847 +static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(
29848 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29849 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29850 +{
29851 + t_CcNodeInformation *p_CcNodeInformation;
29852 + t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL;
29853 + t_List *p_Pos;
29854 + int i = 0;
29855 + t_Handle p_AdTableTmp;
29856 + t_CcNodeInformation ccNodeInfo;
29857 +
29858 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
29859 + {
29860 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29861 + p_TreePtrOnCurrentMdfNode =
29862 + (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
29863 +
29864 + ASSERT_COND(p_TreePtrOnCurrentMdfNode);
29865 +
29866 + /*search in the trees which exact index points on this current modified node for getting AD */
29867 + for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
29868 + {
29869 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29870 + == e_FM_PCD_CC)
29871 + {
29872 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29873 + == (t_Handle)p_CrntMdfNode)
29874 + {
29875 + p_AdTableTmp =
29876 + UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
29877 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29878 + ccNodeInfo.h_CcNode = p_AdTableTmp;
29879 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29880 +
29881 + if (!(*p_NextEngineParams))
29882 + *p_NextEngineParams =
29883 + &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29884 + }
29885 + }
29886 + }
29887 +
29888 + ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
29889 + }
29890 +}
29891 +
29892 +static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart(
29893 + t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29894 + e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree)
29895 +{
29896 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams;
29897 + int i = 0, j = 0;
29898 + bool wasUpdate = FALSE;
29899 + t_FmPcdCcNode *p_CcNode = NULL;
29900 + t_FmPcdCcTree *p_FmPcdCcTree;
29901 + uint16_t numOfKeys;
29902 + t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams;
29903 +
29904 + SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL);
29905 +
29906 + if (!tree)
29907 + {
29908 + p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29909 + numOfKeys = p_CcNode->numOfKeys;
29910 +
29911 + /* node has to be pointed by another node or tree */
29912 +
29913 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29914 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1));
29915 + if (!p_KeyAndNextEngineParams)
29916 + {
29917 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29918 + return NULL;
29919 + }
29920 + memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams,
29921 + (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29922 +
29923 + if (ttlCheck)
29924 + {
29925 + if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL)
29926 + || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT))
29927 + {
29928 + XX_Free(p_KeyAndNextEngineParams);
29929 + 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"));
29930 + return NULL;
29931 + }
29932 + }
29933 +
29934 + if (hashCheck)
29935 + {
29936 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
29937 + {
29938 + XX_Free(p_KeyAndNextEngineParams);
29939 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation"));
29940 + return NULL;
29941 + }
29942 + }
29943 + }
29944 + else
29945 + {
29946 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29947 + numOfKeys = p_FmPcdCcTree->numOfEntries;
29948 +
29949 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29950 + sizeof(t_FmPcdCcKeyAndNextEngineParams)
29951 + * FM_PCD_MAX_NUM_OF_CC_GROUPS);
29952 + if (!p_KeyAndNextEngineParams)
29953 + {
29954 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29955 + return NULL;
29956 + }
29957 + memcpy(p_KeyAndNextEngineParams,
29958 + p_FmPcdCcTree->keyAndNextEngineParams,
29959 + FM_PCD_MAX_NUM_OF_CC_GROUPS
29960 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29961 + }
29962 +
29963 + p_FmPcdModifyCcKeyAdditionalParams =
29964 + (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(
29965 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
29966 + if (!p_FmPcdModifyCcKeyAdditionalParams)
29967 + {
29968 + XX_Free(p_KeyAndNextEngineParams);
29969 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
29970 + return NULL;
29971 + }
29972 + memset(p_FmPcdModifyCcKeyAdditionalParams, 0,
29973 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
29974 +
29975 + p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
29976 + p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex;
29977 +
29978 + while (i < numOfKeys)
29979 + {
29980 + if ((j == keyIndex) && !wasUpdate)
29981 + {
29982 + if (modifyState == e_MODIFY_STATE_ADD)
29983 + j++;
29984 + else
29985 + if (modifyState == e_MODIFY_STATE_REMOVE)
29986 + i++;
29987 + wasUpdate = TRUE;
29988 + }
29989 + else
29990 + {
29991 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
29992 + p_KeyAndNextEngineParams + i,
29993 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
29994 + i++;
29995 + j++;
29996 + }
29997 + }
29998 +
29999 + if (keyIndex == numOfKeys)
30000 + {
30001 + if (modifyState == e_MODIFY_STATE_ADD)
30002 + j++;
30003 + }
30004 +
30005 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
30006 + p_KeyAndNextEngineParams + numOfKeys,
30007 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
30008 +
30009 + XX_Free(p_KeyAndNextEngineParams);
30010 +
30011 + return p_FmPcdModifyCcKeyAdditionalParams;
30012 +}
30013 +
30014 +static t_Error UpdatePtrWhichPointOnCrntMdfNode(
30015 + t_FmPcdCcNode *p_CcNode,
30016 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
30017 + t_List *h_OldLst, t_List *h_NewLst)
30018 +{
30019 + t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL;
30020 + t_CcNodeInformation ccNodeInfo = { 0 };
30021 + t_Handle h_NewAd;
30022 + t_Handle h_OrigAd = NULL;
30023 +
30024 + /* Building a list of all action descriptors that point to the previous node */
30025 + if (!LIST_IsEmpty(&p_CcNode->ccPrevNodesLst))
30026 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
30027 + &p_NextEngineParams);
30028 +
30029 + if (!LIST_IsEmpty(&p_CcNode->ccTreeIdLst))
30030 + UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
30031 + &p_NextEngineParams);
30032 +
30033 + /* This node must be found as next engine of one of its previous nodes or trees*/
30034 + if (p_NextEngineParams)
30035 + {
30036 + /* Building a new action descriptor that points to the modified node */
30037 + h_NewAd = GetNewAd(p_CcNode, FALSE);
30038 + if (!h_NewAd)
30039 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
30040 + MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
30041 +
30042 + h_OrigAd = p_CcNode->h_Ad;
30043 + BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode,
30044 + p_NextEngineParams);
30045 +
30046 + ccNodeInfo.h_CcNode = h_NewAd;
30047 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
30048 +
30049 + if (p_NextEngineParams->h_Manip && !h_OrigAd)
30050 + FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE);
30051 + }
30052 + return E_OK;
30053 +}
30054 +
30055 +static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
30056 +{
30057 + ASSERT_COND(p_FmPcdCcTree);
30058 +
30059 + /* this routine must be protected by the calling routine! */
30060 +
30061 + if (add)
30062 + p_FmPcdCcTree->owners++;
30063 + else
30064 + {
30065 + ASSERT_COND(p_FmPcdCcTree->owners);
30066 + p_FmPcdCcTree->owners--;
30067 + }
30068 +}
30069 +
30070 +static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode)
30071 +{
30072 + t_Error err = E_OK;
30073 + int i = 0;
30074 +
30075 + for (i = 0; i < p_CcNode->numOfKeys; i++)
30076 + {
30077 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
30078 + {
30079 + err =
30080 + FmPcdManipCheckParamsWithCcNodeParams(
30081 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
30082 + (t_Handle)p_CcNode);
30083 + if (err)
30084 + return err;
30085 + }
30086 + }
30087 +
30088 + return err;
30089 +}
30090 +static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode,
30091 + t_FmPcdCcNodeParams *p_CcNodeParam,
30092 + uint32_t *p_NumOfRanges,
30093 + uint32_t *p_CountersArraySize)
30094 +{
30095 + e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode;
30096 + uint32_t i;
30097 +
30098 + UNUSED(p_CcNodeParam);
30099 +
30100 + switch (statisticsMode)
30101 + {
30102 + case e_FM_PCD_CC_STATS_MODE_NONE:
30103 + for (i = 0; i < p_CcNode->numOfKeys; i++)
30104 + if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn)
30105 + RETURN_ERROR(
30106 + MAJOR,
30107 + E_INVALID_VALUE,
30108 + ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i));
30109 + return E_OK;
30110 +
30111 + case e_FM_PCD_CC_STATS_MODE_FRAME:
30112 + case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME:
30113 + *p_NumOfRanges = 1;
30114 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
30115 + return E_OK;
30116 +
30117 +#if (DPAA_VERSION >= 11)
30118 + case e_FM_PCD_CC_STATS_MODE_RMON:
30119 + {
30120 + uint16_t *p_FrameLengthRanges =
30121 + p_CcNodeParam->keysParams.frameLengthRanges;
30122 + uint32_t i;
30123 +
30124 + if (p_FrameLengthRanges[0] <= 0)
30125 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
30126 +
30127 + if (p_FrameLengthRanges[0] == 0xFFFF)
30128 + {
30129 + *p_NumOfRanges = 1;
30130 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
30131 + return E_OK;
30132 + }
30133 +
30134 + for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++)
30135 + {
30136 + if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i])
30137 + RETURN_ERROR(
30138 + MAJOR,
30139 + E_INVALID_VALUE,
30140 + ("Frame length range must be larger at least by 1 from preceding range"));
30141 +
30142 + /* Stop when last range is reached */
30143 + if (p_FrameLengthRanges[i] == 0xFFFF)
30144 + break;
30145 + }
30146 +
30147 + if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR)
30148 + || (p_FrameLengthRanges[i] != 0xFFFF))
30149 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30150 + ("Last Frame length range must be 0xFFFF"));
30151 +
30152 + *p_NumOfRanges = i + 1;
30153 +
30154 + /* Allocate an extra counter for byte count, as counters
30155 + array always begins with byte count */
30156 + *p_CountersArraySize = (*p_NumOfRanges + 1)
30157 + * FM_PCD_CC_STATS_COUNTER_SIZE;
30158 +
30159 + }
30160 + return E_OK;
30161 +#endif /* (DPAA_VERSION >= 11) */
30162 +
30163 + default:
30164 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
30165 + }
30166 +}
30167 +
30168 +static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
30169 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
30170 +{
30171 + int tmp = 0;
30172 + t_FmPcdCcKeyParams *p_KeyParams;
30173 + t_Error err;
30174 + uint32_t requiredAction = 0;
30175 +
30176 + /* Validate statistics parameters */
30177 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30178 + &(p_CcNode->numOfStatsFLRs),
30179 + &(p_CcNode->countersArraySize));
30180 + if (err)
30181 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30182 +
30183 + /* Validate next engine parameters on Miss */
30184 + err = ValidateNextEngineParams(
30185 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30186 + p_CcNode->statisticsMode);
30187 + if (err)
30188 + RETURN_ERROR(MAJOR, err,
30189 + ("For this node MissNextEngineParams are not valid"));
30190 +
30191 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30192 + {
30193 + err = FmPcdManipCheckParamsForCcNextEngine(
30194 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30195 + &requiredAction);
30196 + if (err)
30197 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30198 + }
30199 +
30200 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30201 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30202 + sizeof(t_FmPcdCcNextEngineParams));
30203 +
30204 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30205 + requiredAction;
30206 +
30207 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30208 + == e_FM_PCD_CC)
30209 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30210 + {
30211 + err =
30212 + AllocAndFillAdForContLookupManip(
30213 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30214 + if (err)
30215 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30216 + }
30217 +
30218 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30219 + {
30220 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30221 +
30222 + if (!p_KeyParams->p_Key)
30223 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
30224 +
30225 + err = ValidateNextEngineParams(h_FmPcd,
30226 + &p_KeyParams->ccNextEngineParams,
30227 + p_CcNode->statisticsMode);
30228 + if (err)
30229 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30230 +
30231 + err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize,
30232 + p_KeyParams->p_Mask);
30233 + if (err)
30234 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30235 +
30236 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30237 + {
30238 + err = FmPcdManipCheckParamsForCcNextEngine(
30239 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30240 + if (err)
30241 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30242 + }
30243 +
30244 + /* Store 'key' parameters - key, mask (if passed by the user) */
30245 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key,
30246 + p_CcNodeParam->keysParams.keySize);
30247 +
30248 + if (p_KeyParams->p_Mask)
30249 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask,
30250 + p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize);
30251 + else
30252 + memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF,
30253 + p_CcNodeParam->keysParams.keySize);
30254 +
30255 + /* Store next engine parameters */
30256 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30257 + &p_KeyParams->ccNextEngineParams,
30258 + sizeof(t_FmPcdCcNextEngineParams));
30259 +
30260 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30261 +
30262 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30263 + == e_FM_PCD_CC)
30264 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30265 + {
30266 + err =
30267 + AllocAndFillAdForContLookupManip(
30268 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30269 + if (err)
30270 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30271 + }
30272 + }
30273 +
30274 + if (p_CcNode->maxNumOfKeys)
30275 + {
30276 + if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys)
30277 + RETURN_ERROR(
30278 + MAJOR,
30279 + E_INVALID_VALUE,
30280 + ("Number of keys exceed the provided maximal number of keys"));
30281 + }
30282 +
30283 + *isKeyTblAlloc = TRUE;
30284 +
30285 + return E_OK;
30286 +}
30287 +
30288 +static t_Error Ipv4TtlOrIpv6HopLimitCheckParams(
30289 + t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
30290 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
30291 +{
30292 + int tmp = 0;
30293 + t_FmPcdCcKeyParams *p_KeyParams;
30294 + t_Error err;
30295 + uint8_t key = 0x01;
30296 + uint32_t requiredAction = 0;
30297 +
30298 + if (p_CcNode->numOfKeys != 1)
30299 + RETURN_ERROR(
30300 + MAJOR,
30301 + E_INVALID_VALUE,
30302 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1"));
30303 +
30304 + if ((p_CcNodeParam->keysParams.maxNumOfKeys)
30305 + && (p_CcNodeParam->keysParams.maxNumOfKeys != 1))
30306 + RETURN_ERROR(
30307 + MAJOR,
30308 + E_INVALID_VALUE,
30309 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1"));
30310 +
30311 + /* Validate statistics parameters */
30312 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30313 + &(p_CcNode->numOfStatsFLRs),
30314 + &(p_CcNode->countersArraySize));
30315 + if (err)
30316 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30317 +
30318 + err = ValidateNextEngineParams(
30319 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30320 + p_CcNodeParam->keysParams.statisticsMode);
30321 + if (err)
30322 + RETURN_ERROR(MAJOR, err,
30323 + ("For this node MissNextEngineParams are not valid"));
30324 +
30325 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30326 + {
30327 + err = FmPcdManipCheckParamsForCcNextEngine(
30328 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30329 + &requiredAction);
30330 + if (err)
30331 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30332 + }
30333 +
30334 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30335 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30336 + sizeof(t_FmPcdCcNextEngineParams));
30337 +
30338 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30339 + requiredAction;
30340 +
30341 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30342 + == e_FM_PCD_CC)
30343 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30344 + {
30345 + err =
30346 + AllocAndFillAdForContLookupManip(
30347 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30348 + if (err)
30349 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30350 + }
30351 +
30352 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30353 + {
30354 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30355 +
30356 + if (p_KeyParams->p_Mask)
30357 + RETURN_ERROR(
30358 + MAJOR,
30359 + E_INVALID_VALUE,
30360 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
30361 +
30362 + if (memcmp(p_KeyParams->p_Key, &key, 1) != 0)
30363 + RETURN_ERROR(
30364 + MAJOR,
30365 + E_INVALID_VALUE,
30366 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
30367 +
30368 + err = ValidateNextEngineParams(h_FmPcd,
30369 + &p_KeyParams->ccNextEngineParams,
30370 + p_CcNode->statisticsMode);
30371 + if (err)
30372 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30373 +
30374 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30375 + {
30376 + err = FmPcdManipCheckParamsForCcNextEngine(
30377 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30378 + if (err)
30379 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30380 + }
30381 +
30382 + /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */
30383 + p_CcNode->keyAndNextEngineParams[tmp].key[0] = key;
30384 + p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF;
30385 +
30386 + /* Store NextEngine parameters */
30387 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30388 + &p_KeyParams->ccNextEngineParams,
30389 + sizeof(t_FmPcdCcNextEngineParams));
30390 +
30391 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30392 + == e_FM_PCD_CC)
30393 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30394 + {
30395 + err =
30396 + AllocAndFillAdForContLookupManip(
30397 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30398 + if (err)
30399 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30400 + }
30401 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30402 + }
30403 +
30404 + *isKeyTblAlloc = FALSE;
30405 +
30406 + return E_OK;
30407 +}
30408 +
30409 +static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
30410 + t_FmPcdCcNodeParams *p_CcNodeParam,
30411 + t_FmPcdCcNode *p_CcNode,
30412 + bool *isKeyTblAlloc)
30413 +{
30414 + int tmp = 0, countOnes = 0;
30415 + t_FmPcdCcKeyParams *p_KeyParams;
30416 + t_Error err;
30417 + uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
30418 + uint16_t countMask = (uint16_t)(glblMask >> 4);
30419 + uint32_t requiredAction = 0;
30420 +
30421 + if (glblMask & 0x000f)
30422 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30423 + ("icIndxMask has to be with last nibble 0"));
30424 +
30425 + while (countMask)
30426 + {
30427 + countOnes++;
30428 + countMask = (uint16_t)(countMask >> 1);
30429 + }
30430 +
30431 + if (!POWER_OF_2(p_CcNode->numOfKeys))
30432 + RETURN_ERROR(
30433 + MAJOR,
30434 + E_INVALID_VALUE,
30435 + ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
30436 +
30437 + if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes))
30438 + RETURN_ERROR(
30439 + MAJOR,
30440 + E_INVALID_VALUE,
30441 + ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
30442 +
30443 + if (p_CcNodeParam->keysParams.maxNumOfKeys
30444 + && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys))
30445 + RETURN_ERROR(
30446 + MAJOR,
30447 + E_INVALID_VALUE,
30448 + ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'"));
30449 +
30450 + /* Validate statistics parameters */
30451 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30452 + &(p_CcNode->numOfStatsFLRs),
30453 + &(p_CcNode->countersArraySize));
30454 + if (err)
30455 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30456 +
30457 + err = ValidateNextEngineParams(
30458 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30459 + p_CcNode->statisticsMode);
30460 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30461 + RETURN_ERROR(
30462 + MAJOR,
30463 + err,
30464 + ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
30465 +
30466 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30467 + {
30468 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30469 +
30470 + if (p_KeyParams->p_Mask || p_KeyParams->p_Key)
30471 + RETURN_ERROR(
30472 + MAJOR,
30473 + E_INVALID_VALUE,
30474 + ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
30475 +
30476 + if ((glblMask & (tmp * 16)) == (tmp * 16))
30477 + {
30478 + err = ValidateNextEngineParams(h_FmPcd,
30479 + &p_KeyParams->ccNextEngineParams,
30480 + p_CcNode->statisticsMode);
30481 + if (err)
30482 + RETURN_ERROR(
30483 + MAJOR,
30484 + err,
30485 + ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
30486 +
30487 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30488 + {
30489 + err = FmPcdManipCheckParamsForCcNextEngine(
30490 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30491 + if (err)
30492 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30493 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction =
30494 + requiredAction;
30495 + }
30496 +
30497 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30498 + &p_KeyParams->ccNextEngineParams,
30499 + sizeof(t_FmPcdCcNextEngineParams));
30500 +
30501 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30502 + == e_FM_PCD_CC)
30503 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30504 + {
30505 + err =
30506 + AllocAndFillAdForContLookupManip(
30507 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30508 + if (err)
30509 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30510 + }
30511 + }
30512 + else
30513 + {
30514 + err = ValidateNextEngineParams(h_FmPcd,
30515 + &p_KeyParams->ccNextEngineParams,
30516 + p_CcNode->statisticsMode);
30517 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30518 + RETURN_ERROR(
30519 + MAJOR,
30520 + err,
30521 + ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
30522 + }
30523 + }
30524 +
30525 + *isKeyTblAlloc = FALSE;
30526 + cpu_to_be16s(&glblMask);
30527 + memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2);
30528 +
30529 + return E_OK;
30530 +}
30531 +
30532 +static t_Error ModifyNextEngineParamNode(
30533 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex,
30534 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
30535 +{
30536 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
30537 + t_FmPcd *p_FmPcd;
30538 + t_List h_OldPointersLst, h_NewPointersLst;
30539 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
30540 + t_Error err = E_OK;
30541 +
30542 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE);
30543 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
30544 +
30545 + if (keyIndex >= p_CcNode->numOfKeys)
30546 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30547 + ("keyIndex > previously cleared last index + 1"));
30548 +
30549 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
30550 +
30551 + INIT_LIST(&h_OldPointersLst);
30552 + INIT_LIST(&h_NewPointersLst);
30553 +
30554 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
30555 + e_MODIFY_STATE_CHANGE, FALSE,
30556 + FALSE, FALSE);
30557 + if (!p_ModifyKeyParams)
30558 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
30559 +
30560 + if (p_CcNode->maxNumOfKeys
30561 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
30562 + {
30563 + XX_Free(p_ModifyKeyParams);
30564 + return ERROR_CODE(E_BUSY);
30565 + }
30566 +
30567 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
30568 + p_FmPcdCcNextEngineParams,
30569 + &h_OldPointersLst, &h_NewPointersLst,
30570 + p_ModifyKeyParams);
30571 + if (err)
30572 + {
30573 + XX_Free(p_ModifyKeyParams);
30574 + if (p_CcNode->maxNumOfKeys)
30575 + RELEASE_LOCK(p_FmPcd->shadowLock);
30576 + RETURN_ERROR(MAJOR, err, NO_MSG);
30577 + }
30578 +
30579 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
30580 + p_ModifyKeyParams, FALSE);
30581 +
30582 + if (p_CcNode->maxNumOfKeys)
30583 + RELEASE_LOCK(p_FmPcd->shadowLock);
30584 +
30585 + ReleaseLst(&h_OldPointersLst);
30586 + ReleaseLst(&h_NewPointersLst);
30587 +
30588 + return err;
30589 +}
30590 +
30591 +static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key,
30592 + uint8_t *p_Mask, uint16_t *p_KeyIndex)
30593 +{
30594 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
30595 + uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY];
30596 + uint16_t i;
30597 +
30598 + ASSERT_COND(p_Key);
30599 + ASSERT_COND(p_KeyIndex);
30600 + ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY);
30601 +
30602 + if (keySize != p_CcNode->userSizeOfExtraction)
30603 + RETURN_ERROR(
30604 + MINOR, E_INVALID_VALUE,
30605 + ("Key size doesn't match the extraction size of the node"));
30606 +
30607 + /* If user didn't pass a mask for this key, we'll look for full extraction mask */
30608 + if (!p_Mask)
30609 + memset(tmpMask, 0xFF, keySize);
30610 +
30611 + for (i = 0; i < p_CcNode->numOfKeys; i++)
30612 + {
30613 + /* Comparing received key */
30614 + if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize)
30615 + == 0)
30616 + {
30617 + if (p_Mask)
30618 + {
30619 + /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */
30620 + if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask,
30621 + keySize) == 0)
30622 + {
30623 + *p_KeyIndex = i;
30624 + return E_OK;
30625 + }
30626 + }
30627 + else
30628 + {
30629 + /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */
30630 + if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask,
30631 + keySize) == 0)
30632 + {
30633 + *p_KeyIndex = i;
30634 + return E_OK;
30635 + }
30636 + }
30637 + }
30638 + }
30639 +
30640 + return ERROR_CODE(E_NOT_FOUND);
30641 +}
30642 +
30643 +static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode,
30644 + bool isKeyTblAlloc,
30645 + uint32_t *p_MatchTableSize,
30646 + uint32_t *p_AdTableSize)
30647 +{
30648 + uint32_t shadowSize;
30649 + t_Error err;
30650 +
30651 + /* Calculate keys table maximal size - each entry consists of a key and a mask,
30652 + (if local mask support is requested) */
30653 + *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)
30654 + * p_CcNode->maxNumOfKeys;
30655 +
30656 + if (p_CcNode->maskSupport)
30657 + *p_MatchTableSize *= 2;
30658 +
30659 + /* Calculate next action descriptors table, including one more entry for miss */
30660 + *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1)
30661 + * FM_PCD_CC_AD_ENTRY_SIZE);
30662 +
30663 + /* Calculate maximal shadow size of this node.
30664 + All shadow structures will be used for runtime modifications host command. If
30665 + keys table was allocated for this node, the keys table and next engines table may
30666 + be modified in run time (entries added or removed), so shadow tables are requires.
30667 + Otherwise, the only supported runtime modification is a specific next engine update
30668 + and this requires shadow memory of a single AD */
30669 +
30670 + /* Shadow size should be enough to hold the following 3 structures:
30671 + * 1 - an action descriptor */
30672 + shadowSize = FM_PCD_CC_AD_ENTRY_SIZE;
30673 +
30674 + /* 2 - keys match table, if was allocated for the current node */
30675 + if (isKeyTblAlloc)
30676 + shadowSize += *p_MatchTableSize;
30677 +
30678 + /* 3 - next action descriptors table */
30679 + shadowSize += *p_AdTableSize;
30680 +
30681 + /* Update shadow to the calculated size */
30682 + err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize,
30683 + FM_PCD_CC_AD_TABLE_ALIGN);
30684 + if (err != E_OK)
30685 + {
30686 + DeleteNode(p_CcNode);
30687 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow"));
30688 + }
30689 +
30690 + return E_OK;
30691 +}
30692 +
30693 +static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode)
30694 +{
30695 + t_FmPcdStatsObj *p_StatsObj;
30696 + t_Handle h_FmMuram, h_StatsAd, h_StatsCounters;
30697 + uint32_t i;
30698 +
30699 + h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
30700 + if (!h_FmMuram)
30701 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30702 +
30703 + /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters)
30704 + will be allocated to support runtime modifications */
30705 + for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++)
30706 + {
30707 + /* Allocate list object structure */
30708 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
30709 + if (!p_StatsObj)
30710 + {
30711 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30712 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object"));
30713 + }
30714 + memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj));
30715 +
30716 + /* Allocate statistics AD from MURAM */
30717 + h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram,
30718 + FM_PCD_CC_AD_ENTRY_SIZE,
30719 + FM_PCD_CC_AD_TABLE_ALIGN);
30720 + if (!h_StatsAd)
30721 + {
30722 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30723 + XX_Free(p_StatsObj);
30724 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30725 + ("MURAM allocation for statistics ADs"));
30726 + }
30727 + MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
30728 +
30729 + /* Allocate statistics counters from MURAM */
30730 + h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
30731 + h_FmMuram, p_CcNode->countersArraySize,
30732 + FM_PCD_CC_AD_TABLE_ALIGN);
30733 + if (!h_StatsCounters)
30734 + {
30735 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30736 + FM_MURAM_FreeMem(h_FmMuram, h_StatsAd);
30737 + XX_Free(p_StatsObj);
30738 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30739 + ("MURAM allocation for statistics counters"));
30740 + }
30741 + MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize);
30742 +
30743 + p_StatsObj->h_StatsAd = h_StatsAd;
30744 + p_StatsObj->h_StatsCounters = h_StatsCounters;
30745 +
30746 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
30747 + }
30748 +
30749 + return E_OK;
30750 +}
30751 +
30752 +static t_Error MatchTableGetKeyStatistics(
30753 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
30754 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
30755 +{
30756 + uint32_t *p_StatsCounters, i;
30757 +
30758 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
30759 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30760 + ("Statistics were not enabled for this match table"));
30761 +
30762 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
30763 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30764 + ("Statistics were not enabled for this key"));
30765 +
30766 + memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics));
30767 +
30768 + p_StatsCounters =
30769 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
30770 + ASSERT_COND(p_StatsCounters);
30771 +
30772 + p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters);
30773 +
30774 + for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++)
30775 + {
30776 + p_StatsCounters =
30777 + PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE);
30778 +
30779 + p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters);
30780 +
30781 +#if (DPAA_VERSION >= 11)
30782 + p_KeyStatistics->frameLengthRangeCount[i - 1] =
30783 + GET_UINT32(*p_StatsCounters);
30784 +#endif /* (DPAA_VERSION >= 11) */
30785 + }
30786 +
30787 + return E_OK;
30788 +}
30789 +
30790 +static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode,
30791 + t_FmPcdCcNodeParams *p_CcNodeParam)
30792 +{
30793 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
30794 + t_FmPcdCcNode *p_FmPcdCcNextNode;
30795 + t_Error err = E_OK;
30796 + uint32_t tmp, keySize;
30797 + bool glblMask = FALSE;
30798 + t_FmPcdCcKeyParams *p_KeyParams;
30799 + t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp;
30800 +#if (DPAA_VERSION >= 11)
30801 + t_Handle h_StatsFLRs;
30802 +#endif /* (DPAA_VERSION >= 11) */
30803 + bool fullField = FALSE;
30804 + ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE;
30805 + bool isKeyTblAlloc, fromIc = FALSE;
30806 + uint32_t matchTableSize, adTableSize;
30807 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
30808 + t_FmPcdStatsObj *p_StatsObj;
30809 + t_FmPcdCcStatsParams statsParams = { 0 };
30810 + t_Handle h_Manip;
30811 +
30812 + ASSERT_COND(h_FmPcd);
30813 + ASSERT_COND(p_CcNode);
30814 + ASSERT_COND(p_CcNodeParam);
30815 +
30816 + p_CcNode->p_GlblMask = (t_Handle)XX_Malloc(
30817 + CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30818 + memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30819 +
30820 + p_CcNode->h_FmPcd = h_FmPcd;
30821 + p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
30822 + p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys;
30823 + p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport;
30824 + p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode;
30825 +
30826 + /* For backward compatibility - even if statistics mode is nullified,
30827 + we'll fix it to frame mode so we can support per-key request for
30828 + statistics using 'statisticsEn' in next engine parameters */
30829 + if (!p_CcNode->maxNumOfKeys
30830 + && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE))
30831 + p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME;
30832 +
30833 + h_FmMuram = FmPcdGetMuramHandle(h_FmPcd);
30834 + if (!h_FmMuram)
30835 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30836 +
30837 + INIT_LIST(&p_CcNode->ccPrevNodesLst);
30838 + INIT_LIST(&p_CcNode->ccTreeIdLst);
30839 + INIT_LIST(&p_CcNode->ccTreesLst);
30840 + INIT_LIST(&p_CcNode->availableStatsLst);
30841 +
30842 + p_CcNode->h_Spinlock = XX_InitSpinlock();
30843 + if (!p_CcNode->h_Spinlock)
30844 + {
30845 + DeleteNode(p_CcNode);
30846 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock"));
30847 + }
30848 +
30849 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR)
30850 + && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr
30851 + == HEADER_TYPE_IPv4)
30852 + || (p_CcNodeParam->extractCcParams.extractByHdr.hdr
30853 + == HEADER_TYPE_IPv6))
30854 + && (p_CcNodeParam->extractCcParams.extractByHdr.type
30855 + == e_FM_PCD_EXTRACT_FULL_FIELD)
30856 + && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6
30857 + == NET_HEADER_FIELD_IPv6_HOP_LIMIT)
30858 + || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4
30859 + == NET_HEADER_FIELD_IPv4_TTL)))
30860 + {
30861 + err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30862 + &isKeyTblAlloc);
30863 + glblMask = FALSE;
30864 + }
30865 + else
30866 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR)
30867 + && ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30868 + == e_FM_PCD_EXTRACT_FROM_KEY)
30869 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30870 + == e_FM_PCD_EXTRACT_FROM_HASH)
30871 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30872 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
30873 + {
30874 + if ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30875 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)
30876 + && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
30877 + {
30878 + DeleteNode(p_CcNode);
30879 + RETURN_ERROR(
30880 + MAJOR,
30881 + E_INVALID_VALUE,
30882 + ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0"));
30883 + }
30884 +
30885 + icCode = IcDefineCode(p_CcNodeParam);
30886 + fromIc = TRUE;
30887 + if (icCode == CC_PRIVATE_INFO_NONE)
30888 + {
30889 + DeleteNode(p_CcNode);
30890 + RETURN_ERROR(
30891 + MAJOR,
30892 + E_INVALID_STATE,
30893 + ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way"));
30894 + }
30895 +
30896 + if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP)
30897 + || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
30898 + {
30899 + err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30900 + &isKeyTblAlloc);
30901 + glblMask = TRUE;
30902 + }
30903 + else
30904 + {
30905 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30906 + &isKeyTblAlloc);
30907 + if (p_CcNode->glblMaskSize)
30908 + glblMask = TRUE;
30909 + }
30910 + }
30911 + else
30912 + {
30913 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc);
30914 + if (p_CcNode->glblMaskSize)
30915 + glblMask = TRUE;
30916 + }
30917 +
30918 + if (err)
30919 + {
30920 + DeleteNode(p_CcNode);
30921 + RETURN_ERROR(MAJOR, err, NO_MSG);
30922 + }
30923 +
30924 + switch (p_CcNodeParam->extractCcParams.type)
30925 + {
30926 + case (e_FM_PCD_EXTRACT_BY_HDR):
30927 + switch (p_CcNodeParam->extractCcParams.extractByHdr.type)
30928 + {
30929 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
30930 + p_CcNode->parseCode =
30931 + GetFullFieldParseCode(
30932 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30933 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30934 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
30935 + GetSizeHeaderField(
30936 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30937 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField,
30938 + &p_CcNode->sizeOfExtraction);
30939 + fullField = TRUE;
30940 + if ((p_CcNode->parseCode != CC_PC_FF_TCI1)
30941 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
30942 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
30943 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
30944 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
30945 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
30946 + && (p_CcNode->parseCode
30947 + != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
30948 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
30949 + && (p_CcNode->parseCode
30950 + != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)
30951 + && glblMask)
30952 + {
30953 + glblMask = FALSE;
30954 + p_CcNode->glblMaskSize = 4;
30955 + p_CcNode->lclMask = TRUE;
30956 + }
30957 + break;
30958 +
30959 + case (e_FM_PCD_EXTRACT_FROM_HDR):
30960 + p_CcNode->sizeOfExtraction =
30961 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
30962 + p_CcNode->offset =
30963 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
30964 + p_CcNode->userOffset =
30965 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
30966 + p_CcNode->parseCode =
30967 + GetPrParseCode(
30968 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30969 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30970 + p_CcNode->offset, glblMask,
30971 + &p_CcNode->prsArrayOffset);
30972 + break;
30973 +
30974 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
30975 + p_CcNode->offset =
30976 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
30977 + p_CcNode->userOffset =
30978 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
30979 + p_CcNode->sizeOfExtraction =
30980 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
30981 + p_CcNode->parseCode =
30982 + GetFieldParseCode(
30983 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30984 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
30985 + p_CcNode->offset,
30986 + &p_CcNode->prsArrayOffset,
30987 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
30988 + break;
30989 +
30990 + default:
30991 + DeleteNode(p_CcNode);
30992 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
30993 + }
30994 + break;
30995 +
30996 + case (e_FM_PCD_EXTRACT_NON_HDR):
30997 + /* get the field code for the generic extract */
30998 + p_CcNode->sizeOfExtraction =
30999 + p_CcNodeParam->extractCcParams.extractNonHdr.size;
31000 + p_CcNode->offset =
31001 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
31002 + p_CcNode->userOffset =
31003 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
31004 + p_CcNode->parseCode = GetGenParseCode(
31005 + p_CcNodeParam->extractCcParams.extractNonHdr.src,
31006 + p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset,
31007 + fromIc, icCode);
31008 +
31009 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
31010 + {
31011 + if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8)
31012 + {
31013 + DeleteNode(p_CcNode);
31014 + RETURN_ERROR(
31015 + MAJOR,
31016 + E_INVALID_SELECTION,
31017 + ("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)"));
31018 + }
31019 + }
31020 + if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK)
31021 + || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
31022 + {
31023 + p_CcNode->offset += p_CcNode->prsArrayOffset;
31024 + p_CcNode->prsArrayOffset = 0;
31025 + }
31026 + break;
31027 +
31028 + default:
31029 + DeleteNode(p_CcNode);
31030 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
31031 + }
31032 +
31033 + if (p_CcNode->parseCode == CC_PC_ILLEGAL)
31034 + {
31035 + DeleteNode(p_CcNode);
31036 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type"));
31037 + }
31038 +
31039 + if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY)
31040 + || !p_CcNode->sizeOfExtraction)
31041 + {
31042 + DeleteNode(p_CcNode);
31043 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31044 + ("sizeOfExatrction can not be greater than 56 and not 0"));
31045 + }
31046 +
31047 + if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction)
31048 + {
31049 + DeleteNode(p_CcNode);
31050 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31051 + ("keySize has to be equal to sizeOfExtraction"));
31052 + }
31053 +
31054 + p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction;
31055 +
31056 + if (!glblMask)
31057 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
31058 +
31059 + err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode);
31060 + if (err != E_OK)
31061 + {
31062 + DeleteNode(p_CcNode);
31063 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31064 + ("keySize has to be equal to sizeOfExtraction"));
31065 + }
31066 +
31067 + /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */
31068 + GetCcExtractKeySize(p_CcNode->sizeOfExtraction,
31069 + &p_CcNode->ccKeySizeAccExtraction);
31070 +
31071 + /* If local mask is used, it is stored next to each key in the keys match table */
31072 + if (p_CcNode->lclMask)
31073 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
31074 + else
31075 + keySize = p_CcNode->ccKeySizeAccExtraction;
31076 +
31077 + /* Update CC shadow with maximal size required by this node */
31078 + if (p_CcNode->maxNumOfKeys)
31079 + {
31080 + err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize,
31081 + &adTableSize);
31082 + if (err != E_OK)
31083 + {
31084 + DeleteNode(p_CcNode);
31085 + RETURN_ERROR(MAJOR, err, NO_MSG);
31086 + }
31087 +
31088 + p_CcNode->keysMatchTableMaxSize = matchTableSize;
31089 +
31090 + if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)
31091 + {
31092 + err = AllocStatsObjs(p_CcNode);
31093 + if (err != E_OK)
31094 + {
31095 + DeleteNode(p_CcNode);
31096 + RETURN_ERROR(MAJOR, err, NO_MSG);
31097 + }
31098 + }
31099 +
31100 + /* If manipulation will be initialized before this node, it will use the table
31101 + descriptor in the AD table of previous node and this node will need an extra
31102 + AD as his table descriptor. */
31103 + p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem(
31104 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
31105 + if (!p_CcNode->h_TmpAd)
31106 + {
31107 + DeleteNode(p_CcNode);
31108 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31109 + ("MURAM allocation for CC action descriptor"));
31110 + }
31111 + }
31112 + else
31113 + {
31114 + matchTableSize = (uint32_t)(keySize * sizeof(uint8_t)
31115 + * (p_CcNode->numOfKeys + 1));
31116 + adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE
31117 + * (p_CcNode->numOfKeys + 1));
31118 + }
31119 +
31120 +#if (DPAA_VERSION >= 11)
31121 + switch (p_CcNode->statisticsMode)
31122 + {
31123 +
31124 + case e_FM_PCD_CC_STATS_MODE_RMON:
31125 + /* If RMON statistics or RMON conditional statistics modes are requested,
31126 + allocate frame length ranges array */
31127 + p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem(
31128 + h_FmMuram,
31129 + (uint32_t)(p_CcNode->numOfStatsFLRs)
31130 + * FM_PCD_CC_STATS_FLR_SIZE,
31131 + FM_PCD_CC_AD_TABLE_ALIGN);
31132 +
31133 + if (!p_CcNode->h_StatsFLRs)
31134 + {
31135 + DeleteNode(p_CcNode);
31136 + RETURN_ERROR(
31137 + MAJOR, E_NO_MEMORY,
31138 + ("MURAM allocation for CC frame length ranges array"));
31139 + }
31140 +
31141 + /* Initialize using value received from the user */
31142 + for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++)
31143 + {
31144 + uint16_t flr =
31145 + cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]);
31146 +
31147 + h_StatsFLRs =
31148 + PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE);
31149 +
31150 + MemCpy8(h_StatsFLRs,
31151 + &flr,
31152 + FM_PCD_CC_STATS_FLR_SIZE);
31153 + }
31154 + break;
31155 +
31156 + default:
31157 + break;
31158 + }
31159 +#endif /* (DPAA_VERSION >= 11) */
31160 +
31161 + /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL
31162 + identification, IPv6 hop count identification, etc. */
31163 + if (isKeyTblAlloc)
31164 + {
31165 + p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem(
31166 + h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
31167 + if (!p_CcNode->h_KeysMatchTable)
31168 + {
31169 + DeleteNode(p_CcNode);
31170 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31171 + ("MURAM allocation for CC node key match table"));
31172 + }
31173 + MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize);
31174 + }
31175 +
31176 + /* Allocate action descriptors table */
31177 + p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize,
31178 + FM_PCD_CC_AD_TABLE_ALIGN);
31179 + if (!p_CcNode->h_AdTable)
31180 + {
31181 + DeleteNode(p_CcNode);
31182 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31183 + ("MURAM allocation for CC node action descriptors table"));
31184 + }
31185 + MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize);
31186 +
31187 + p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable;
31188 + p_AdTableTmp = p_CcNode->h_AdTable;
31189 +
31190 + /* For each key, create the key and the next step AD */
31191 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
31192 + {
31193 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
31194 +
31195 + if (p_KeysMatchTblTmp)
31196 + {
31197 + /* Copy the key */
31198 + MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key,
31199 + p_CcNode->sizeOfExtraction);
31200 +
31201 + /* Copy the key mask or initialize it to 0xFF..F */
31202 + if (p_CcNode->lclMask && p_KeyParams->p_Mask)
31203 + {
31204 + MemCpy8(PTR_MOVE(p_KeysMatchTblTmp,
31205 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
31206 + p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
31207 + }
31208 + else
31209 + if (p_CcNode->lclMask)
31210 + {
31211 + MemSet8(PTR_MOVE(p_KeysMatchTblTmp,
31212 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
31213 + 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
31214 + }
31215 +
31216 + p_KeysMatchTblTmp =
31217 + PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t));
31218 + }
31219 +
31220 + /* Create the next action descriptor in the match table */
31221 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
31222 + {
31223 + p_StatsObj = GetStatsObj(p_CcNode);
31224 + ASSERT_COND(p_StatsObj);
31225 +
31226 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31227 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31228 +#if (DPAA_VERSION >= 11)
31229 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
31230 +
31231 +#endif /* (DPAA_VERSION >= 11) */
31232 + NextStepAd(p_AdTableTmp, &statsParams,
31233 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
31234 +
31235 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
31236 + }
31237 + else
31238 + {
31239 + NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams,
31240 + p_FmPcd);
31241 +
31242 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
31243 + }
31244 +
31245 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31246 + }
31247 +
31248 + /* Update next engine for the 'miss' entry */
31249 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn)
31250 + {
31251 + p_StatsObj = GetStatsObj(p_CcNode);
31252 + ASSERT_COND(p_StatsObj);
31253 +
31254 + /* All 'bucket' nodes of a hash table should share the same statistics counters,
31255 + allocated by the hash table. So, if this node is a bucket of a hash table,
31256 + we'll replace the locally allocated counters with the shared counters. */
31257 + if (p_CcNode->isHashBucket)
31258 + {
31259 + ASSERT_COND(p_CcNode->h_MissStatsCounters);
31260 +
31261 + /* Store original counters pointer and replace it with mutual preallocated pointer */
31262 + p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters;
31263 + p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters;
31264 + }
31265 +
31266 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31267 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31268 +#if (DPAA_VERSION >= 11)
31269 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
31270 +
31271 +#endif /* (DPAA_VERSION >= 11) */
31272 +
31273 + NextStepAd(p_AdTableTmp, &statsParams,
31274 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31275 + p_FmPcd);
31276 +
31277 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
31278 + }
31279 + else
31280 + {
31281 + NextStepAd(p_AdTableTmp, NULL,
31282 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31283 + p_FmPcd);
31284 +
31285 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
31286 + }
31287 +
31288 + /* This parameter will be used to initialize the "key length" field in the action descriptor
31289 + that points to this node and it should be 0 for full field extraction */
31290 + if (fullField == TRUE)
31291 + p_CcNode->sizeOfExtraction = 0;
31292 +
31293 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31294 + {
31295 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
31296 + == e_FM_PCD_CC)
31297 + {
31298 + p_FmPcdCcNextNode =
31299 + (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode;
31300 + p_CcInformation = FindNodeInfoInReleventLst(
31301 + &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode,
31302 + p_FmPcdCcNextNode->h_Spinlock);
31303 + if (!p_CcInformation)
31304 + {
31305 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31306 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31307 + ccNodeInfo.index = 1;
31308 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst,
31309 + &ccNodeInfo,
31310 + p_FmPcdCcNextNode->h_Spinlock);
31311 + }
31312 + else
31313 + p_CcInformation->index++;
31314 +
31315 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
31316 + {
31317 + h_Manip =
31318 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip;
31319 + p_CcInformation = FindNodeInfoInReleventLst(
31320 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31321 + (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip));
31322 + if (!p_CcInformation)
31323 + {
31324 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31325 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31326 + ccNodeInfo.index = 1;
31327 + EnqueueNodeInfoToRelevantLst(
31328 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31329 + &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip));
31330 + }
31331 + else
31332 + p_CcInformation->index++;
31333 + }
31334 + }
31335 + }
31336 +
31337 + p_AdTableTmp = p_CcNode->h_AdTable;
31338 +
31339 + if (!FmPcdLockTryLockAll(h_FmPcd))
31340 + {
31341 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31342 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
31343 + return ERROR_CODE(E_BUSY);
31344 + }
31345 +
31346 + /* Required action for each next engine */
31347 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31348 + {
31349 + if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction)
31350 + {
31351 + err = SetRequiredAction(
31352 + h_FmPcd,
31353 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction,
31354 + &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1,
31355 + NULL);
31356 + if (err)
31357 + {
31358 + FmPcdLockUnlockAll(h_FmPcd);
31359 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31360 + RETURN_ERROR(MAJOR, err, NO_MSG);
31361 + }
31362 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31363 + }
31364 + }
31365 +
31366 + FmPcdLockUnlockAll(h_FmPcd);
31367 +
31368 + return E_OK;
31369 +}
31370 +/************************** End of static functions **************************/
31371 +
31372 +/*****************************************************************************/
31373 +/* Inter-module API routines */
31374 +/*****************************************************************************/
31375 +
31376 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info,
31377 + t_Handle h_Spinlock)
31378 +{
31379 + t_CcNodeInformation *p_CcInformation;
31380 + t_List *p_Pos;
31381 + uint32_t intFlags;
31382 +
31383 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31384 +
31385 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31386 + p_Pos = LIST_NEXT(p_Pos))
31387 + {
31388 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31389 +
31390 + ASSERT_COND(p_CcInformation->h_CcNode);
31391 +
31392 + if (p_CcInformation->h_CcNode == h_Info)
31393 + {
31394 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31395 + return p_CcInformation;
31396 + }
31397 + }
31398 +
31399 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31400 +
31401 + return NULL;
31402 +}
31403 +
31404 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo,
31405 + t_Handle h_Spinlock)
31406 +{
31407 + t_CcNodeInformation *p_CcInformation;
31408 + uint32_t intFlags = 0;
31409 +
31410 + p_CcInformation = (t_CcNodeInformation *)XX_Malloc(
31411 + sizeof(t_CcNodeInformation));
31412 +
31413 + if (p_CcInformation)
31414 + {
31415 + memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
31416 + memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
31417 + INIT_LIST(&p_CcInformation->node);
31418 +
31419 + if (h_Spinlock)
31420 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31421 +
31422 + LIST_AddToTail(&p_CcInformation->node, p_List);
31423 +
31424 + if (h_Spinlock)
31425 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31426 + }
31427 + else
31428 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
31429 +}
31430 +
31431 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info,
31432 + t_Handle h_Spinlock)
31433 +{
31434 + t_CcNodeInformation *p_CcInformation = NULL;
31435 + uint32_t intFlags = 0;
31436 + t_List *p_Pos;
31437 +
31438 + if (h_Spinlock)
31439 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31440 +
31441 + if (LIST_IsEmpty(p_List))
31442 + {
31443 + XX_RestoreAllIntr(intFlags);
31444 + return;
31445 + }
31446 +
31447 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31448 + p_Pos = LIST_NEXT(p_Pos))
31449 + {
31450 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31451 + ASSERT_COND(p_CcInformation);
31452 + ASSERT_COND(p_CcInformation->h_CcNode);
31453 + if (p_CcInformation->h_CcNode == h_Info)
31454 + break;
31455 + }
31456 +
31457 + if (p_CcInformation)
31458 + {
31459 + LIST_DelAndInit(&p_CcInformation->node);
31460 + XX_Free(p_CcInformation);
31461 + }
31462 +
31463 + if (h_Spinlock)
31464 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31465 +}
31466 +
31467 +void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
31468 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
31469 + t_FmPcd *p_FmPcd)
31470 +{
31471 + switch (p_FmPcdCcNextEngineParams->nextEngine)
31472 + {
31473 + case (e_FM_PCD_KG):
31474 + case (e_FM_PCD_PLCR):
31475 + case (e_FM_PCD_DONE):
31476 + /* if NIA is not CC, create a "result" type AD */
31477 + FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31478 + p_FmPcdCcNextEngineParams);
31479 + break;
31480 +#if (DPAA_VERSION >= 11)
31481 + case (e_FM_PCD_FR):
31482 + if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
31483 + {
31484 + FillAdOfTypeContLookup(
31485 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31486 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31487 + p_FmPcdCcNextEngineParams->h_Manip,
31488 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
31489 + FrmReplicGroupUpdateOwner(
31490 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic,
31491 + TRUE/* add */);
31492 + }
31493 + break;
31494 +#endif /* (DPAA_VERSION >= 11) */
31495 +
31496 + case (e_FM_PCD_CC):
31497 + /* if NIA is not CC, create a TD to continue the CC lookup */
31498 + FillAdOfTypeContLookup(
31499 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31500 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31501 + p_FmPcdCcNextEngineParams->h_Manip, NULL);
31502 +
31503 + UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31504 + TRUE);
31505 + break;
31506 +
31507 + default:
31508 + return;
31509 + }
31510 +}
31511 +
31512 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31513 + t_Handle h_NetEnv, t_Handle h_IpReassemblyManip,
31514 + bool createSchemes)
31515 +{
31516 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31517 + t_FmPcdCcNextEngineParams nextEngineParams;
31518 + t_NetEnvParams netEnvParams;
31519 + t_Handle h_Ad;
31520 + bool isIpv6Present;
31521 + uint8_t ipv4GroupId, ipv6GroupId;
31522 + t_Error err;
31523 +
31524 + ASSERT_COND(p_FmPcdCcTree);
31525 +
31526 + /* this routine must be protected by the calling routine! */
31527 +
31528 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31529 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31530 +
31531 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31532 +
31533 + isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip);
31534 +
31535 + if (isIpv6Present
31536 + && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2)))
31537 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31538 +
31539 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31540 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31541 +
31542 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31543 + nextEngineParams.h_Manip = h_IpReassemblyManip;
31544 +
31545 + /* Lock tree */
31546 + err = CcRootTryLock(p_FmPcdCcTree);
31547 + if (err)
31548 + return ERROR_CODE(E_BUSY);
31549 +
31550 + if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip)
31551 + {
31552 + CcRootReleaseLock(p_FmPcdCcTree);
31553 + return E_OK;
31554 + }
31555 +
31556 + if ((p_FmPcdCcTree->h_IpReassemblyManip)
31557 + && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip))
31558 + {
31559 + CcRootReleaseLock(p_FmPcdCcTree);
31560 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31561 + ("This tree was previously updated with different IPR"));
31562 + }
31563 +
31564 + /* Initialize IPR for the first time for this tree */
31565 + if (isIpv6Present)
31566 + {
31567 + ipv6GroupId = p_FmPcdCcTree->numOfGrps++;
31568 + p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry =
31569 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2);
31570 +
31571 + if (createSchemes)
31572 + {
31573 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv,
31574 + p_FmPcdCcTree,
31575 + h_IpReassemblyManip, FALSE,
31576 + ipv6GroupId);
31577 + if (err)
31578 + {
31579 + p_FmPcdCcTree->numOfGrps--;
31580 + CcRootReleaseLock(p_FmPcdCcTree);
31581 + RETURN_ERROR(MAJOR, err, NO_MSG);
31582 + }
31583 + }
31584 +
31585 + NextStepAd(
31586 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE),
31587 + NULL, &nextEngineParams, h_FmPcd);
31588 + }
31589 +
31590 + ipv4GroupId = p_FmPcdCcTree->numOfGrps++;
31591 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0;
31592 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry =
31593 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31594 +
31595 + if (createSchemes)
31596 + {
31597 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree,
31598 + h_IpReassemblyManip, TRUE,
31599 + ipv4GroupId);
31600 + if (err)
31601 + {
31602 + p_FmPcdCcTree->numOfGrps--;
31603 + if (isIpv6Present)
31604 + {
31605 + p_FmPcdCcTree->numOfGrps--;
31606 + FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip);
31607 + }
31608 + CcRootReleaseLock(p_FmPcdCcTree);
31609 + RETURN_ERROR(MAJOR, err, NO_MSG);
31610 + }
31611 + }
31612 +
31613 + NextStepAd(
31614 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31615 + NULL, &nextEngineParams, h_FmPcd);
31616 +
31617 + p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip;
31618 +
31619 + CcRootReleaseLock(p_FmPcdCcTree);
31620 +
31621 + return E_OK;
31622 +}
31623 +
31624 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31625 + t_Handle h_NetEnv, t_Handle h_ReassemblyManip,
31626 + bool createSchemes)
31627 +{
31628 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31629 + t_FmPcdCcNextEngineParams nextEngineParams;
31630 + t_NetEnvParams netEnvParams;
31631 + t_Handle h_Ad;
31632 + uint8_t groupId;
31633 + t_Error err;
31634 +
31635 + ASSERT_COND(p_FmPcdCcTree);
31636 +
31637 + /* this routine must be protected by the calling routine! */
31638 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31639 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31640 +
31641 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31642 +
31643 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31644 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR"));
31645 +
31646 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31647 + nextEngineParams.h_Manip = h_ReassemblyManip;
31648 +
31649 + /* Lock tree */
31650 + err = CcRootTryLock(p_FmPcdCcTree);
31651 + if (err)
31652 + return ERROR_CODE(E_BUSY);
31653 +
31654 + if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip)
31655 + {
31656 + CcRootReleaseLock(p_FmPcdCcTree);
31657 + return E_OK;
31658 + }
31659 +
31660 + if ((p_FmPcdCcTree->h_CapwapReassemblyManip)
31661 + && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip))
31662 + {
31663 + CcRootReleaseLock(p_FmPcdCcTree);
31664 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31665 + ("This tree was previously updated with different CPR"));
31666 + }
31667 +
31668 + groupId = p_FmPcdCcTree->numOfGrps++;
31669 + p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry =
31670 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31671 +
31672 + if (createSchemes)
31673 + {
31674 + err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv,
31675 + p_FmPcdCcTree,
31676 + h_ReassemblyManip, groupId);
31677 + if (err)
31678 + {
31679 + p_FmPcdCcTree->numOfGrps--;
31680 + CcRootReleaseLock(p_FmPcdCcTree);
31681 + RETURN_ERROR(MAJOR, err, NO_MSG);
31682 + }
31683 + }
31684 +
31685 + NextStepAd(
31686 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31687 + NULL, &nextEngineParams, h_FmPcd);
31688 +
31689 + p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip;
31690 +
31691 + CcRootReleaseLock(p_FmPcdCcTree);
31692 +
31693 + return E_OK;
31694 +}
31695 +
31696 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree)
31697 +{
31698 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31699 +
31700 + ASSERT_COND(p_FmPcdCcTree);
31701 +
31702 + return p_FmPcdCcTree->h_FmPcdCcSavedManipParams;
31703 +}
31704 +
31705 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree,
31706 + t_Handle h_SavedManipParams)
31707 +{
31708 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31709 +
31710 + ASSERT_COND(p_FmPcdCcTree);
31711 +
31712 + p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams;
31713 +}
31714 +
31715 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
31716 +{
31717 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31718 +
31719 + ASSERT_COND(p_CcNode);
31720 +
31721 + return p_CcNode->parseCode;
31722 +}
31723 +
31724 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
31725 +{
31726 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31727 +
31728 + ASSERT_COND(p_CcNode);
31729 +
31730 + return p_CcNode->offset;
31731 +}
31732 +
31733 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
31734 +{
31735 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31736 +
31737 + ASSERT_COND(p_CcNode);
31738 +
31739 + return p_CcNode->numOfKeys;
31740 +}
31741 +
31742 +t_Error FmPcdCcModifyNextEngineParamTree(
31743 + t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index,
31744 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31745 +{
31746 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
31747 + t_FmPcd *p_FmPcd;
31748 + t_List h_OldPointersLst, h_NewPointersLst;
31749 + uint16_t keyIndex;
31750 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31751 + t_Error err = E_OK;
31752 +
31753 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
31754 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
31755 + SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE);
31756 +
31757 + if (grpId >= p_FmPcdCcTree->numOfGrps)
31758 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
31759 + ("grpId you asked > numOfGroup of relevant tree"));
31760 +
31761 + if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
31762 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
31763 +
31764 + p_FmPcd = (t_FmPcd *)h_FmPcd;
31765 +
31766 + INIT_LIST(&h_OldPointersLst);
31767 + INIT_LIST(&h_NewPointersLst);
31768 +
31769 + keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry
31770 + + index);
31771 +
31772 + p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex,
31773 + e_MODIFY_STATE_CHANGE, FALSE,
31774 + FALSE, TRUE);
31775 + if (!p_ModifyKeyParams)
31776 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31777 +
31778 + p_ModifyKeyParams->tree = TRUE;
31779 +
31780 + if (p_FmPcd->p_CcShadow
31781 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31782 + {
31783 + XX_Free(p_ModifyKeyParams);
31784 + return ERROR_CODE(E_BUSY);
31785 + }
31786 +
31787 + err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex,
31788 + p_FmPcdCcNextEngineParams,
31789 + &h_OldPointersLst, &h_NewPointersLst,
31790 + p_ModifyKeyParams);
31791 + if (err)
31792 + {
31793 + XX_Free(p_ModifyKeyParams);
31794 + RETURN_ERROR(MAJOR, err, NO_MSG);
31795 + }
31796 +
31797 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31798 + p_ModifyKeyParams, FALSE);
31799 +
31800 + if (p_FmPcd->p_CcShadow)
31801 + RELEASE_LOCK(p_FmPcd->shadowLock);
31802 +
31803 + ReleaseLst(&h_OldPointersLst);
31804 + ReleaseLst(&h_NewPointersLst);
31805 +
31806 + return err;
31807 +
31808 +}
31809 +
31810 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31811 + uint16_t keyIndex)
31812 +{
31813 +
31814 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31815 + t_FmPcd *p_FmPcd;
31816 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31817 + t_List h_OldPointersLst, h_NewPointersLst;
31818 + bool useShadowStructs = FALSE;
31819 + t_Error err = E_OK;
31820 +
31821 + if (keyIndex >= p_CcNode->numOfKeys)
31822 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31823 + ("impossible to remove key when numOfKeys <= keyIndex"));
31824 +
31825 + if (p_CcNode->h_FmPcd != h_FmPcd)
31826 + RETURN_ERROR(
31827 + MAJOR,
31828 + E_INVALID_VALUE,
31829 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31830 +
31831 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31832 +
31833 + INIT_LIST(&h_OldPointersLst);
31834 + INIT_LIST(&h_NewPointersLst);
31835 +
31836 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31837 + e_MODIFY_STATE_REMOVE, TRUE, TRUE,
31838 + FALSE);
31839 + if (!p_ModifyKeyParams)
31840 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31841 +
31842 + if (p_CcNode->maxNumOfKeys)
31843 + {
31844 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31845 + {
31846 + XX_Free(p_ModifyKeyParams);
31847 + return ERROR_CODE(E_BUSY);
31848 + }
31849 +
31850 + useShadowStructs = TRUE;
31851 + }
31852 +
31853 + err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams);
31854 + if (err)
31855 + {
31856 + XX_Free(p_ModifyKeyParams);
31857 + if (p_CcNode->maxNumOfKeys)
31858 + RELEASE_LOCK(p_FmPcd->shadowLock);
31859 + RETURN_ERROR(MAJOR, err, NO_MSG);
31860 + }
31861 +
31862 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31863 + &h_OldPointersLst,
31864 + &h_NewPointersLst);
31865 + if (err)
31866 + {
31867 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31868 + XX_Free(p_ModifyKeyParams);
31869 + if (p_CcNode->maxNumOfKeys)
31870 + RELEASE_LOCK(p_FmPcd->shadowLock);
31871 + RETURN_ERROR(MAJOR, err, NO_MSG);
31872 + }
31873 +
31874 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31875 + p_ModifyKeyParams, useShadowStructs);
31876 +
31877 + if (p_CcNode->maxNumOfKeys)
31878 + RELEASE_LOCK(p_FmPcd->shadowLock);
31879 +
31880 + ReleaseLst(&h_OldPointersLst);
31881 + ReleaseLst(&h_NewPointersLst);
31882 +
31883 + return err;
31884 +}
31885 +
31886 +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31887 + uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key,
31888 + uint8_t *p_Mask)
31889 +{
31890 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31891 + t_FmPcd *p_FmPcd;
31892 + t_List h_OldPointersLst, h_NewPointersLst;
31893 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31894 + uint16_t tmpKeyIndex;
31895 + bool useShadowStructs = FALSE;
31896 + t_Error err = E_OK;
31897 +
31898 + if (keyIndex >= p_CcNode->numOfKeys)
31899 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31900 + ("keyIndex > previously cleared last index + 1"));
31901 +
31902 + if (keySize != p_CcNode->userSizeOfExtraction)
31903 + RETURN_ERROR(
31904 + MAJOR,
31905 + E_INVALID_VALUE,
31906 + ("size for ModifyKey has to be the same as defined in SetNode"));
31907 +
31908 + if (p_CcNode->h_FmPcd != h_FmPcd)
31909 + RETURN_ERROR(
31910 + MAJOR,
31911 + E_INVALID_VALUE,
31912 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31913 +
31914 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex);
31915 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31916 + RETURN_ERROR(
31917 + MINOR,
31918 + E_ALREADY_EXISTS,
31919 + ("The received key and mask pair was already found in the match table of the provided node"));
31920 +
31921 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31922 +
31923 + INIT_LIST(&h_OldPointersLst);
31924 + INIT_LIST(&h_NewPointersLst);
31925 +
31926 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31927 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
31928 + FALSE);
31929 + if (!p_ModifyKeyParams)
31930 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31931 +
31932 + if (p_CcNode->maxNumOfKeys)
31933 + {
31934 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31935 + {
31936 + XX_Free(p_ModifyKeyParams);
31937 + return ERROR_CODE(E_BUSY);
31938 + }
31939 +
31940 + useShadowStructs = TRUE;
31941 + }
31942 +
31943 + err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask,
31944 + p_ModifyKeyParams);
31945 + if (err)
31946 + {
31947 + XX_Free(p_ModifyKeyParams);
31948 + if (p_CcNode->maxNumOfKeys)
31949 + RELEASE_LOCK(p_FmPcd->shadowLock);
31950 + RETURN_ERROR(MAJOR, err, NO_MSG);
31951 + }
31952 +
31953 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31954 + &h_OldPointersLst,
31955 + &h_NewPointersLst);
31956 + if (err)
31957 + {
31958 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31959 + XX_Free(p_ModifyKeyParams);
31960 + if (p_CcNode->maxNumOfKeys)
31961 + RELEASE_LOCK(p_FmPcd->shadowLock);
31962 + RETURN_ERROR(MAJOR, err, NO_MSG);
31963 + }
31964 +
31965 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31966 + p_ModifyKeyParams, useShadowStructs);
31967 +
31968 + if (p_CcNode->maxNumOfKeys)
31969 + RELEASE_LOCK(p_FmPcd->shadowLock);
31970 +
31971 + ReleaseLst(&h_OldPointersLst);
31972 + ReleaseLst(&h_NewPointersLst);
31973 +
31974 + return err;
31975 +}
31976 +
31977 +t_Error FmPcdCcModifyMissNextEngineParamNode(
31978 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31979 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31980 +{
31981 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31982 + t_FmPcd *p_FmPcd;
31983 + t_List h_OldPointersLst, h_NewPointersLst;
31984 + uint16_t keyIndex;
31985 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31986 + t_Error err = E_OK;
31987 +
31988 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE);
31989 +
31990 + keyIndex = p_CcNode->numOfKeys;
31991 +
31992 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31993 +
31994 + INIT_LIST(&h_OldPointersLst);
31995 + INIT_LIST(&h_NewPointersLst);
31996 +
31997 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31998 + e_MODIFY_STATE_CHANGE, FALSE, TRUE,
31999 + FALSE);
32000 + if (!p_ModifyKeyParams)
32001 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32002 +
32003 + if (p_CcNode->maxNumOfKeys
32004 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
32005 + {
32006 + XX_Free(p_ModifyKeyParams);
32007 + return ERROR_CODE(E_BUSY);
32008 + }
32009 +
32010 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
32011 + p_FmPcdCcNextEngineParams,
32012 + &h_OldPointersLst, &h_NewPointersLst,
32013 + p_ModifyKeyParams);
32014 + if (err)
32015 + {
32016 + XX_Free(p_ModifyKeyParams);
32017 + if (p_CcNode->maxNumOfKeys)
32018 + RELEASE_LOCK(p_FmPcd->shadowLock);
32019 + RETURN_ERROR(MAJOR, err, NO_MSG);
32020 + }
32021 +
32022 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32023 + p_ModifyKeyParams, FALSE);
32024 +
32025 + if (p_CcNode->maxNumOfKeys)
32026 + RELEASE_LOCK(p_FmPcd->shadowLock);
32027 +
32028 + ReleaseLst(&h_OldPointersLst);
32029 + ReleaseLst(&h_NewPointersLst);
32030 +
32031 + return err;
32032 +}
32033 +
32034 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32035 + uint16_t keyIndex, uint8_t keySize,
32036 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
32037 +{
32038 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32039 + t_FmPcd *p_FmPcd;
32040 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
32041 + t_List h_OldPointersLst, h_NewPointersLst;
32042 + bool useShadowStructs = FALSE;
32043 + uint16_t tmpKeyIndex;
32044 + t_Error err = E_OK;
32045 +
32046 + if (keyIndex > p_CcNode->numOfKeys)
32047 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
32048 + ("keyIndex > previously cleared last index + 1"));
32049 +
32050 + if (keySize != p_CcNode->userSizeOfExtraction)
32051 + RETURN_ERROR(
32052 + MAJOR,
32053 + E_INVALID_VALUE,
32054 + ("keySize has to be defined as it was defined in initialization step"));
32055 +
32056 + if (p_CcNode->h_FmPcd != h_FmPcd)
32057 + RETURN_ERROR(
32058 + MAJOR,
32059 + E_INVALID_VALUE,
32060 + ("handler to FmPcd is different from the handle provided at node initialization time"));
32061 +
32062 + if (p_CcNode->maxNumOfKeys)
32063 + {
32064 + if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys)
32065 + RETURN_ERROR(
32066 + MAJOR,
32067 + E_FULL,
32068 + ("number of keys exceeds the maximal number of keys provided at node initialization time"));
32069 + }
32070 + else
32071 + if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS)
32072 + RETURN_ERROR(
32073 + MAJOR,
32074 + E_INVALID_VALUE,
32075 + ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS));
32076 +
32077 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
32078 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
32079 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
32080 + RETURN_ERROR(
32081 + MAJOR,
32082 + E_ALREADY_EXISTS,
32083 + ("The received key and mask pair was already found in the match table of the provided node"));
32084 +
32085 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32086 +
32087 + INIT_LIST(&h_OldPointersLst);
32088 + INIT_LIST(&h_NewPointersLst);
32089 +
32090 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
32091 + e_MODIFY_STATE_ADD, TRUE, TRUE,
32092 + FALSE);
32093 + if (!p_ModifyKeyParams)
32094 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32095 +
32096 + if (p_CcNode->maxNumOfKeys)
32097 + {
32098 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
32099 + {
32100 + XX_Free(p_ModifyKeyParams);
32101 + return ERROR_CODE(E_BUSY);
32102 + }
32103 +
32104 + useShadowStructs = TRUE;
32105 + }
32106 +
32107 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
32108 + p_FmPcdCcKeyParams,
32109 + p_ModifyKeyParams, TRUE);
32110 + if (err)
32111 + {
32112 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32113 + XX_Free(p_ModifyKeyParams);
32114 + if (p_CcNode->maxNumOfKeys)
32115 + RELEASE_LOCK(p_FmPcd->shadowLock);
32116 + RETURN_ERROR(MAJOR, err, NO_MSG);
32117 + }
32118 +
32119 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
32120 + &h_OldPointersLst,
32121 + &h_NewPointersLst);
32122 + if (err)
32123 + {
32124 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32125 + XX_Free(p_ModifyKeyParams);
32126 + if (p_CcNode->maxNumOfKeys)
32127 + RELEASE_LOCK(p_FmPcd->shadowLock);
32128 + RETURN_ERROR(MAJOR, err, NO_MSG);
32129 + }
32130 +
32131 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32132 + p_ModifyKeyParams, useShadowStructs);
32133 + if (p_CcNode->maxNumOfKeys)
32134 + RELEASE_LOCK(p_FmPcd->shadowLock);
32135 +
32136 + ReleaseLst(&h_OldPointersLst);
32137 + ReleaseLst(&h_NewPointersLst);
32138 +
32139 + return err;
32140 +}
32141 +
32142 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32143 + uint16_t keyIndex, uint8_t keySize,
32144 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
32145 +{
32146 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32147 + t_FmPcd *p_FmPcd;
32148 + t_List h_OldPointersLst, h_NewPointersLst;
32149 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
32150 + uint16_t tmpKeyIndex;
32151 + bool useShadowStructs = FALSE;
32152 + t_Error err = E_OK;
32153 +
32154 + if (keyIndex > p_CcNode->numOfKeys)
32155 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
32156 + ("keyIndex > previously cleared last index + 1"));
32157 +
32158 + if (keySize != p_CcNode->userSizeOfExtraction)
32159 + RETURN_ERROR(
32160 + MAJOR,
32161 + E_INVALID_VALUE,
32162 + ("keySize has to be defined as it was defined in initialization step"));
32163 +
32164 + if (p_CcNode->h_FmPcd != h_FmPcd)
32165 + RETURN_ERROR(
32166 + MAJOR,
32167 + E_INVALID_VALUE,
32168 + ("handler to FmPcd is different from the handle provided at node initialization time"));
32169 +
32170 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
32171 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
32172 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
32173 + RETURN_ERROR(
32174 + MINOR,
32175 + E_ALREADY_EXISTS,
32176 + ("The received key and mask pair was already found in the match table of the provided node"));
32177 +
32178 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32179 +
32180 + INIT_LIST(&h_OldPointersLst);
32181 + INIT_LIST(&h_NewPointersLst);
32182 +
32183 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
32184 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
32185 + FALSE);
32186 + if (!p_ModifyKeyParams)
32187 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32188 +
32189 + if (p_CcNode->maxNumOfKeys)
32190 + {
32191 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
32192 + {
32193 + XX_Free(p_ModifyKeyParams);
32194 + return ERROR_CODE(E_BUSY);
32195 + }
32196 +
32197 + useShadowStructs = TRUE;
32198 + }
32199 +
32200 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
32201 + p_FmPcdCcKeyParams,
32202 + p_ModifyKeyParams, FALSE);
32203 + if (err)
32204 + {
32205 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32206 + XX_Free(p_ModifyKeyParams);
32207 + if (p_CcNode->maxNumOfKeys)
32208 + RELEASE_LOCK(p_FmPcd->shadowLock);
32209 + RETURN_ERROR(MAJOR, err, NO_MSG);
32210 + }
32211 +
32212 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
32213 + &h_OldPointersLst,
32214 + &h_NewPointersLst);
32215 + if (err)
32216 + {
32217 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32218 + XX_Free(p_ModifyKeyParams);
32219 + if (p_CcNode->maxNumOfKeys)
32220 + RELEASE_LOCK(p_FmPcd->shadowLock);
32221 + RETURN_ERROR(MAJOR, err, NO_MSG);
32222 + }
32223 +
32224 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32225 + p_ModifyKeyParams, useShadowStructs);
32226 +
32227 + if (p_CcNode->maxNumOfKeys)
32228 + RELEASE_LOCK(p_FmPcd->shadowLock);
32229 +
32230 + ReleaseLst(&h_OldPointersLst);
32231 + ReleaseLst(&h_NewPointersLst);
32232 +
32233 + return err;
32234 +}
32235 +
32236 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd,
32237 + t_Handle h_Pointer)
32238 +{
32239 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32240 + t_CcNodeInformation *p_CcNodeInfo;
32241 +
32242 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE,
32243 + (uint32_t)ILLEGAL_BASE);
32244 +
32245 + p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
32246 +
32247 + return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode)
32248 + - p_FmPcd->physicalMuramBase);
32249 +}
32250 +
32251 +t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId,
32252 + uint32_t *p_GrpBits, uint8_t *p_GrpBase)
32253 +{
32254 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32255 +
32256 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32257 +
32258 + if (grpId >= p_FmPcdCcTree->numOfGrps)
32259 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
32260 + ("grpId you asked > numOfGroup of relevant tree"));
32261 +
32262 + *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
32263 + *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
32264 +
32265 + return E_OK;
32266 +}
32267 +
32268 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams,
32269 + t_Handle h_FmPcdCcTree, uint32_t *p_Offset,
32270 + t_Handle h_FmPort)
32271 +{
32272 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
32273 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32274 + t_Error err = E_OK;
32275 +
32276 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
32277 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32278 +
32279 + /* this routine must be protected by the calling routine by locking all PCD modules! */
32280 +
32281 + err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE);
32282 +
32283 + if (err == E_OK)
32284 + UpdateCcRootOwner(p_FmPcdCcTree, TRUE);
32285 +
32286 + *p_Offset = (uint32_t)(XX_VirtToPhys(
32287 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr))
32288 + - p_FmPcd->physicalMuramBase);
32289 +
32290 + return err;
32291 +}
32292 +
32293 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree)
32294 +{
32295 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32296 +
32297 + /* this routine must be protected by the calling routine by locking all PCD modules! */
32298 +
32299 + UNUSED(h_FmPcd);
32300 +
32301 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32302 +
32303 + UpdateCcRootOwner(p_FmPcdCcTree, FALSE);
32304 +
32305 + return E_OK;
32306 +}
32307 +
32308 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32309 + t_List *p_List)
32310 +{
32311 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32312 + t_List *p_Pos, *p_Tmp;
32313 + t_CcNodeInformation *p_CcNodeInfo, nodeInfo;
32314 + uint32_t intFlags;
32315 + t_Error err = E_OK;
32316 +
32317 + intFlags = FmPcdLock(h_FmPcd);
32318 +
32319 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
32320 + {
32321 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32322 + ASSERT_COND(p_CcNodeInfo->h_CcNode);
32323 +
32324 + err = CcRootTryLock(p_CcNodeInfo->h_CcNode);
32325 +
32326 + if (err)
32327 + {
32328 + LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst)
32329 + {
32330 + if (p_Tmp == p_Pos)
32331 + break;
32332 +
32333 + CcRootReleaseLock(p_CcNodeInfo->h_CcNode);
32334 + }
32335 + break;
32336 + }
32337 +
32338 + memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
32339 + nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
32340 + EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL);
32341 + }
32342 +
32343 + FmPcdUnlock(h_FmPcd, intFlags);
32344 + CORE_MemoryBarrier();
32345 +
32346 + return err;
32347 +}
32348 +
32349 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List)
32350 +{
32351 + t_List *p_Pos;
32352 + t_CcNodeInformation *p_CcNodeInfo;
32353 + t_Handle h_FmPcdCcTree;
32354 + uint32_t intFlags;
32355 +
32356 + intFlags = FmPcdLock(h_FmPcd);
32357 +
32358 + LIST_FOR_EACH(p_Pos, p_List)
32359 + {
32360 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32361 + h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
32362 + CcRootReleaseLock(h_FmPcdCcTree);
32363 + }
32364 +
32365 + ReleaseLst(p_List);
32366 +
32367 + FmPcdUnlock(h_FmPcd, intFlags);
32368 + CORE_MemoryBarrier();
32369 +}
32370 +
32371 +t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align)
32372 +{
32373 + uint32_t intFlags;
32374 + uint32_t newSize = 0, newAlign = 0;
32375 + bool allocFail = FALSE;
32376 +
32377 + ASSERT_COND(p_FmPcd);
32378 +
32379 + if (!size)
32380 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0"));
32381 +
32382 + if (!POWER_OF_2(align))
32383 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2"));
32384 +
32385 + newSize = p_FmPcd->ccShadowSize;
32386 + newAlign = p_FmPcd->ccShadowAlign;
32387 +
32388 + /* Check if current shadow is large enough to hold the requested size */
32389 + if (size > p_FmPcd->ccShadowSize)
32390 + newSize = size;
32391 +
32392 + /* Check if current shadow matches the requested alignment */
32393 + if (align > p_FmPcd->ccShadowAlign)
32394 + newAlign = align;
32395 +
32396 + /* If a bigger shadow size or bigger shadow alignment are required,
32397 + a new shadow will be allocated */
32398 + if ((newSize != p_FmPcd->ccShadowSize)
32399 + || (newAlign != p_FmPcd->ccShadowAlign))
32400 + {
32401 + intFlags = FmPcdLock(p_FmPcd);
32402 +
32403 + if (p_FmPcd->p_CcShadow)
32404 + {
32405 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow);
32406 + p_FmPcd->ccShadowSize = 0;
32407 + p_FmPcd->ccShadowAlign = 0;
32408 + }
32409 +
32410 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
32411 + newSize, newAlign);
32412 + if (!p_FmPcd->p_CcShadow)
32413 + {
32414 + allocFail = TRUE;
32415 +
32416 + /* If new shadow size allocation failed,
32417 + re-allocate with previous parameters */
32418 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(
32419 + FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize,
32420 + p_FmPcd->ccShadowAlign);
32421 + }
32422 +
32423 + FmPcdUnlock(p_FmPcd, intFlags);
32424 +
32425 + if (allocFail)
32426 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32427 + ("MURAM allocation for CC Shadow memory"));
32428 +
32429 + p_FmPcd->ccShadowSize = newSize;
32430 + p_FmPcd->ccShadowAlign = newAlign;
32431 + }
32432 +
32433 + return E_OK;
32434 +}
32435 +
32436 +#if (DPAA_VERSION >= 11)
32437 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
32438 + t_Handle h_ReplicGroup,
32439 + t_List *p_AdTables,
32440 + uint32_t *p_NumOfAdTables)
32441 +{
32442 + t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node;
32443 + int i = 0;
32444 + void * p_AdTable;
32445 + t_CcNodeInformation ccNodeInfo;
32446 +
32447 + ASSERT_COND(h_Node);
32448 + *p_NumOfAdTables = 0;
32449 +
32450 + /* search in the current node which exact index points on this current replicator group for getting AD */
32451 + for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++)
32452 + {
32453 + if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32454 + == e_FM_PCD_FR)
32455 + && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic
32456 + == (t_Handle)h_ReplicGroup)))
32457 + {
32458 + /* save the current ad table in the list */
32459 + /* this entry uses the input replicator group */
32460 + p_AdTable =
32461 + PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
32462 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32463 + ccNodeInfo.h_CcNode = p_AdTable;
32464 + EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL);
32465 + (*p_NumOfAdTables)++;
32466 + }
32467 + }
32468 +
32469 + ASSERT_COND(i != p_CurrentNode->numOfKeys);
32470 +}
32471 +#endif /* (DPAA_VERSION >= 11) */
32472 +/*********************** End of inter-module routines ************************/
32473 +
32474 +/****************************************/
32475 +/* API Init unit functions */
32476 +/****************************************/
32477 +
32478 +t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd,
32479 + t_FmPcdCcTreeParams *p_PcdGroupsParam)
32480 +{
32481 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32482 + t_Error err = E_OK;
32483 + int i = 0, j = 0, k = 0;
32484 + t_FmPcdCcTree *p_FmPcdCcTree;
32485 + uint8_t numOfEntries;
32486 + t_Handle p_CcTreeTmp;
32487 + t_FmPcdCcGrpParams *p_FmPcdCcGroupParams;
32488 + t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams;
32489 + t_NetEnvParams netEnvParams;
32490 + uint8_t lastOne = 0;
32491 + uint32_t requiredAction = 0;
32492 + t_FmPcdCcNode *p_FmPcdCcNextNode;
32493 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
32494 +
32495 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32496 + SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL);
32497 +
32498 + if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32499 + {
32500 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32501 + return NULL;
32502 + }
32503 +
32504 + p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
32505 + if (!p_FmPcdCcTree)
32506 + {
32507 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
32508 + return NULL;
32509 + }
32510 + memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree));
32511 + p_FmPcdCcTree->h_FmPcd = h_FmPcd;
32512 +
32513 + p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc(
32514 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32515 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32516 + memset(p_Params,
32517 + 0,
32518 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32519 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32520 +
32521 + INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
32522 +
32523 +#ifdef FM_CAPWAP_SUPPORT
32524 + if ((p_PcdGroupsParam->numOfGrps == 1) &&
32525 + (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) &&
32526 + (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) &&
32527 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode &&
32528 + IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode))
32529 + {
32530 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild();
32531 + if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip)
32532 + {
32533 + DeleteTree(p_FmPcdCcTree,p_FmPcd);
32534 + XX_Free(p_Params);
32535 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32536 + return NULL;
32537 + }
32538 + }
32539 +#endif /* FM_CAPWAP_SUPPORT */
32540 +
32541 + numOfEntries = 0;
32542 + p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv);
32543 +
32544 + for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
32545 + {
32546 + p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
32547 +
32548 + if (p_FmPcdCcGroupParams->numOfDistinctionUnits
32549 + > FM_PCD_MAX_NUM_OF_CC_UNITS)
32550 + {
32551 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32552 + XX_Free(p_Params);
32553 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
32554 + ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
32555 + return NULL;
32556 + }
32557 +
32558 + p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
32559 + p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01
32560 + << p_FmPcdCcGroupParams->numOfDistinctionUnits);
32561 + numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32562 + if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32563 + {
32564 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32565 + XX_Free(p_Params);
32566 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32567 + return NULL;
32568 + }
32569 +
32570 + if (lastOne)
32571 + {
32572 + if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
32573 + {
32574 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32575 + XX_Free(p_Params);
32576 + REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
32577 + return NULL;
32578 + }
32579 + }
32580 +
32581 + lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32582 +
32583 + netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
32584 + netEnvParams.numOfDistinctionUnits =
32585 + p_FmPcdCcGroupParams->numOfDistinctionUnits;
32586 +
32587 + memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds,
32588 + (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
32589 +
32590 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
32591 + if (err)
32592 + {
32593 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32594 + XX_Free(p_Params);
32595 + REPORT_ERROR(MAJOR, err, NO_MSG);
32596 + return NULL;
32597 + }
32598 +
32599 + p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
32600 + for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32601 + j++)
32602 + {
32603 + err = ValidateNextEngineParams(
32604 + h_FmPcd,
32605 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32606 + e_FM_PCD_CC_STATS_MODE_NONE);
32607 + if (err)
32608 + {
32609 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32610 + XX_Free(p_Params);
32611 + REPORT_ERROR(MAJOR, err, (NO_MSG));
32612 + return NULL;
32613 + }
32614 +
32615 + if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
32616 + {
32617 + err = FmPcdManipCheckParamsForCcNextEngine(
32618 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32619 + &requiredAction);
32620 + if (err)
32621 + {
32622 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32623 + XX_Free(p_Params);
32624 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32625 + return NULL;
32626 + }
32627 + }
32628 + p_KeyAndNextEngineParams = p_Params + k;
32629 +
32630 + memcpy(&p_KeyAndNextEngineParams->nextEngineParams,
32631 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32632 + sizeof(t_FmPcdCcNextEngineParams));
32633 +
32634 + if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine
32635 + == e_FM_PCD_CC)
32636 + && p_KeyAndNextEngineParams->nextEngineParams.h_Manip)
32637 + {
32638 + err =
32639 + AllocAndFillAdForContLookupManip(
32640 + p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode);
32641 + if (err)
32642 + {
32643 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32644 + XX_Free(p_Params);
32645 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32646 + return NULL;
32647 + }
32648 + }
32649 +
32650 + requiredAction |= UPDATE_CC_WITH_TREE;
32651 + p_KeyAndNextEngineParams->requiredAction = requiredAction;
32652 +
32653 + k++;
32654 + }
32655 + }
32656 +
32657 + p_FmPcdCcTree->numOfEntries = (uint8_t)k;
32658 + p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
32659 +
32660 + p_FmPcdCcTree->ccTreeBaseAddr =
32661 + PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
32662 + (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE),
32663 + FM_PCD_CC_TREE_ADDR_ALIGN));
32664 + if (!p_FmPcdCcTree->ccTreeBaseAddr)
32665 + {
32666 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32667 + XX_Free(p_Params);
32668 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32669 + return NULL;
32670 + }
32671 + MemSet8(
32672 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0,
32673 + (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE));
32674 +
32675 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32676 +
32677 + for (i = 0; i < numOfEntries; i++)
32678 + {
32679 + p_KeyAndNextEngineParams = p_Params + i;
32680 +
32681 + NextStepAd(p_CcTreeTmp, NULL,
32682 + &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd);
32683 +
32684 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32685 +
32686 + memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i],
32687 + p_KeyAndNextEngineParams,
32688 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
32689 +
32690 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32691 + == e_FM_PCD_CC)
32692 + {
32693 + p_FmPcdCcNextNode =
32694 + (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
32695 + p_CcInformation = FindNodeInfoInReleventLst(
32696 + &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree,
32697 + p_FmPcdCcNextNode->h_Spinlock);
32698 +
32699 + if (!p_CcInformation)
32700 + {
32701 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32702 + ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
32703 + ccNodeInfo.index = 1;
32704 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst,
32705 + &ccNodeInfo,
32706 + p_FmPcdCcNextNode->h_Spinlock);
32707 + }
32708 + else
32709 + p_CcInformation->index++;
32710 + }
32711 + }
32712 +
32713 + FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
32714 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32715 +
32716 + if (!FmPcdLockTryLockAll(p_FmPcd))
32717 + {
32718 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32719 + XX_Free(p_Params);
32720 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32721 + return NULL;
32722 + }
32723 +
32724 + for (i = 0; i < numOfEntries; i++)
32725 + {
32726 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction)
32727 + {
32728 + err = SetRequiredAction(
32729 + h_FmPcd,
32730 + p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction,
32731 + &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1,
32732 + p_FmPcdCcTree);
32733 + if (err)
32734 + {
32735 + FmPcdLockUnlockAll(p_FmPcd);
32736 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32737 + XX_Free(p_Params);
32738 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32739 + return NULL;
32740 + }
32741 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32742 + }
32743 + }
32744 +
32745 + FmPcdLockUnlockAll(p_FmPcd);
32746 + p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd);
32747 + if (!p_FmPcdCcTree->p_Lock)
32748 + {
32749 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32750 + XX_Free(p_Params);
32751 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock"));
32752 + return NULL;
32753 + }
32754 +
32755 + XX_Free(p_Params);
32756 +
32757 + return p_FmPcdCcTree;
32758 +}
32759 +
32760 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree)
32761 +{
32762 + t_FmPcd *p_FmPcd;
32763 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32764 + int i = 0;
32765 +
32766 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32767 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32768 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32769 +
32770 + FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId);
32771 +
32772 + if (p_CcTree->owners)
32773 + RETURN_ERROR(
32774 + MAJOR,
32775 + E_INVALID_SELECTION,
32776 + ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
32777 +
32778 + /* Delete ip-reassembly schemes if exist */
32779 + if (p_CcTree->h_IpReassemblyManip)
32780 + {
32781 + FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip);
32782 + FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE);
32783 + }
32784 +
32785 + /* Delete capwap-reassembly schemes if exist */
32786 + if (p_CcTree->h_CapwapReassemblyManip)
32787 + {
32788 + FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip);
32789 + FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE);
32790 + }
32791 +
32792 + for (i = 0; i < p_CcTree->numOfEntries; i++)
32793 + {
32794 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32795 + == e_FM_PCD_CC)
32796 + UpdateNodeOwner(
32797 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32798 + FALSE);
32799 +
32800 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32801 + FmPcdManipUpdateOwner(
32802 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32803 + FALSE);
32804 +
32805 +#ifdef FM_CAPWAP_SUPPORT
32806 + if ((p_CcTree->numOfGrps == 1) &&
32807 + (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) &&
32808 + (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) &&
32809 + p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode &&
32810 + IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode))
32811 + {
32812 + if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK)
32813 + return E_INVALID_STATE;
32814 + }
32815 +#endif /* FM_CAPWAP_SUPPORT */
32816 +
32817 +#if (DPAA_VERSION >= 11)
32818 + if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32819 + == e_FM_PCD_FR)
32820 + && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32821 + FrmReplicGroupUpdateOwner(
32822 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32823 + FALSE);
32824 +#endif /* (DPAA_VERSION >= 11) */
32825 + }
32826 +
32827 + if (p_CcTree->p_Lock)
32828 + FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock);
32829 +
32830 + DeleteTree(p_CcTree, p_FmPcd);
32831 +
32832 + return E_OK;
32833 +}
32834 +
32835 +t_Error FM_PCD_CcRootModifyNextEngine(
32836 + t_Handle h_CcTree, uint8_t grpId, uint8_t index,
32837 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32838 +{
32839 + t_FmPcd *p_FmPcd;
32840 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32841 + t_Error err = E_OK;
32842 +
32843 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32844 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32845 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32846 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32847 +
32848 + if (!FmPcdLockTryLockAll(p_FmPcd))
32849 + {
32850 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32851 + return ERROR_CODE(E_BUSY);
32852 + }
32853 +
32854 + err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index,
32855 + p_FmPcdCcNextEngineParams);
32856 + FmPcdLockUnlockAll(p_FmPcd);
32857 +
32858 + if (err)
32859 + {
32860 + RETURN_ERROR(MAJOR, err, NO_MSG);
32861 + }
32862 +
32863 + return E_OK;
32864 +}
32865 +
32866 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd,
32867 + t_FmPcdCcNodeParams *p_CcNodeParam)
32868 +{
32869 + t_FmPcdCcNode *p_CcNode;
32870 + t_Error err;
32871 +
32872 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32873 + SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL);
32874 +
32875 + p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
32876 + if (!p_CcNode)
32877 + {
32878 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32879 + return NULL;
32880 + }
32881 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
32882 +
32883 + err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam);
32884 +
32885 + switch(GET_ERROR_TYPE(err)
32886 +) {
32887 + case E_OK:
32888 + break;
32889 +
32890 + case E_BUSY:
32891 + DBG(TRACE, ("E_BUSY error"));
32892 + return NULL;
32893 +
32894 + default:
32895 + REPORT_ERROR(MAJOR, err, NO_MSG);
32896 + return NULL;
32897 + }
32898 +
32899 + return p_CcNode;
32900 +}
32901 +
32902 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode)
32903 +{
32904 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32905 + int i = 0;
32906 +
32907 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32908 + SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE);
32909 +
32910 + if (p_CcNode->owners)
32911 + RETURN_ERROR(
32912 + MAJOR,
32913 + E_INVALID_STATE,
32914 + ("This node cannot be removed because it is occupied; first unbind this node"));
32915 +
32916 + for (i = 0; i < p_CcNode->numOfKeys; i++)
32917 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32918 + == e_FM_PCD_CC)
32919 + UpdateNodeOwner(
32920 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32921 + FALSE);
32922 +
32923 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32924 + == e_FM_PCD_CC)
32925 + UpdateNodeOwner(
32926 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32927 + FALSE);
32928 +
32929 + /* Handle also Miss entry */
32930 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
32931 + {
32932 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32933 + FmPcdManipUpdateOwner(
32934 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32935 + FALSE);
32936 +
32937 +#if (DPAA_VERSION >= 11)
32938 + if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32939 + == e_FM_PCD_FR)
32940 + && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32941 + {
32942 + FrmReplicGroupUpdateOwner(
32943 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32944 + FALSE);
32945 + }
32946 +#endif /* (DPAA_VERSION >= 11) */
32947 + }
32948 +
32949 + DeleteNode(p_CcNode);
32950 +
32951 + return E_OK;
32952 +}
32953 +
32954 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex,
32955 + uint8_t keySize,
32956 + t_FmPcdCcKeyParams *p_KeyParams)
32957 +{
32958 + t_FmPcd *p_FmPcd;
32959 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32960 + t_Error err = E_OK;
32961 +
32962 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
32963 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32964 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32965 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32966 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32967 +
32968 + if (keyIndex == FM_PCD_LAST_KEY_INDEX)
32969 + keyIndex = p_CcNode->numOfKeys;
32970 +
32971 + if (!FmPcdLockTryLockAll(p_FmPcd))
32972 + {
32973 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32974 + return ERROR_CODE(E_BUSY);
32975 + }
32976 +
32977 + err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams);
32978 +
32979 + FmPcdLockUnlockAll(p_FmPcd);
32980 +
32981 + switch(GET_ERROR_TYPE(err)
32982 +) {
32983 + case E_OK:
32984 + return E_OK;
32985 +
32986 + case E_BUSY:
32987 + DBG(TRACE, ("E_BUSY error"));
32988 + return ERROR_CODE(E_BUSY);
32989 +
32990 + default:
32991 + RETURN_ERROR(MAJOR, err, NO_MSG);
32992 + }
32993 +}
32994 +
32995 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex)
32996 +{
32997 + t_FmPcd *p_FmPcd;
32998 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32999 + t_Error err = E_OK;
33000 +
33001 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33002 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33003 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33004 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33005 +
33006 + if (!FmPcdLockTryLockAll(p_FmPcd))
33007 + {
33008 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33009 + return ERROR_CODE(E_BUSY);
33010 + }
33011 +
33012 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
33013 +
33014 + FmPcdLockUnlockAll(p_FmPcd);
33015 +
33016 + switch(GET_ERROR_TYPE(err)
33017 +) {
33018 + case E_OK:
33019 + return E_OK;
33020 +
33021 + case E_BUSY:
33022 + DBG(TRACE, ("E_BUSY error"));
33023 + return ERROR_CODE(E_BUSY);
33024 +
33025 + default:
33026 + RETURN_ERROR(MAJOR, err, NO_MSG);
33027 + }
33028 +
33029 + return E_OK;
33030 +}
33031 +
33032 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex,
33033 + uint8_t keySize, uint8_t *p_Key,
33034 + uint8_t *p_Mask)
33035 +{
33036 + t_FmPcd *p_FmPcd;
33037 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33038 + t_Error err = E_OK;
33039 +
33040 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33041 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33042 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33043 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33044 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33045 +
33046 +
33047 + if (!FmPcdLockTryLockAll(p_FmPcd))
33048 + {
33049 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33050 + return ERROR_CODE(E_BUSY);
33051 + }
33052 +
33053 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask);
33054 +
33055 + FmPcdLockUnlockAll(p_FmPcd);
33056 +
33057 + switch(GET_ERROR_TYPE(err)
33058 +) {
33059 + case E_OK:
33060 + return E_OK;
33061 +
33062 + case E_BUSY:
33063 + DBG(TRACE, ("E_BUSY error"));
33064 + return ERROR_CODE(E_BUSY);
33065 +
33066 + default:
33067 + RETURN_ERROR(MAJOR, err, NO_MSG);
33068 + }
33069 +}
33070 +
33071 +t_Error FM_PCD_MatchTableModifyNextEngine(
33072 + t_Handle h_CcNode, uint16_t keyIndex,
33073 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33074 +{
33075 + t_FmPcd *p_FmPcd;
33076 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33077 + t_Error err = E_OK;
33078 +
33079 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33080 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33081 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33082 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33083 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33084 +
33085 + if (!FmPcdLockTryLockAll(p_FmPcd))
33086 + {
33087 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33088 + return ERROR_CODE(E_BUSY);
33089 + }
33090 +
33091 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
33092 + p_FmPcdCcNextEngineParams);
33093 +
33094 + FmPcdLockUnlockAll(p_FmPcd);
33095 +
33096 + switch(GET_ERROR_TYPE(err)
33097 +) {
33098 + case E_OK:
33099 + return E_OK;
33100 +
33101 + case E_BUSY:
33102 + DBG(TRACE, ("E_BUSY error"));
33103 + return ERROR_CODE(E_BUSY);
33104 +
33105 + default:
33106 + RETURN_ERROR(MAJOR, err, NO_MSG);
33107 + }
33108 +}
33109 +
33110 +t_Error FM_PCD_MatchTableModifyMissNextEngine(
33111 + t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33112 +{
33113 + t_FmPcd *p_FmPcd;
33114 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33115 + t_Error err = E_OK;
33116 +
33117 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33118 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33119 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33120 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33121 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33122 +
33123 + if (!FmPcdLockTryLockAll(p_FmPcd))
33124 + {
33125 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33126 + return ERROR_CODE(E_BUSY);
33127 + }
33128 +
33129 + err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode,
33130 + p_FmPcdCcNextEngineParams);
33131 +
33132 + FmPcdLockUnlockAll(p_FmPcd);
33133 +
33134 + switch(GET_ERROR_TYPE(err)
33135 +) {
33136 + case E_OK:
33137 + return E_OK;
33138 +
33139 + case E_BUSY:
33140 + DBG(TRACE, ("E_BUSY error"));
33141 + return ERROR_CODE(E_BUSY);
33142 +
33143 + default:
33144 + RETURN_ERROR(MAJOR, err, NO_MSG);
33145 + }
33146 +}
33147 +
33148 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
33149 + uint16_t keyIndex,
33150 + uint8_t keySize,
33151 + t_FmPcdCcKeyParams *p_KeyParams)
33152 +{
33153 + t_FmPcd *p_FmPcd;
33154 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33155 + t_Error err = E_OK;
33156 +
33157 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33158 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33159 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33160 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33161 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33162 +
33163 + if (!FmPcdLockTryLockAll(p_FmPcd))
33164 + {
33165 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33166 + return ERROR_CODE(E_BUSY);
33167 + }
33168 +
33169 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize,
33170 + p_KeyParams);
33171 +
33172 + FmPcdLockUnlockAll(p_FmPcd);
33173 +
33174 + switch(GET_ERROR_TYPE(err)
33175 +) {
33176 + case E_OK:
33177 + return E_OK;
33178 +
33179 + case E_BUSY:
33180 + DBG(TRACE, ("E_BUSY error"));
33181 + return ERROR_CODE(E_BUSY);
33182 +
33183 + default:
33184 + RETURN_ERROR(MAJOR, err, NO_MSG);
33185 + }
33186 +}
33187 +
33188 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize,
33189 + uint8_t *p_Key, uint8_t *p_Mask)
33190 +{
33191 + t_FmPcd *p_FmPcd;
33192 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33193 + uint16_t keyIndex;
33194 + t_Error err;
33195 +
33196 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33197 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33198 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33199 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33200 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33201 +
33202 + if (!FmPcdLockTryLockAll(p_FmPcd))
33203 + {
33204 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33205 + return ERROR_CODE(E_BUSY);
33206 + }
33207 +
33208 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33209 + if (GET_ERROR_TYPE(err) != E_OK)
33210 + {
33211 + FmPcdLockUnlockAll(p_FmPcd);
33212 + RETURN_ERROR(
33213 + MAJOR,
33214 + err,
33215 + ("The received key and mask pair was not found in the match table of the provided node"));
33216 + }
33217 +
33218 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
33219 +
33220 + FmPcdLockUnlockAll(p_FmPcd);
33221 +
33222 + switch(GET_ERROR_TYPE(err)
33223 +) {
33224 + case E_OK:
33225 + return E_OK;
33226 +
33227 + case E_BUSY:
33228 + DBG(TRACE, ("E_BUSY error"));
33229 + return ERROR_CODE(E_BUSY);
33230 +
33231 + default:
33232 + RETURN_ERROR(MAJOR, err, NO_MSG);
33233 + }
33234 +}
33235 +
33236 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(
33237 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33238 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33239 +{
33240 + t_FmPcd *p_FmPcd;
33241 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33242 + uint16_t keyIndex;
33243 + t_Error err;
33244 +
33245 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33246 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33247 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33248 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33249 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33250 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33251 +
33252 + if (!FmPcdLockTryLockAll(p_FmPcd))
33253 + {
33254 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33255 + return ERROR_CODE(E_BUSY);
33256 + }
33257 +
33258 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33259 + if (GET_ERROR_TYPE(err) != E_OK)
33260 + {
33261 + FmPcdLockUnlockAll(p_FmPcd);
33262 + RETURN_ERROR(
33263 + MAJOR,
33264 + err,
33265 + ("The received key and mask pair was not found in the match table of the provided node"));
33266 + }
33267 +
33268 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
33269 + p_FmPcdCcNextEngineParams);
33270 +
33271 + FmPcdLockUnlockAll(p_FmPcd);
33272 +
33273 + switch(GET_ERROR_TYPE(err)
33274 +) {
33275 + case E_OK:
33276 + return E_OK;
33277 +
33278 + case E_BUSY:
33279 + DBG(TRACE, ("E_BUSY error"));
33280 + return ERROR_CODE(E_BUSY);
33281 +
33282 + default:
33283 + RETURN_ERROR(MAJOR, err, NO_MSG);
33284 + }
33285 +}
33286 +
33287 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(
33288 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33289 + t_FmPcdCcKeyParams *p_KeyParams)
33290 +{
33291 + t_FmPcd *p_FmPcd;
33292 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33293 + uint16_t keyIndex;
33294 + t_Error err;
33295 +
33296 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33297 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33298 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33299 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33300 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33301 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33302 +
33303 + if (!FmPcdLockTryLockAll(p_FmPcd))
33304 + {
33305 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33306 + return ERROR_CODE(E_BUSY);
33307 + }
33308 +
33309 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33310 + if (GET_ERROR_TYPE(err) != E_OK)
33311 + {
33312 + FmPcdLockUnlockAll(p_FmPcd);
33313 + RETURN_ERROR(
33314 + MAJOR,
33315 + err,
33316 + ("The received key and mask pair was not found in the match table of the provided node"));
33317 + }
33318 +
33319 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize,
33320 + p_KeyParams);
33321 +
33322 + FmPcdLockUnlockAll(p_FmPcd);
33323 +
33324 + switch(GET_ERROR_TYPE(err)
33325 +) {
33326 + case E_OK:
33327 + return E_OK;
33328 +
33329 + case E_BUSY:
33330 + DBG(TRACE, ("E_BUSY error"));
33331 + return ERROR_CODE(E_BUSY);
33332 +
33333 + default:
33334 + RETURN_ERROR(MAJOR, err, NO_MSG);
33335 + }
33336 +}
33337 +
33338 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize,
33339 + uint8_t *p_Key, uint8_t *p_Mask,
33340 + uint8_t *p_NewKey, uint8_t *p_NewMask)
33341 +{
33342 + t_FmPcd *p_FmPcd;
33343 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33344 + t_List h_List;
33345 + uint16_t keyIndex;
33346 + t_Error err;
33347 +
33348 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33349 + SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER);
33350 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33351 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33352 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33353 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33354 +
33355 + INIT_LIST(&h_List);
33356 +
33357 + err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List);
33358 + if (err)
33359 + {
33360 + DBG(TRACE, ("Node's trees lock failed"));
33361 + return ERROR_CODE(E_BUSY);
33362 + }
33363 +
33364 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33365 + if (GET_ERROR_TYPE(err) != E_OK)
33366 + {
33367 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33368 + RETURN_ERROR(MAJOR, err,
33369 + ("The received key and mask pair was not found in the "
33370 + "match table of the provided node"));
33371 + }
33372 +
33373 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey,
33374 + p_NewMask);
33375 +
33376 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33377 +
33378 + switch(GET_ERROR_TYPE(err)
33379 +) {
33380 + case E_OK:
33381 + return E_OK;
33382 +
33383 + case E_BUSY:
33384 + DBG(TRACE, ("E_BUSY error"));
33385 + return ERROR_CODE(E_BUSY);
33386 +
33387 + default:
33388 + RETURN_ERROR(MAJOR, err, NO_MSG);
33389 + }
33390 +}
33391 +
33392 +t_Error FM_PCD_MatchTableGetNextEngine(
33393 + t_Handle h_CcNode, uint16_t keyIndex,
33394 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33395 +{
33396 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33397 +
33398 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33399 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33400 +
33401 + if (keyIndex >= p_CcNode->numOfKeys)
33402 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33403 + ("keyIndex exceeds current number of keys"));
33404 +
33405 + if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1))
33406 + RETURN_ERROR(
33407 + MAJOR,
33408 + E_INVALID_VALUE,
33409 + ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1)));
33410 +
33411 + memcpy(p_FmPcdCcNextEngineParams,
33412 + &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams,
33413 + sizeof(t_FmPcdCcNextEngineParams));
33414 +
33415 + return E_OK;
33416 +}
33417 +
33418 +
33419 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex)
33420 +{
33421 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33422 + uint32_t *p_StatsCounters, frameCount;
33423 + uint32_t intFlags;
33424 +
33425 + SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0);
33426 +
33427 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
33428 + {
33429 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table"));
33430 + return 0;
33431 + }
33432 +
33433 + if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME)
33434 + && (p_CcNode->statisticsMode
33435 + != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33436 + {
33437 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table"));
33438 + return 0;
33439 + }
33440 +
33441 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33442 +
33443 + if (keyIndex >= p_CcNode->numOfKeys)
33444 + {
33445 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33446 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table"));
33447 + return 0;
33448 + }
33449 +
33450 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
33451 + {
33452 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33453 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key"));
33454 + return 0;
33455 + }
33456 +
33457 + p_StatsCounters =
33458 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
33459 + ASSERT_COND(p_StatsCounters);
33460 +
33461 + /* The first counter is byte counter, so we need to advance to the next counter */
33462 + frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters,
33463 + FM_PCD_CC_STATS_COUNTER_SIZE)));
33464 +
33465 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33466 +
33467 + return frameCount;
33468 +}
33469 +
33470 +t_Error FM_PCD_MatchTableGetKeyStatistics(
33471 + t_Handle h_CcNode, uint16_t keyIndex,
33472 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33473 +{
33474 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33475 + uint32_t intFlags;
33476 + t_Error err;
33477 +
33478 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33479 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33480 +
33481 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33482 +
33483 + if (keyIndex >= p_CcNode->numOfKeys)
33484 + RETURN_ERROR(
33485 + MAJOR,
33486 + E_INVALID_STATE,
33487 + ("The provided keyIndex exceeds the number of keys in this match table"));
33488 +
33489 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33490 +
33491 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33492 +
33493 + if (err != E_OK)
33494 + RETURN_ERROR(MAJOR, err, NO_MSG);
33495 +
33496 + return E_OK;
33497 +}
33498 +
33499 +t_Error FM_PCD_MatchTableGetMissStatistics(
33500 + t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics)
33501 +{
33502 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33503 + uint32_t intFlags;
33504 + t_Error err;
33505 +
33506 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33507 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
33508 +
33509 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33510 +
33511 + err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys,
33512 + p_MissStatistics);
33513 +
33514 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33515 +
33516 + if (err != E_OK)
33517 + RETURN_ERROR(MAJOR, err, NO_MSG);
33518 +
33519 + return E_OK;
33520 +}
33521 +
33522 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(
33523 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33524 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33525 +{
33526 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33527 + uint16_t keyIndex;
33528 + uint32_t intFlags;
33529 + t_Error err;
33530 +
33531 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33532 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33533 +
33534 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33535 +
33536 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33537 + if (GET_ERROR_TYPE(err) != E_OK)
33538 + {
33539 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33540 + RETURN_ERROR(MAJOR, err,
33541 + ("The received key and mask pair was not found in the "
33542 + "match table of the provided node"));
33543 + }
33544 +
33545 + ASSERT_COND(keyIndex < p_CcNode->numOfKeys);
33546 +
33547 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33548 +
33549 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33550 +
33551 + if (err != E_OK)
33552 + RETURN_ERROR(MAJOR, err, NO_MSG);
33553 +
33554 + return E_OK;
33555 +}
33556 +
33557 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
33558 + uint8_t keySize, uint8_t *p_Key,
33559 + uint8_t hashShift,
33560 + t_Handle *p_CcNodeBucketHandle,
33561 + uint8_t *p_BucketIndex,
33562 + uint16_t *p_LastIndex)
33563 +{
33564 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33565 + uint16_t glblMask;
33566 + uint64_t crc64 = 0;
33567 +
33568 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33569 + SANITY_CHECK_RETURN_ERROR(
33570 + p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED,
33571 + E_INVALID_STATE);
33572 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33573 + SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER);
33574 +
33575 + memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2);
33576 + be16_to_cpus(&glblMask);
33577 +
33578 + crc64 = crc64_init();
33579 + crc64 = crc64_compute(p_Key, keySize, crc64);
33580 + crc64 >>= hashShift;
33581 +
33582 + *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset)))
33583 + & glblMask) >> 4);
33584 + if (*p_BucketIndex >= p_CcNode->numOfKeys)
33585 + RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!"));
33586 +
33587 + *p_CcNodeBucketHandle =
33588 + p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode;
33589 + if (!*p_CcNodeBucketHandle)
33590 + RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!"));
33591 +
33592 + *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys;
33593 +
33594 + return E_OK;
33595 +}
33596 +
33597 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param)
33598 +{
33599 + t_FmPcdCcNode *p_CcNodeHashTbl;
33600 + t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam;
33601 + t_FmPcdCcNode *p_CcNode;
33602 + t_Handle h_MissStatsCounters = NULL;
33603 + t_FmPcdCcKeyParams *p_HashKeyParams;
33604 + int i;
33605 + uint16_t numOfSets, numOfWays, countMask, onesCount = 0;
33606 + bool statsEnForMiss = FALSE;
33607 + t_Error err;
33608 +
33609 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
33610 + SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL);
33611 +
33612 + if (p_Param->maxNumOfKeys == 0)
33613 + {
33614 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0"));
33615 + return NULL;
33616 + }
33617 +
33618 + if (p_Param->hashResMask == 0)
33619 + {
33620 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0"));
33621 + return NULL;
33622 + }
33623 +
33624 + /*Fix: QorIQ SDK / QSDK-2131*/
33625 + if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID)
33626 + {
33627 + 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."));
33628 + return NULL;
33629 + }
33630 +
33631 +#if (DPAA_VERSION >= 11)
33632 + if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON)
33633 + {
33634 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
33635 + ("RMON statistics mode is not supported for hash table"));
33636 + return NULL;
33637 + }
33638 +#endif /* (DPAA_VERSION >= 11) */
33639 +
33640 + p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33641 + sizeof(t_FmPcdCcNodeParams));
33642 + if (!p_ExactMatchCcNodeParam)
33643 + {
33644 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam"));
33645 + return NULL;
33646 + }
33647 + memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33648 +
33649 + p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33650 + sizeof(t_FmPcdCcNodeParams));
33651 + if (!p_IndxHashCcNodeParam)
33652 + {
33653 + XX_Free(p_ExactMatchCcNodeParam);
33654 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam"));
33655 + return NULL;
33656 + }
33657 + memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33658 +
33659 + /* Calculate number of sets and number of ways of the hash table */
33660 + countMask = (uint16_t)(p_Param->hashResMask >> 4);
33661 + while (countMask)
33662 + {
33663 + onesCount++;
33664 + countMask = (uint16_t)(countMask >> 1);
33665 + }
33666 +
33667 + numOfSets = (uint16_t)(1 << onesCount);
33668 + numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets);
33669 +
33670 + if (p_Param->maxNumOfKeys % numOfSets)
33671 + DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up"));
33672 +
33673 + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME)
33674 + || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33675 + {
33676 + /* Allocating a statistics counters table that will be used by all
33677 + 'miss' entries of the hash table */
33678 + h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem(
33679 + FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE,
33680 + FM_PCD_CC_AD_TABLE_ALIGN);
33681 + if (!h_MissStatsCounters)
33682 + {
33683 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss"));
33684 + XX_Free(p_IndxHashCcNodeParam);
33685 + XX_Free(p_ExactMatchCcNodeParam);
33686 + return NULL;
33687 + }
33688 + memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33689 +
33690 + /* Always enable statistics for 'miss', so that a statistics AD will be
33691 + initialized from the start. We'll store the requested 'statistics enable'
33692 + value and it will be used when statistics are read by the user. */
33693 + statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn;
33694 + p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE;
33695 + }
33696 +
33697 + /* Building exact-match node params, will be used to create the hash buckets */
33698 + p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33699 +
33700 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src =
33701 + e_FM_PCD_EXTRACT_FROM_KEY;
33702 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action =
33703 + e_FM_PCD_ACTION_EXACT_MATCH;
33704 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0;
33705 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size =
33706 + p_Param->matchKeySize;
33707 +
33708 + p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays;
33709 + p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE;
33710 + p_ExactMatchCcNodeParam->keysParams.statisticsMode =
33711 + p_Param->statisticsMode;
33712 + p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0;
33713 + p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize;
33714 + p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss =
33715 + p_Param->ccNextEngineParamsForMiss;
33716 +
33717 + p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams;
33718 +
33719 + for (i = 0; i < numOfSets; i++)
33720 + {
33721 + /* Each exact-match node will be marked as a 'bucket' and provided with
33722 + a pointer to statistics counters, to be used for 'miss' entry
33723 + statistics */
33724 + p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode));
33725 + if (!p_CcNode)
33726 + break;
33727 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
33728 +
33729 + p_CcNode->isHashBucket = TRUE;
33730 + p_CcNode->h_MissStatsCounters = h_MissStatsCounters;
33731 +
33732 + err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam);
33733 + if (err)
33734 + break;
33735 +
33736 + p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC;
33737 + p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE;
33738 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode =
33739 + p_CcNode;
33740 + }
33741 +
33742 + if (i < numOfSets)
33743 + {
33744 + for (i = i - 1; i >= 0; i--)
33745 + FM_PCD_MatchTableDelete(
33746 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode);
33747 +
33748 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33749 +
33750 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
33751 + XX_Free(p_IndxHashCcNodeParam);
33752 + XX_Free(p_ExactMatchCcNodeParam);
33753 + return NULL;
33754 + }
33755 +
33756 + /* Creating indexed-hash CC node */
33757 + p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33758 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src =
33759 + e_FM_PCD_EXTRACT_FROM_HASH;
33760 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action =
33761 + e_FM_PCD_ACTION_INDEXED_LOOKUP;
33762 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask =
33763 + p_Param->hashResMask;
33764 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset =
33765 + p_Param->hashShift;
33766 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2;
33767 +
33768 + p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets;
33769 + p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE;
33770 + p_IndxHashCcNodeParam->keysParams.statisticsMode =
33771 + e_FM_PCD_CC_STATS_MODE_NONE;
33772 + /* Number of keys of this node is number of sets of the hash */
33773 + p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets;
33774 + p_IndxHashCcNodeParam->keysParams.keySize = 2;
33775 +
33776 + p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam);
33777 +
33778 + if (p_CcNodeHashTbl)
33779 + {
33780 + p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift;
33781 +
33782 + /* Storing the allocated counters for buckets 'miss' in the hash table
33783 + and if statistics for miss were enabled. */
33784 + p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters;
33785 + p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss;
33786 + }
33787 +
33788 + XX_Free(p_IndxHashCcNodeParam);
33789 + XX_Free(p_ExactMatchCcNodeParam);
33790 +
33791 + return p_CcNodeHashTbl;
33792 +}
33793 +
33794 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl)
33795 +{
33796 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33797 + t_Handle h_FmPcd;
33798 + t_Handle *p_HashBuckets, h_MissStatsCounters;
33799 + uint16_t i, numOfBuckets;
33800 + t_Error err;
33801 +
33802 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33803 +
33804 + /* Store all hash buckets before the hash is freed */
33805 + numOfBuckets = p_HashTbl->numOfKeys;
33806 +
33807 + p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle));
33808 + if (!p_HashBuckets)
33809 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
33810 +
33811 + for (i = 0; i < numOfBuckets; i++)
33812 + p_HashBuckets[i] =
33813 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33814 +
33815 + h_FmPcd = p_HashTbl->h_FmPcd;
33816 + h_MissStatsCounters = p_HashTbl->h_MissStatsCounters;
33817 +
33818 + /* Free the hash */
33819 + err = FM_PCD_MatchTableDelete(p_HashTbl);
33820 +
33821 + /* Free each hash bucket */
33822 + for (i = 0; i < numOfBuckets; i++)
33823 + err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]);
33824 +
33825 + XX_Free(p_HashBuckets);
33826 +
33827 + /* Free statistics counters for 'miss', if these were allocated */
33828 + if (h_MissStatsCounters)
33829 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33830 +
33831 + if (err)
33832 + RETURN_ERROR(MAJOR, err, NO_MSG);
33833 +
33834 + return E_OK;
33835 +}
33836 +
33837 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize,
33838 + t_FmPcdCcKeyParams *p_KeyParams)
33839 +{
33840 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33841 + t_Handle h_HashBucket;
33842 + uint8_t bucketIndex;
33843 + uint16_t lastIndex;
33844 + t_Error err;
33845 +
33846 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33847 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33848 + SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER);
33849 +
33850 + if (p_KeyParams->p_Mask)
33851 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
33852 + ("Keys masks not supported for hash table"));
33853 +
33854 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize,
33855 + p_KeyParams->p_Key,
33856 + p_HashTbl->kgHashShift,
33857 + &h_HashBucket, &bucketIndex,
33858 + &lastIndex);
33859 + if (err)
33860 + RETURN_ERROR(MAJOR, err, NO_MSG);
33861 +
33862 + return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize,
33863 + p_KeyParams);
33864 +}
33865 +
33866 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize,
33867 + uint8_t *p_Key)
33868 +{
33869 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33870 + t_Handle h_HashBucket;
33871 + uint8_t bucketIndex;
33872 + uint16_t lastIndex;
33873 + t_Error err;
33874 +
33875 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33876 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33877 +
33878 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33879 + p_HashTbl->kgHashShift,
33880 + &h_HashBucket, &bucketIndex,
33881 + &lastIndex);
33882 + if (err)
33883 + RETURN_ERROR(MAJOR, err, NO_MSG);
33884 +
33885 + return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL);
33886 +}
33887 +
33888 +t_Error FM_PCD_HashTableModifyNextEngine(
33889 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33890 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33891 +{
33892 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33893 + t_Handle h_HashBucket;
33894 + uint8_t bucketIndex;
33895 + uint16_t lastIndex;
33896 + t_Error err;
33897 +
33898 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33899 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33900 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33901 +
33902 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33903 + p_HashTbl->kgHashShift,
33904 + &h_HashBucket, &bucketIndex,
33905 + &lastIndex);
33906 + if (err)
33907 + RETURN_ERROR(MAJOR, err, NO_MSG);
33908 +
33909 + return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key,
33910 + NULL,
33911 + p_FmPcdCcNextEngineParams);
33912 +}
33913 +
33914 +t_Error FM_PCD_HashTableModifyMissNextEngine(
33915 + t_Handle h_HashTbl,
33916 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33917 +{
33918 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33919 + t_Handle h_HashBucket;
33920 + uint8_t i;
33921 + bool nullifyMissStats = FALSE;
33922 + t_Error err;
33923 +
33924 + SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE);
33925 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33926 +
33927 + if ((!p_HashTbl->h_MissStatsCounters)
33928 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33929 + RETURN_ERROR(
33930 + MAJOR,
33931 + E_CONFLICT,
33932 + ("Statistics are requested for a key, but statistics mode was set"
33933 + "to 'NONE' upon initialization"));
33934 +
33935 + if (p_HashTbl->h_MissStatsCounters)
33936 + {
33937 + if ((!p_HashTbl->statsEnForMiss)
33938 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33939 + nullifyMissStats = TRUE;
33940 +
33941 + if ((p_HashTbl->statsEnForMiss)
33942 + && (!p_FmPcdCcNextEngineParams->statisticsEn))
33943 + {
33944 + p_HashTbl->statsEnForMiss = FALSE;
33945 + p_FmPcdCcNextEngineParams->statisticsEn = TRUE;
33946 + }
33947 + }
33948 +
33949 + for (i = 0; i < p_HashTbl->numOfKeys; i++)
33950 + {
33951 + h_HashBucket =
33952 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33953 +
33954 + err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket,
33955 + p_FmPcdCcNextEngineParams);
33956 + if (err)
33957 + RETURN_ERROR(MAJOR, err, NO_MSG);
33958 + }
33959 +
33960 + if (nullifyMissStats)
33961 + {
33962 + memset(p_HashTbl->h_MissStatsCounters, 0,
33963 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33964 + memset(p_HashTbl->h_MissStatsCounters, 0,
33965 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33966 + p_HashTbl->statsEnForMiss = TRUE;
33967 + }
33968 +
33969 + return E_OK;
33970 +}
33971 +
33972 +
33973 +t_Error FM_PCD_HashTableGetMissNextEngine(
33974 + t_Handle h_HashTbl,
33975 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33976 +{
33977 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33978 + t_FmPcdCcNode *p_HashBucket;
33979 +
33980 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33981 +
33982 + /* Miss next engine of each bucket was initialized with the next engine of the hash table */
33983 + p_HashBucket =
33984 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
33985 +
33986 + memcpy(p_FmPcdCcNextEngineParams,
33987 + &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams,
33988 + sizeof(t_FmPcdCcNextEngineParams));
33989 +
33990 + return E_OK;
33991 +}
33992 +
33993 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(
33994 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33995 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33996 +{
33997 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33998 + t_Handle h_HashBucket;
33999 + uint8_t bucketIndex;
34000 + uint16_t lastIndex;
34001 + t_Error err;
34002 +
34003 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
34004 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34005 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
34006 +
34007 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
34008 + p_HashTbl->kgHashShift,
34009 + &h_HashBucket, &bucketIndex,
34010 + &lastIndex);
34011 + if (err)
34012 + RETURN_ERROR(MAJOR, err, NO_MSG);
34013 +
34014 + return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key,
34015 + NULL, p_KeyStatistics);
34016 +}
34017 +
34018 +t_Error FM_PCD_HashTableGetMissStatistics(
34019 + t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics)
34020 +{
34021 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
34022 + t_Handle h_HashBucket;
34023 +
34024 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
34025 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
34026 +
34027 + if (!p_HashTbl->statsEnForMiss)
34028 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
34029 + ("Statistics were not enabled for miss"));
34030 +
34031 + h_HashBucket =
34032 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
34033 +
34034 + return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics);
34035 +}
34036 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
34037 new file mode 100644
34038 index 00000000..3456bb56
34039 --- /dev/null
34040 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
34041 @@ -0,0 +1,399 @@
34042 +/*
34043 + * Copyright 2008-2012 Freescale Semiconductor Inc.
34044 + *
34045 + * Redistribution and use in source and binary forms, with or without
34046 + * modification, are permitted provided that the following conditions are met:
34047 + * * Redistributions of source code must retain the above copyright
34048 + * notice, this list of conditions and the following disclaimer.
34049 + * * Redistributions in binary form must reproduce the above copyright
34050 + * notice, this list of conditions and the following disclaimer in the
34051 + * documentation and/or other materials provided with the distribution.
34052 + * * Neither the name of Freescale Semiconductor nor the
34053 + * names of its contributors may be used to endorse or promote products
34054 + * derived from this software without specific prior written permission.
34055 + *
34056 + *
34057 + * ALTERNATIVELY, this software may be distributed under the terms of the
34058 + * GNU General Public License ("GPL") as published by the Free Software
34059 + * Foundation, either version 2 of that License or (at your option) any
34060 + * later version.
34061 + *
34062 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
34063 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34064 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34065 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
34066 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34067 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34068 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34069 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34070 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34071 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34072 + */
34073 +
34074 +
34075 +/******************************************************************************
34076 + @File fm_cc.h
34077 +
34078 + @Description FM PCD CC ...
34079 +*//***************************************************************************/
34080 +#ifndef __FM_CC_H
34081 +#define __FM_CC_H
34082 +
34083 +#include "std_ext.h"
34084 +#include "error_ext.h"
34085 +#include "list_ext.h"
34086 +
34087 +#include "fm_pcd.h"
34088 +
34089 +
34090 +/***********************************************************************/
34091 +/* Coarse classification defines */
34092 +/***********************************************************************/
34093 +
34094 +#define CC_MAX_NUM_OF_KEYS (FM_PCD_MAX_NUM_OF_KEYS + 1)
34095 +
34096 +#define CC_PC_FF_MACDST 0x00
34097 +#define CC_PC_FF_MACSRC 0x01
34098 +#define CC_PC_FF_ETYPE 0x02
34099 +
34100 +#define CC_PC_FF_TCI1 0x03
34101 +#define CC_PC_FF_TCI2 0x04
34102 +
34103 +#define CC_PC_FF_MPLS1 0x06
34104 +#define CC_PC_FF_MPLS_LAST 0x07
34105 +
34106 +#define CC_PC_FF_IPV4DST1 0x08
34107 +#define CC_PC_FF_IPV4DST2 0x16
34108 +#define CC_PC_FF_IPV4IPTOS_TC1 0x09
34109 +#define CC_PC_FF_IPV4IPTOS_TC2 0x17
34110 +#define CC_PC_FF_IPV4PTYPE1 0x0A
34111 +#define CC_PC_FF_IPV4PTYPE2 0x18
34112 +#define CC_PC_FF_IPV4SRC1 0x0b
34113 +#define CC_PC_FF_IPV4SRC2 0x19
34114 +#define CC_PC_FF_IPV4SRC1_IPV4DST1 0x0c
34115 +#define CC_PC_FF_IPV4SRC2_IPV4DST2 0x1a
34116 +#define CC_PC_FF_IPV4TTL 0x29
34117 +
34118 +
34119 +#define CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1 0x0d /*TODO - CLASS - what is it? TOS*/
34120 +#define CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2 0x1b
34121 +#define CC_PC_FF_IPV6PTYPE1 0x0e
34122 +#define CC_PC_FF_IPV6PTYPE2 0x1c
34123 +#define CC_PC_FF_IPV6DST1 0x0f
34124 +#define CC_PC_FF_IPV6DST2 0x1d
34125 +#define CC_PC_FF_IPV6SRC1 0x10
34126 +#define CC_PC_FF_IPV6SRC2 0x1e
34127 +#define CC_PC_FF_IPV6HOP_LIMIT 0x2a
34128 +#define CC_PC_FF_IPPID 0x24
34129 +#define CC_PC_FF_IPDSCP 0x76
34130 +
34131 +#define CC_PC_FF_GREPTYPE 0x11
34132 +
34133 +#define CC_PC_FF_MINENCAP_PTYPE 0x12
34134 +#define CC_PC_FF_MINENCAP_IPDST 0x13
34135 +#define CC_PC_FF_MINENCAP_IPSRC 0x14
34136 +#define CC_PC_FF_MINENCAP_IPSRC_IPDST 0x15
34137 +
34138 +#define CC_PC_FF_L4PSRC 0x1f
34139 +#define CC_PC_FF_L4PDST 0x20
34140 +#define CC_PC_FF_L4PSRC_L4PDST 0x21
34141 +
34142 +#define CC_PC_FF_PPPPID 0x05
34143 +
34144 +#define CC_PC_PR_SHIM1 0x22
34145 +#define CC_PC_PR_SHIM2 0x23
34146 +
34147 +#define CC_PC_GENERIC_WITHOUT_MASK 0x27
34148 +#define CC_PC_GENERIC_WITH_MASK 0x28
34149 +#define CC_PC_GENERIC_IC_GMASK 0x2B
34150 +#define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C
34151 +#define CC_PC_GENERIC_IC_AGING_MASK 0x2D
34152 +
34153 +#define CC_PR_OFFSET 0x25
34154 +#define CC_PR_WITHOUT_OFFSET 0x26
34155 +
34156 +#define CC_PC_PR_ETH_OFFSET 19
34157 +#define CC_PC_PR_USER_DEFINED_SHIM1_OFFSET 16
34158 +#define CC_PC_PR_USER_DEFINED_SHIM2_OFFSET 17
34159 +#define CC_PC_PR_USER_LLC_SNAP_OFFSET 20
34160 +#define CC_PC_PR_VLAN1_OFFSET 21
34161 +#define CC_PC_PR_VLAN2_OFFSET 22
34162 +#define CC_PC_PR_PPPOE_OFFSET 24
34163 +#define CC_PC_PR_MPLS1_OFFSET 25
34164 +#define CC_PC_PR_MPLS_LAST_OFFSET 26
34165 +#define CC_PC_PR_IP1_OFFSET 27
34166 +#define CC_PC_PR_IP_LAST_OFFSET 28
34167 +#define CC_PC_PR_MINENC_OFFSET 28
34168 +#define CC_PC_PR_L4_OFFSET 30
34169 +#define CC_PC_PR_GRE_OFFSET 29
34170 +#define CC_PC_PR_ETYPE_LAST_OFFSET 23
34171 +#define CC_PC_PR_NEXT_HEADER_OFFSET 31
34172 +
34173 +#define CC_PC_ILLEGAL 0xff
34174 +#define CC_SIZE_ILLEGAL 0
34175 +
34176 +#define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16
34177 +#define FM_PCD_CC_AD_TABLE_ALIGN 16
34178 +#define FM_PCD_CC_AD_ENTRY_SIZE 16
34179 +#define FM_PCD_CC_NUM_OF_KEYS 255
34180 +#define FM_PCD_CC_TREE_ADDR_ALIGN 256
34181 +
34182 +#define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000
34183 +#define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000
34184 +#define FM_PCD_AD_RESULT_PLCR_DIS 0x20000000
34185 +#define FM_PCD_AD_RESULT_EXTENDED_MODE 0x80000000
34186 +#define FM_PCD_AD_RESULT_NADEN 0x20000000
34187 +#define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000
34188 +
34189 +#define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000
34190 +#define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000
34191 +
34192 +#define FM_PCD_AD_STATS_TYPE 0x40000000
34193 +#define FM_PCD_AD_STATS_FLR_ADDR_MASK 0x00FFFFFF
34194 +#define FM_PCD_AD_STATS_COUNTERS_ADDR_MASK 0x00FFFFFF
34195 +#define FM_PCD_AD_STATS_NEXT_ACTION_MASK 0xFFFF0000
34196 +#define FM_PCD_AD_STATS_NEXT_ACTION_SHIFT 12
34197 +#define FM_PCD_AD_STATS_NAD_EN 0x00008000
34198 +#define FM_PCD_AD_STATS_OP_CODE 0x00000036
34199 +#define FM_PCD_AD_STATS_FLR_EN 0x00004000
34200 +#define FM_PCD_AD_STATS_COND_EN 0x00002000
34201 +
34202 +
34203 +
34204 +#define FM_PCD_AD_BYPASS_TYPE 0xc0000000
34205 +
34206 +#define FM_PCD_AD_TYPE_MASK 0xc0000000
34207 +#define FM_PCD_AD_OPCODE_MASK 0x0000000f
34208 +
34209 +#define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16
34210 +#if (DPAA_VERSION >= 11)
34211 +#define FM_PCD_AD_RESULT_VSP_SHIFT 24
34212 +#define FM_PCD_AD_RESULT_NO_OM_VSPE 0x02000000
34213 +#define FM_PCD_AD_RESULT_VSP_MASK 0x3f
34214 +#define FM_PCD_AD_NCSPFQIDM_MASK 0x80000000
34215 +#endif /* (DPAA_VERSION >= 11) */
34216 +
34217 +#define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000
34218 +#define CC_GLBL_MASK_SIZE 4
34219 +#define CC_AGING_MASK_SIZE 4
34220 +
34221 +typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */
34222 +
34223 +#define CC_PRIVATE_INFO_NONE 0
34224 +#define CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP 0x80000000
34225 +#define CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH 0x40000000
34226 +#define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000
34227 +#define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000
34228 +
34229 +#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys)))
34230 +/***********************************************************************/
34231 +/* Memory map */
34232 +/***********************************************************************/
34233 +#if defined(__MWERKS__) && !defined(__GNUC__)
34234 +#pragma pack(push,1)
34235 +#endif /* defined(__MWERKS__) && ... */
34236 +
34237 +typedef struct
34238 +{
34239 + volatile uint32_t fqid;
34240 + volatile uint32_t plcrProfile;
34241 + volatile uint32_t nia;
34242 + volatile uint32_t res;
34243 +} t_AdOfTypeResult;
34244 +
34245 +typedef struct
34246 +{
34247 + volatile uint32_t ccAdBase;
34248 + volatile uint32_t matchTblPtr;
34249 + volatile uint32_t pcAndOffsets;
34250 + volatile uint32_t gmask;
34251 +} t_AdOfTypeContLookup;
34252 +
34253 +typedef struct
34254 +{
34255 + volatile uint32_t profileTableAddr;
34256 + volatile uint32_t reserved;
34257 + volatile uint32_t nextActionIndx;
34258 + volatile uint32_t statsTableAddr;
34259 +} t_AdOfTypeStats;
34260 +
34261 +typedef union
34262 +{
34263 + volatile t_AdOfTypeResult adResult;
34264 + volatile t_AdOfTypeContLookup adContLookup;
34265 +} t_Ad;
34266 +
34267 +#if defined(__MWERKS__) && !defined(__GNUC__)
34268 +#pragma pack(pop)
34269 +#endif /* defined(__MWERKS__) && ... */
34270 +
34271 +
34272 +/***********************************************************************/
34273 +/* Driver's internal structures */
34274 +/***********************************************************************/
34275 +
34276 +typedef struct t_FmPcdStatsObj
34277 +{
34278 + t_Handle h_StatsAd;
34279 + t_Handle h_StatsCounters;
34280 + t_List node;
34281 +} t_FmPcdStatsObj;
34282 +
34283 +typedef struct
34284 +{
34285 + uint8_t key[FM_PCD_MAX_SIZE_OF_KEY];
34286 + uint8_t mask[FM_PCD_MAX_SIZE_OF_KEY];
34287 +
34288 + t_FmPcdCcNextEngineParams nextEngineParams;
34289 + uint32_t requiredAction;
34290 + uint32_t shadowAction;
34291 +
34292 + t_FmPcdStatsObj *p_StatsObj;
34293 +
34294 +} t_FmPcdCcKeyAndNextEngineParams;
34295 +
34296 +typedef struct
34297 +{
34298 + t_Handle p_Ad;
34299 + e_FmPcdEngine fmPcdEngine;
34300 + bool adAllocated;
34301 + bool isTree;
34302 +
34303 + uint32_t myInfo;
34304 + t_List *h_CcNextNodesLst;
34305 + t_Handle h_AdditionalInfo;
34306 + t_Handle h_Node;
34307 +} t_FmPcdModifyCcAdditionalParams;
34308 +
34309 +typedef struct
34310 +{
34311 + t_Handle p_AdTableNew;
34312 + t_Handle p_KeysMatchTableNew;
34313 + t_Handle p_AdTableOld;
34314 + t_Handle p_KeysMatchTableOld;
34315 + uint16_t numOfKeys;
34316 + t_Handle h_CurrentNode;
34317 + uint16_t savedKeyIndex;
34318 + t_Handle h_NodeForAdd;
34319 + t_Handle h_NodeForRmv;
34320 + t_Handle h_ManipForRmv;
34321 + t_Handle h_ManipForAdd;
34322 + t_FmPcdStatsObj *p_StatsObjForRmv;
34323 +#if (DPAA_VERSION >= 11)
34324 + t_Handle h_FrmReplicForAdd;
34325 + t_Handle h_FrmReplicForRmv;
34326 +#endif /* (DPAA_VERSION >= 11) */
34327 + bool tree;
34328 +
34329 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34330 +} t_FmPcdModifyCcKeyAdditionalParams;
34331 +
34332 +typedef struct
34333 +{
34334 + t_Handle h_Manip;
34335 + t_Handle h_CcNode;
34336 +} t_CcNextEngineInfo;
34337 +
34338 +typedef struct
34339 +{
34340 + uint16_t numOfKeys;
34341 + uint16_t maxNumOfKeys;
34342 +
34343 + bool maskSupport;
34344 + uint32_t keysMatchTableMaxSize;
34345 +
34346 + e_FmPcdCcStatsMode statisticsMode;
34347 + uint32_t numOfStatsFLRs;
34348 + uint32_t countersArraySize;
34349 +
34350 + bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */
34351 + t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket;
34352 + Holds the statistics counters allocated by the hash table and
34353 + are shared by all hash table buckets; */
34354 + t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only;
34355 + Holds the statistics counters that were allocated for this node
34356 + and replaced by the shared counters (allocated by the hash table); */
34357 + bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently
34358 + enabled for hash 'miss', FALSE otherwise; This parameter effects the
34359 + returned statistics count to user, statistics AD always present for 'miss'
34360 + for all hash buckets; */
34361 + bool glblMaskUpdated;
34362 + t_Handle p_GlblMask;
34363 + bool lclMask;
34364 + uint8_t parseCode;
34365 + uint8_t offset;
34366 + uint8_t prsArrayOffset;
34367 + bool ctrlFlow;
34368 + uint16_t owners;
34369 +
34370 + uint8_t ccKeySizeAccExtraction;
34371 + uint8_t sizeOfExtraction;
34372 + uint8_t glblMaskSize;
34373 +
34374 + t_Handle h_KeysMatchTable;
34375 + t_Handle h_AdTable;
34376 + t_Handle h_StatsAds;
34377 + t_Handle h_TmpAd;
34378 + t_Handle h_Ad;
34379 + t_Handle h_StatsFLRs;
34380 +
34381 + t_List availableStatsLst;
34382 +
34383 + t_List ccPrevNodesLst;
34384 +
34385 + t_List ccTreeIdLst;
34386 + t_List ccTreesLst;
34387 +
34388 + t_Handle h_FmPcd;
34389 + uint32_t shadowAction;
34390 + uint8_t userSizeOfExtraction;
34391 + uint8_t userOffset;
34392 + uint8_t kgHashShift; /* used in hash-table */
34393 +
34394 + t_Handle h_Spinlock;
34395 +
34396 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34397 +} t_FmPcdCcNode;
34398 +
34399 +typedef struct
34400 +{
34401 + t_FmPcdCcNode *p_FmPcdCcNode;
34402 + bool occupied;
34403 + uint16_t owners;
34404 + volatile bool lock;
34405 +} t_FmPcdCcNodeArray;
34406 +
34407 +typedef struct
34408 +{
34409 + uint8_t numOfEntriesInGroup;
34410 + uint32_t totalBitsMask;
34411 + uint8_t baseGroupEntry;
34412 +} t_FmPcdCcGroupParam;
34413 +
34414 +typedef struct
34415 +{
34416 + t_Handle h_FmPcd;
34417 + uint8_t netEnvId;
34418 + uintptr_t ccTreeBaseAddr;
34419 + uint8_t numOfGrps;
34420 + t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34421 + t_List fmPortsLst;
34422 + t_FmPcdLock *p_Lock;
34423 + uint8_t numOfEntries;
34424 + uint16_t owners;
34425 + t_Handle h_FmPcdCcSavedManipParams;
34426 + bool modifiedState;
34427 + uint32_t requiredAction;
34428 + t_Handle h_IpReassemblyManip;
34429 + t_Handle h_CapwapReassemblyManip;
34430 +
34431 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34432 +} t_FmPcdCcTree;
34433 +
34434 +
34435 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List);
34436 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List);
34437 +t_Error FmPcdUpdateCcShadow (t_FmPcd *p_FmPcd, uint32_t size, uint32_t align);
34438 +
34439 +
34440 +#endif /* __FM_CC_H */
34441 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
34442 new file mode 100644
34443 index 00000000..f183d2f9
34444 --- /dev/null
34445 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
34446 @@ -0,0 +1,3242 @@
34447 +/*
34448 + * Copyright 2008-2012 Freescale Semiconductor Inc.
34449 + *
34450 + * Redistribution and use in source and binary forms, with or without
34451 + * modification, are permitted provided that the following conditions are met:
34452 + * * Redistributions of source code must retain the above copyright
34453 + * notice, this list of conditions and the following disclaimer.
34454 + * * Redistributions in binary form must reproduce the above copyright
34455 + * notice, this list of conditions and the following disclaimer in the
34456 + * documentation and/or other materials provided with the distribution.
34457 + * * Neither the name of Freescale Semiconductor nor the
34458 + * names of its contributors may be used to endorse or promote products
34459 + * derived from this software without specific prior written permission.
34460 + *
34461 + *
34462 + * ALTERNATIVELY, this software may be distributed under the terms of the
34463 + * GNU General Public License ("GPL") as published by the Free Software
34464 + * Foundation, either version 2 of that License or (at your option) any
34465 + * later version.
34466 + *
34467 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
34468 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34469 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34470 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
34471 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34472 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34473 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34474 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34475 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34476 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34477 + */
34478 +
34479 +
34480 +/******************************************************************************
34481 + @File fm_kg.c
34482 +
34483 + @Description FM PCD ...
34484 +*//***************************************************************************/
34485 +#include "std_ext.h"
34486 +#include "error_ext.h"
34487 +#include "string_ext.h"
34488 +#include "debug_ext.h"
34489 +#include "net_ext.h"
34490 +#include "fm_port_ext.h"
34491 +
34492 +#include "fm_common.h"
34493 +#include "fm_pcd.h"
34494 +#include "fm_hc.h"
34495 +#include "fm_pcd_ipc.h"
34496 +#include "fm_kg.h"
34497 +#include "fsl_fman_kg.h"
34498 +
34499 +
34500 +/****************************************/
34501 +/* static functions */
34502 +/****************************************/
34503 +
34504 +static uint32_t KgHwLock(t_Handle h_FmPcdKg)
34505 +{
34506 + ASSERT_COND(h_FmPcdKg);
34507 + return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock);
34508 +}
34509 +
34510 +static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags)
34511 +{
34512 + ASSERT_COND(h_FmPcdKg);
34513 + XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags);
34514 +}
34515 +
34516 +static uint32_t KgSchemeLock(t_Handle h_Scheme)
34517 +{
34518 + ASSERT_COND(h_Scheme);
34519 + return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34520 +}
34521 +
34522 +static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags)
34523 +{
34524 + ASSERT_COND(h_Scheme);
34525 + FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags);
34526 +}
34527 +
34528 +static bool KgSchemeFlagTryLock(t_Handle h_Scheme)
34529 +{
34530 + ASSERT_COND(h_Scheme);
34531 + return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34532 +}
34533 +
34534 +static void KgSchemeFlagUnlock(t_Handle h_Scheme)
34535 +{
34536 + ASSERT_COND(h_Scheme);
34537 + FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34538 +}
34539 +
34540 +static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar)
34541 +{
34542 +
34543 + struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
34544 +
34545 + if (fman_kg_write_ar_wait(regs, fmkg_ar))
34546 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation"));
34547 +
34548 + return E_OK;
34549 +}
34550 +
34551 +static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code)
34552 +{
34553 + int i;
34554 +
34555 + switch (code)
34556 + {
34557 + case (KG_SCH_GEN_PARSE_RESULT_N_FQID):
34558 + case (KG_SCH_GEN_DEFAULT):
34559 + case (KG_SCH_GEN_NEXTHDR):
34560 + for (i=0 ; i<numOfSwDefaults ; i++)
34561 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA)
34562 + return swDefaults[i].dfltSelect;
34563 + break;
34564 + case (KG_SCH_GEN_SHIM1):
34565 + case (KG_SCH_GEN_SHIM2):
34566 + case (KG_SCH_GEN_IP_PID_NO_V):
34567 + case (KG_SCH_GEN_ETH_NO_V):
34568 + case (KG_SCH_GEN_SNAP_NO_V):
34569 + case (KG_SCH_GEN_VLAN1_NO_V):
34570 + case (KG_SCH_GEN_VLAN2_NO_V):
34571 + case (KG_SCH_GEN_ETH_TYPE_NO_V):
34572 + case (KG_SCH_GEN_PPP_NO_V):
34573 + case (KG_SCH_GEN_MPLS1_NO_V):
34574 + case (KG_SCH_GEN_MPLS_LAST_NO_V):
34575 + case (KG_SCH_GEN_L3_NO_V):
34576 + case (KG_SCH_GEN_IP2_NO_V):
34577 + case (KG_SCH_GEN_GRE_NO_V):
34578 + case (KG_SCH_GEN_L4_NO_V):
34579 + for (i=0 ; i<numOfSwDefaults ; i++)
34580 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V)
34581 + return swDefaults[i].dfltSelect;
34582 + break;
34583 + case (KG_SCH_GEN_START_OF_FRM):
34584 + case (KG_SCH_GEN_ETH):
34585 + case (KG_SCH_GEN_SNAP):
34586 + case (KG_SCH_GEN_VLAN1):
34587 + case (KG_SCH_GEN_VLAN2):
34588 + case (KG_SCH_GEN_ETH_TYPE):
34589 + case (KG_SCH_GEN_PPP):
34590 + case (KG_SCH_GEN_MPLS1):
34591 + case (KG_SCH_GEN_MPLS2):
34592 + case (KG_SCH_GEN_MPLS3):
34593 + case (KG_SCH_GEN_MPLS_LAST):
34594 + case (KG_SCH_GEN_IPV4):
34595 + case (KG_SCH_GEN_IPV6):
34596 + case (KG_SCH_GEN_IPV4_TUNNELED):
34597 + case (KG_SCH_GEN_IPV6_TUNNELED):
34598 + case (KG_SCH_GEN_MIN_ENCAP):
34599 + case (KG_SCH_GEN_GRE):
34600 + case (KG_SCH_GEN_TCP):
34601 + case (KG_SCH_GEN_UDP):
34602 + case (KG_SCH_GEN_IPSEC_AH):
34603 + case (KG_SCH_GEN_SCTP):
34604 + case (KG_SCH_GEN_DCCP):
34605 + case (KG_SCH_GEN_IPSEC_ESP):
34606 + for (i=0 ; i<numOfSwDefaults ; i++)
34607 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA)
34608 + return swDefaults[i].dfltSelect;
34609 + break;
34610 + default:
34611 + break;
34612 + }
34613 +
34614 + return e_FM_PCD_KG_DFLT_ILLEGAL;
34615 +}
34616 +
34617 +static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset)
34618 +{
34619 + *p_Offset = 0;
34620 +
34621 + switch (src)
34622 + {
34623 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
34624 + return KG_SCH_GEN_START_OF_FRM;
34625 + case (e_FM_PCD_EXTRACT_FROM_DFLT_VALUE):
34626 + return KG_SCH_GEN_DEFAULT;
34627 + case (e_FM_PCD_EXTRACT_FROM_PARSE_RESULT):
34628 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34629 + case (e_FM_PCD_EXTRACT_FROM_ENQ_FQID):
34630 + *p_Offset = 32;
34631 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34632 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
34633 + return KG_SCH_GEN_NEXTHDR;
34634 + default:
34635 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
34636 + return 0;
34637 + }
34638 +}
34639 +
34640 +static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation)
34641 +{
34642 + if (!ignoreProtocolValidation)
34643 + switch (hdr)
34644 + {
34645 + case (HEADER_TYPE_NONE):
34646 + ASSERT_COND(FALSE);
34647 + case (HEADER_TYPE_ETH):
34648 + return KG_SCH_GEN_ETH;
34649 + case (HEADER_TYPE_LLC_SNAP):
34650 + return KG_SCH_GEN_SNAP;
34651 + case (HEADER_TYPE_PPPoE):
34652 + return KG_SCH_GEN_PPP;
34653 + case (HEADER_TYPE_MPLS):
34654 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34655 + return KG_SCH_GEN_MPLS1;
34656 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
34657 + return KG_SCH_GEN_MPLS2;
34658 + if (hdrIndex == e_FM_PCD_HDR_INDEX_3)
34659 + return KG_SCH_GEN_MPLS3;
34660 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34661 + return KG_SCH_GEN_MPLS_LAST;
34662 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34663 + return 0;
34664 + case (HEADER_TYPE_IPv4):
34665 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34666 + return KG_SCH_GEN_IPV4;
34667 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34668 + return KG_SCH_GEN_IPV4_TUNNELED;
34669 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index"));
34670 + return 0;
34671 + case (HEADER_TYPE_IPv6):
34672 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34673 + return KG_SCH_GEN_IPV6;
34674 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34675 + return KG_SCH_GEN_IPV6_TUNNELED;
34676 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index"));
34677 + return 0;
34678 + case (HEADER_TYPE_GRE):
34679 + return KG_SCH_GEN_GRE;
34680 + case (HEADER_TYPE_TCP):
34681 + return KG_SCH_GEN_TCP;
34682 + case (HEADER_TYPE_UDP):
34683 + return KG_SCH_GEN_UDP;
34684 + case (HEADER_TYPE_IPSEC_AH):
34685 + return KG_SCH_GEN_IPSEC_AH;
34686 + case (HEADER_TYPE_IPSEC_ESP):
34687 + return KG_SCH_GEN_IPSEC_ESP;
34688 + case (HEADER_TYPE_SCTP):
34689 + return KG_SCH_GEN_SCTP;
34690 + case (HEADER_TYPE_DCCP):
34691 + return KG_SCH_GEN_DCCP;
34692 + default:
34693 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34694 + return 0;
34695 + }
34696 + else
34697 + switch (hdr)
34698 + {
34699 + case (HEADER_TYPE_NONE):
34700 + ASSERT_COND(FALSE);
34701 + case (HEADER_TYPE_ETH):
34702 + return KG_SCH_GEN_ETH_NO_V;
34703 + case (HEADER_TYPE_LLC_SNAP):
34704 + return KG_SCH_GEN_SNAP_NO_V;
34705 + case (HEADER_TYPE_PPPoE):
34706 + return KG_SCH_GEN_PPP_NO_V;
34707 + case (HEADER_TYPE_MPLS):
34708 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34709 + return KG_SCH_GEN_MPLS1_NO_V;
34710 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34711 + return KG_SCH_GEN_MPLS_LAST_NO_V;
34712 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) )
34713 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported"));
34714 + else
34715 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34716 + return 0;
34717 + case (HEADER_TYPE_IPv4):
34718 + case (HEADER_TYPE_IPv6):
34719 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34720 + return KG_SCH_GEN_L3_NO_V;
34721 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34722 + return KG_SCH_GEN_IP2_NO_V;
34723 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
34724 + case (HEADER_TYPE_MINENCAP):
34725 + return KG_SCH_GEN_IP2_NO_V;
34726 + case (HEADER_TYPE_USER_DEFINED_L3):
34727 + return KG_SCH_GEN_L3_NO_V;
34728 + case (HEADER_TYPE_GRE):
34729 + return KG_SCH_GEN_GRE_NO_V;
34730 + case (HEADER_TYPE_TCP):
34731 + case (HEADER_TYPE_UDP):
34732 + case (HEADER_TYPE_IPSEC_AH):
34733 + case (HEADER_TYPE_IPSEC_ESP):
34734 + case (HEADER_TYPE_SCTP):
34735 + case (HEADER_TYPE_DCCP):
34736 + return KG_SCH_GEN_L4_NO_V;
34737 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
34738 + return KG_SCH_GEN_SHIM1;
34739 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
34740 + return KG_SCH_GEN_SHIM2;
34741 + default:
34742 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34743 + return 0;
34744 + }
34745 +}
34746 +static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex)
34747 +{
34748 + if (!ignoreProtocolValidation)
34749 + switch (hdr)
34750 + {
34751 + case (HEADER_TYPE_NONE):
34752 + ASSERT_COND(FALSE);
34753 + break;
34754 + case (HEADER_TYPE_ETH):
34755 + switch (field.eth)
34756 + {
34757 + case (NET_HEADER_FIELD_ETH_TYPE):
34758 + return KG_SCH_GEN_ETH_TYPE;
34759 + default:
34760 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34761 + return 0;
34762 + }
34763 + break;
34764 + case (HEADER_TYPE_VLAN):
34765 + switch (field.vlan)
34766 + {
34767 + case (NET_HEADER_FIELD_VLAN_TCI):
34768 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34769 + return KG_SCH_GEN_VLAN1;
34770 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34771 + return KG_SCH_GEN_VLAN2;
34772 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34773 + return 0;
34774 + }
34775 + break;
34776 + case (HEADER_TYPE_MPLS):
34777 + case (HEADER_TYPE_IPSEC_AH):
34778 + case (HEADER_TYPE_IPSEC_ESP):
34779 + case (HEADER_TYPE_LLC_SNAP):
34780 + case (HEADER_TYPE_PPPoE):
34781 + case (HEADER_TYPE_IPv4):
34782 + case (HEADER_TYPE_IPv6):
34783 + case (HEADER_TYPE_GRE):
34784 + case (HEADER_TYPE_MINENCAP):
34785 + case (HEADER_TYPE_USER_DEFINED_L3):
34786 + case (HEADER_TYPE_TCP):
34787 + case (HEADER_TYPE_UDP):
34788 + case (HEADER_TYPE_SCTP):
34789 + case (HEADER_TYPE_DCCP):
34790 + case (HEADER_TYPE_USER_DEFINED_L4):
34791 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34792 + return 0;
34793 + default:
34794 + break;
34795 +
34796 + }
34797 + else
34798 + switch (hdr)
34799 + {
34800 + case (HEADER_TYPE_NONE):
34801 + ASSERT_COND(FALSE);
34802 + break;
34803 + case (HEADER_TYPE_ETH):
34804 + switch (field.eth)
34805 + {
34806 + case (NET_HEADER_FIELD_ETH_TYPE):
34807 + return KG_SCH_GEN_ETH_TYPE_NO_V;
34808 + default:
34809 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34810 + return 0;
34811 + }
34812 + break;
34813 + case (HEADER_TYPE_VLAN):
34814 + switch (field.vlan)
34815 + {
34816 + case (NET_HEADER_FIELD_VLAN_TCI) :
34817 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34818 + return KG_SCH_GEN_VLAN1_NO_V;
34819 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34820 + return KG_SCH_GEN_VLAN2_NO_V;
34821 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34822 + return 0;
34823 + }
34824 + break;
34825 + case (HEADER_TYPE_IPv4):
34826 + switch (field.ipv4)
34827 + {
34828 + case (NET_HEADER_FIELD_IPv4_PROTO):
34829 + return KG_SCH_GEN_IP_PID_NO_V;
34830 + default:
34831 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34832 + return 0;
34833 + }
34834 + break;
34835 + case (HEADER_TYPE_IPv6):
34836 + switch (field.ipv6)
34837 + {
34838 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34839 + return KG_SCH_GEN_IP_PID_NO_V;
34840 + default:
34841 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34842 + return 0;
34843 + }
34844 + break;
34845 + case (HEADER_TYPE_MPLS):
34846 + case (HEADER_TYPE_LLC_SNAP):
34847 + case (HEADER_TYPE_PPPoE):
34848 + case (HEADER_TYPE_GRE):
34849 + case (HEADER_TYPE_MINENCAP):
34850 + case (HEADER_TYPE_USER_DEFINED_L3):
34851 + case (HEADER_TYPE_TCP):
34852 + case (HEADER_TYPE_UDP):
34853 + case (HEADER_TYPE_IPSEC_AH):
34854 + case (HEADER_TYPE_IPSEC_ESP):
34855 + case (HEADER_TYPE_SCTP):
34856 + case (HEADER_TYPE_DCCP):
34857 + case (HEADER_TYPE_USER_DEFINED_L4):
34858 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34859 + return 0;
34860 + default:
34861 + break;
34862 + }
34863 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));
34864 + return 0;
34865 +}
34866 +
34867 +static t_KnownFieldsMasks GetKnownProtMask(t_FmPcd *p_FmPcd, e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
34868 +{
34869 + UNUSED(p_FmPcd);
34870 +
34871 + switch (hdr)
34872 + {
34873 + case (HEADER_TYPE_NONE):
34874 + ASSERT_COND(FALSE);
34875 + break;
34876 + case (HEADER_TYPE_ETH):
34877 + switch (field.eth)
34878 + {
34879 + case (NET_HEADER_FIELD_ETH_DA):
34880 + return KG_SCH_KN_MACDST;
34881 + case (NET_HEADER_FIELD_ETH_SA):
34882 + return KG_SCH_KN_MACSRC;
34883 + case (NET_HEADER_FIELD_ETH_TYPE):
34884 + return KG_SCH_KN_ETYPE;
34885 + default:
34886 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34887 + return 0;
34888 + }
34889 + case (HEADER_TYPE_LLC_SNAP):
34890 + switch (field.llcSnap)
34891 + {
34892 + case (NET_HEADER_FIELD_LLC_SNAP_TYPE):
34893 + return KG_SCH_KN_ETYPE;
34894 + default:
34895 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34896 + return 0;
34897 + }
34898 + case (HEADER_TYPE_VLAN):
34899 + switch (field.vlan)
34900 + {
34901 + case (NET_HEADER_FIELD_VLAN_TCI):
34902 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34903 + return KG_SCH_KN_TCI1;
34904 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34905 + return KG_SCH_KN_TCI2;
34906 + else
34907 + {
34908 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34909 + return 0;
34910 + }
34911 + default:
34912 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34913 + return 0;
34914 + }
34915 + case (HEADER_TYPE_MPLS):
34916 + switch (field.mpls)
34917 + {
34918 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
34919 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34920 + return KG_SCH_KN_MPLS1;
34921 + if (index == e_FM_PCD_HDR_INDEX_2)
34922 + return KG_SCH_KN_MPLS2;
34923 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34924 + return KG_SCH_KN_MPLS_LAST;
34925 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
34926 + return 0;
34927 + default:
34928 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34929 + return 0;
34930 + }
34931 + case (HEADER_TYPE_IPv4):
34932 + switch (field.ipv4)
34933 + {
34934 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
34935 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34936 + return KG_SCH_KN_IPSRC1;
34937 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34938 + return KG_SCH_KN_IPSRC2;
34939 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34940 + return 0;
34941 + case (NET_HEADER_FIELD_IPv4_DST_IP):
34942 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34943 + return KG_SCH_KN_IPDST1;
34944 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34945 + return KG_SCH_KN_IPDST2;
34946 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34947 + return 0;
34948 + case (NET_HEADER_FIELD_IPv4_PROTO):
34949 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34950 + return KG_SCH_KN_PTYPE1;
34951 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34952 + return KG_SCH_KN_PTYPE2;
34953 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34954 + return 0;
34955 + case (NET_HEADER_FIELD_IPv4_TOS):
34956 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34957 + return KG_SCH_KN_IPTOS_TC1;
34958 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34959 + return KG_SCH_KN_IPTOS_TC2;
34960 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34961 + return 0;
34962 + default:
34963 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34964 + return 0;
34965 + }
34966 + case (HEADER_TYPE_IPv6):
34967 + switch (field.ipv6)
34968 + {
34969 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
34970 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34971 + return KG_SCH_KN_IPSRC1;
34972 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34973 + return KG_SCH_KN_IPSRC2;
34974 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34975 + return 0;
34976 + case (NET_HEADER_FIELD_IPv6_DST_IP):
34977 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34978 + return KG_SCH_KN_IPDST1;
34979 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34980 + return KG_SCH_KN_IPDST2;
34981 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34982 + return 0;
34983 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34984 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34985 + return KG_SCH_KN_PTYPE1;
34986 + if (index == e_FM_PCD_HDR_INDEX_2)
34987 + return KG_SCH_KN_PTYPE2;
34988 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34989 +#ifdef FM_KG_NO_IPPID_SUPPORT
34990 + if (p_FmPcd->fmRevInfo.majorRev < 6)
34991 + return KG_SCH_KN_PTYPE2;
34992 +#endif /* FM_KG_NO_IPPID_SUPPORT */
34993 + return KG_SCH_KN_IPPID;
34994 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34995 + return 0;
34996 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
34997 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34998 + return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1);
34999 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
35000 + return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2);
35001 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
35002 + return 0;
35003 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC):
35004 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
35005 + return KG_SCH_KN_IPTOS_TC1;
35006 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
35007 + return KG_SCH_KN_IPTOS_TC2;
35008 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
35009 + return 0;
35010 + case (NET_HEADER_FIELD_IPv6_FL):
35011 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
35012 + return KG_SCH_KN_IPV6FL1;
35013 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
35014 + return KG_SCH_KN_IPV6FL2;
35015 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
35016 + return 0;
35017 + default:
35018 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35019 + return 0;
35020 + }
35021 + case (HEADER_TYPE_GRE):
35022 + switch (field.gre)
35023 + {
35024 + case (NET_HEADER_FIELD_GRE_TYPE):
35025 + return KG_SCH_KN_GREPTYPE;
35026 + default:
35027 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35028 + return 0;
35029 + }
35030 + case (HEADER_TYPE_MINENCAP):
35031 + switch (field.minencap)
35032 + {
35033 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
35034 + return KG_SCH_KN_IPSRC2;
35035 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
35036 + return KG_SCH_KN_IPDST2;
35037 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
35038 + return KG_SCH_KN_PTYPE2;
35039 + default:
35040 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35041 + return 0;
35042 + }
35043 + case (HEADER_TYPE_TCP):
35044 + switch (field.tcp)
35045 + {
35046 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
35047 + return KG_SCH_KN_L4PSRC;
35048 + case (NET_HEADER_FIELD_TCP_PORT_DST):
35049 + return KG_SCH_KN_L4PDST;
35050 + case (NET_HEADER_FIELD_TCP_FLAGS):
35051 + return KG_SCH_KN_TFLG;
35052 + default:
35053 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35054 + return 0;
35055 + }
35056 + case (HEADER_TYPE_UDP):
35057 + switch (field.udp)
35058 + {
35059 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
35060 + return KG_SCH_KN_L4PSRC;
35061 + case (NET_HEADER_FIELD_UDP_PORT_DST):
35062 + return KG_SCH_KN_L4PDST;
35063 + default:
35064 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35065 + return 0;
35066 + }
35067 + case (HEADER_TYPE_IPSEC_AH):
35068 + switch (field.ipsecAh)
35069 + {
35070 + case (NET_HEADER_FIELD_IPSEC_AH_SPI):
35071 + return KG_SCH_KN_IPSEC_SPI;
35072 + case (NET_HEADER_FIELD_IPSEC_AH_NH):
35073 + return KG_SCH_KN_IPSEC_NH;
35074 + default:
35075 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35076 + return 0;
35077 + }
35078 + case (HEADER_TYPE_IPSEC_ESP):
35079 + switch (field.ipsecEsp)
35080 + {
35081 + case (NET_HEADER_FIELD_IPSEC_ESP_SPI):
35082 + return KG_SCH_KN_IPSEC_SPI;
35083 + default:
35084 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35085 + return 0;
35086 + }
35087 + case (HEADER_TYPE_SCTP):
35088 + switch (field.sctp)
35089 + {
35090 + case (NET_HEADER_FIELD_SCTP_PORT_SRC):
35091 + return KG_SCH_KN_L4PSRC;
35092 + case (NET_HEADER_FIELD_SCTP_PORT_DST):
35093 + return KG_SCH_KN_L4PDST;
35094 + default:
35095 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35096 + return 0;
35097 + }
35098 + case (HEADER_TYPE_DCCP):
35099 + switch (field.dccp)
35100 + {
35101 + case (NET_HEADER_FIELD_DCCP_PORT_SRC):
35102 + return KG_SCH_KN_L4PSRC;
35103 + case (NET_HEADER_FIELD_DCCP_PORT_DST):
35104 + return KG_SCH_KN_L4PDST;
35105 + default:
35106 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35107 + return 0;
35108 + }
35109 + case (HEADER_TYPE_PPPoE):
35110 + switch (field.pppoe)
35111 + {
35112 + case (NET_HEADER_FIELD_PPPoE_PID):
35113 + return KG_SCH_KN_PPPID;
35114 + case (NET_HEADER_FIELD_PPPoE_SID):
35115 + return KG_SCH_KN_PPPSID;
35116 + default:
35117 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35118 + return 0;
35119 + }
35120 + default:
35121 + break;
35122 +
35123 + }
35124 +
35125 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35126 + return 0;
35127 +}
35128 +
35129 +
35130 +static uint8_t GetKnownFieldId(uint32_t bitMask)
35131 +{
35132 + uint8_t cnt = 0;
35133 +
35134 + while (bitMask)
35135 + if (bitMask & 0x80000000)
35136 + break;
35137 + else
35138 + {
35139 + cnt++;
35140 + bitMask <<= 1;
35141 + }
35142 + return cnt;
35143 +
35144 +}
35145 +
35146 +static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid)
35147 +{
35148 + uint8_t i, mask, numOfOnesToClear, walking1Mask = 1;
35149 +
35150 + /* bitOffset 1-7 --> mask 0x1-0x7F */
35151 + if (bitOffset<8)
35152 + {
35153 + mask = 0;
35154 + for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1)
35155 + mask |= walking1Mask;
35156 + }
35157 + else
35158 + {
35159 + mask = 0xFF;
35160 + numOfOnesToClear = 0;
35161 + if (fqid && bitOffset>24)
35162 + /* bitOffset 25-31 --> mask 0xFE-0x80 */
35163 + numOfOnesToClear = (uint8_t)(bitOffset-24);
35164 + else
35165 + /* bitOffset 9-15 --> mask 0xFE-0x80 */
35166 + if (!fqid && bitOffset>8)
35167 + numOfOnesToClear = (uint8_t)(bitOffset-8);
35168 + for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1)
35169 + mask &= ~walking1Mask;
35170 + /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/
35171 + }
35172 + return mask;
35173 +}
35174 +
35175 +static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
35176 +{
35177 + t_FmPcdKg *p_FmPcdKg;
35178 + t_FmPcdKgScheme *p_Scheme;
35179 + uint32_t intFlags;
35180 + uint8_t relativeSchemeId;
35181 + int i;
35182 +
35183 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
35184 +
35185 + /* for each scheme - update owners counters */
35186 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
35187 + {
35188 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
35189 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
35190 +
35191 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
35192 +
35193 + /* increment owners number */
35194 + intFlags = KgSchemeLock(p_Scheme);
35195 + p_Scheme->owners++;
35196 + KgSchemeUnlock(p_Scheme, intFlags);
35197 + }
35198 +}
35199 +
35200 +static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
35201 +{
35202 + t_FmPcdKg *p_FmPcdKg;
35203 + t_FmPcdKgScheme *p_Scheme;
35204 + uint32_t intFlags;
35205 + uint8_t relativeSchemeId;
35206 + int i;
35207 +
35208 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
35209 +
35210 + /* for each scheme - update owners counters */
35211 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
35212 + {
35213 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
35214 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
35215 +
35216 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
35217 +
35218 + /* increment owners number */
35219 + ASSERT_COND(p_Scheme->owners);
35220 + intFlags = KgSchemeLock(p_Scheme);
35221 + p_Scheme->owners--;
35222 + KgSchemeUnlock(p_Scheme, intFlags);
35223 + }
35224 +}
35225 +
35226 +static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set)
35227 +{
35228 + /* this routine is locked by the calling routine */
35229 + ASSERT_COND(p_Scheme);
35230 + ASSERT_COND(p_Scheme->valid);
35231 +
35232 + if (set)
35233 + p_Scheme->requiredActionFlag = TRUE;
35234 + else
35235 + {
35236 + p_Scheme->requiredAction = 0;
35237 + p_Scheme->requiredActionFlag = FALSE;
35238 + }
35239 +}
35240 +
35241 +static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add)
35242 +{
35243 + struct fman_kg_regs *p_KgRegs;
35244 +
35245 + uint32_t tmpKgarReg = 0, intFlags;
35246 + t_Error err = E_OK;
35247 +
35248 + /* The calling routine had locked the port, so for each port only one core can access
35249 + * (so we don't need a lock here) */
35250 +
35251 + if (p_FmPcd->h_Hc)
35252 + return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add);
35253 +
35254 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35255 +
35256 + tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
35257 + /* lock a common KG reg */
35258 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
35259 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35260 + if (err)
35261 + {
35262 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35263 + RETURN_ERROR(MINOR, err, NO_MSG);
35264 + }
35265 +
35266 + fman_kg_write_sp(p_KgRegs, spReg, add);
35267 +
35268 + tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
35269 +
35270 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35271 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35272 + return err;
35273 +}
35274 +
35275 +static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg)
35276 +{
35277 + struct fman_kg_regs *p_KgRegs;
35278 + uint32_t tmpKgarReg, intFlags;
35279 + t_Error err;
35280 +
35281 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35282 +
35283 + if (p_FmPcd->h_Hc)
35284 + {
35285 + err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg);
35286 + return err;
35287 + }
35288 +
35289 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
35290 + fman_kg_write_cpp(p_KgRegs, cppReg);
35291 + tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
35292 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35293 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35294 +
35295 + return err;
35296 +}
35297 +
35298 +static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId)
35299 +{
35300 + uint32_t tmpKgpeCpp;
35301 +
35302 + tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8);
35303 + tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT);
35304 +
35305 + return tmpKgpeCpp;
35306 +}
35307 +
35308 +static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
35309 +{
35310 + uint32_t tmpKgpeCpp = 0;
35311 +
35312 + tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId);
35313 + return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp);
35314 +}
35315 +
35316 +static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
35317 +{
35318 + KgWriteCpp(p_FmPcd, hardwarePortId, 0);
35319 +}
35320 +
35321 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
35322 +static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId)
35323 +{
35324 + return (uint32_t)(FM_KG_KGAR_GO |
35325 + FM_KG_KGAR_READ |
35326 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
35327 + DUMMY_PORT_ID |
35328 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
35329 + FM_PCD_KG_KGAR_WSEL_MASK);
35330 +
35331 + /* if we ever want to write 1 by 1, use:
35332 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
35333 + */
35334 +}
35335 +#endif /* (defined(DEBUG_ERRORS) && ... */
35336 +
35337 +static void PcdKgErrorException(t_Handle h_FmPcd)
35338 +{
35339 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
35340 + uint32_t event,schemeIndexes = 0, index = 0;
35341 + struct fman_kg_regs *p_KgRegs;
35342 +
35343 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
35344 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35345 + fman_kg_get_event(p_KgRegs, &event, &schemeIndexes);
35346 +
35347 + if (event & FM_EX_KG_DOUBLE_ECC)
35348 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC);
35349 + if (event & FM_EX_KG_KEYSIZE_OVERFLOW)
35350 + {
35351 + if (schemeIndexes)
35352 + {
35353 + while (schemeIndexes)
35354 + {
35355 + if (schemeIndexes & 0x1)
35356 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index));
35357 + schemeIndexes >>= 1;
35358 + index+=1;
35359 + }
35360 + }
35361 + else /* this should happen only when interrupt is forced. */
35362 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW);
35363 + }
35364 +}
35365 +
35366 +static t_Error KgInitGuest(t_FmPcd *p_FmPcd)
35367 +{
35368 + t_Error err = E_OK;
35369 + t_FmPcdIpcKgSchemesParams kgAlloc;
35370 + uint32_t replyLength;
35371 + t_FmPcdIpcReply reply;
35372 + t_FmPcdIpcMsg msg;
35373 +
35374 + ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID);
35375 +
35376 + /* in GUEST_PARTITION, we use the IPC */
35377 + memset(&reply, 0, sizeof(reply));
35378 + memset(&msg, 0, sizeof(msg));
35379 + memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams));
35380 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
35381 + kgAlloc.guestId = p_FmPcd->guestId;
35382 + msg.msgId = FM_PCD_ALLOC_KG_SCHEMES;
35383 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
35384 + replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t);
35385 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
35386 + (uint8_t*)&msg,
35387 + sizeof(msg.msgId) + sizeof(kgAlloc),
35388 + (uint8_t*)&reply,
35389 + &replyLength,
35390 + NULL,
35391 + NULL)) != E_OK)
35392 + RETURN_ERROR(MAJOR, err, NO_MSG);
35393 + if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)))
35394 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
35395 + memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t));
35396 +
35397 + return (t_Error)reply.error;
35398 +}
35399 +
35400 +static t_Error KgInitMaster(t_FmPcd *p_FmPcd)
35401 +{
35402 + t_Error err = E_OK;
35403 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35404 +
35405 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
35406 +
35407 + if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)
35408 + FmEnableRamsEcc(p_FmPcd->h_Fm);
35409 +
35410 + fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd));
35411 +
35412 + /* register even if no interrupts enabled, to allow future enablement */
35413 + FmRegisterIntr(p_FmPcd->h_Fm,
35414 + e_FM_MOD_KG,
35415 + 0,
35416 + e_FM_INTR_TYPE_ERR,
35417 + PcdKgErrorException,
35418 + p_FmPcd);
35419 +
35420 + fman_kg_enable_scheme_interrupts(p_Regs);
35421 +
35422 + if (p_FmPcd->p_FmPcdKg->numOfSchemes)
35423 + {
35424 + err = FmPcdKgAllocSchemes(p_FmPcd,
35425 + p_FmPcd->p_FmPcdKg->numOfSchemes,
35426 + p_FmPcd->guestId,
35427 + p_FmPcd->p_FmPcdKg->schemesIds);
35428 + if (err)
35429 + RETURN_ERROR(MINOR, err, NO_MSG);
35430 + }
35431 +
35432 + return E_OK;
35433 +}
35434 +
35435 +static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35436 +{
35437 + ASSERT_COND(!p_Scheme->valid);
35438 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35439 + FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35440 + p_Scheme->valid = TRUE;
35441 +}
35442 +
35443 +static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35444 +{
35445 + if (p_Scheme->owners)
35446 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to"));
35447 +
35448 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35449 + FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35450 + p_Scheme->valid = FALSE;
35451 +
35452 + return E_OK;
35453 +}
35454 +
35455 +static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme,
35456 + t_FmPcdKgSchemeParams *p_SchemeParams,
35457 + struct fman_kg_scheme_regs *p_SchemeRegs)
35458 +{
35459 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd);
35460 + uint32_t grpBits = 0;
35461 + uint8_t grpBase;
35462 + bool direct=TRUE, absolute=FALSE;
35463 + uint16_t profileId=0, numOfProfiles=0, relativeProfileId;
35464 + t_Error err = E_OK;
35465 + int i = 0;
35466 + t_NetEnvParams netEnvParams;
35467 + uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp;
35468 + t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL;
35469 + uint8_t j, curr, idx;
35470 + uint8_t id, shift=0, code=0, offset=0, size=0;
35471 + t_FmPcdExtractEntry *p_Extract = NULL;
35472 + t_FmPcdKgExtractedOrParams *p_ExtractOr;
35473 + bool generic = FALSE;
35474 + t_KnownFieldsMasks bitMask;
35475 + e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0;
35476 + t_FmPcdKgSchemesExtracts *p_LocalExtractsArray;
35477 + uint8_t numOfSwDefaults = 0;
35478 + t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS];
35479 + uint8_t currGenId = 0;
35480 +
35481 + memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt));
35482 + memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
35483 +
35484 + if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
35485 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
35486 + ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS));
35487 +
35488 + /* by netEnv parameters, get match vector */
35489 + if (!p_SchemeParams->alwaysDirect)
35490 + {
35491 + p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv);
35492 + netEnvParams.netEnvId = p_Scheme->netEnvId;
35493 + netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits;
35494 + memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits);
35495 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
35496 + if (err)
35497 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
35498 + p_Scheme->matchVector = netEnvParams.vector;
35499 + }
35500 + else
35501 + {
35502 + p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT;
35503 + p_Scheme->netEnvId = ILLEGAL_NETENV;
35504 + }
35505 +
35506 + if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID)
35507 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid"));
35508 +
35509 + if (p_SchemeParams->bypassFqidGeneration)
35510 + {
35511 +#ifdef FM_KG_NO_BYPASS_FQID_GEN
35512 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35513 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration."));
35514 +#endif /* FM_KG_NO_BYPASS_FQID_GEN */
35515 + if (p_SchemeParams->baseFqid)
35516 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID"));
35517 + }
35518 + else
35519 + if (!p_SchemeParams->baseFqid)
35520 + DBG(WARNING, ("baseFqid is 0."));
35521 +
35522 + if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR)
35523 + {
35524 + direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct;
35525 + p_Scheme->directPlcr = direct;
35526 + absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE);
35527 + if (!direct && absolute)
35528 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared."));
35529 +
35530 + if (direct)
35531 + {
35532 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId;
35533 + numOfProfiles = 1;
35534 + }
35535 + else
35536 + {
35537 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35538 + shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35539 + numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35540 + }
35541 + }
35542 +
35543 + if (p_SchemeParams->nextEngine == e_FM_PCD_CC)
35544 + {
35545 +#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
35546 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35547 + {
35548 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35549 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration."));
35550 + }
35551 +#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */
35552 +
35553 + err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree,
35554 + p_SchemeParams->kgNextEngineParams.cc.grpId,
35555 + &grpBits,
35556 + &grpBase);
35557 + if (err)
35558 + RETURN_ERROR(MAJOR, err, NO_MSG);
35559 + p_Scheme->ccUnits = grpBits;
35560 +
35561 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35562 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35563 + {
35564 + if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile)
35565 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification."));
35566 + absolute = FALSE;
35567 + direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct;
35568 + if (direct)
35569 + {
35570 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId;
35571 + numOfProfiles = 1;
35572 + }
35573 + else
35574 + {
35575 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35576 + shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35577 + numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35578 + }
35579 + }
35580 + }
35581 +
35582 + /* if policer is used directly after KG, or after CC */
35583 + if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) ||
35584 + ((p_SchemeParams->nextEngine == e_FM_PCD_CC) &&
35585 + (p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35586 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)))
35587 + {
35588 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
35589 + if (absolute)
35590 + {
35591 + /* for absolute direct policy only, */
35592 + relativeProfileId = profileId;
35593 + err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId);
35594 + if (err)
35595 + RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset"));
35596 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId))
35597 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid."));
35598 + p_Scheme->relativeProfileId = profileId;
35599 + }
35600 + else
35601 + {
35602 + /* save relative profile id's for later check */
35603 + p_Scheme->nextRelativePlcrProfile = TRUE;
35604 + p_Scheme->relativeProfileId = profileId;
35605 + p_Scheme->numOfProfiles = numOfProfiles;
35606 + }
35607 + }
35608 + else
35609 + {
35610 + /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration
35611 + is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */
35612 + if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs)
35613 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35614 + ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID"));
35615 + if (p_SchemeParams->bypassFqidGeneration &&
35616 + p_SchemeParams->useHash &&
35617 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids)
35618 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35619 + ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID"));
35620 + }
35621 +
35622 + /* configure all 21 scheme registers */
35623 + tmpReg = KG_SCH_MODE_EN;
35624 + switch (p_SchemeParams->nextEngine)
35625 + {
35626 + case (e_FM_PCD_PLCR):
35627 + /* add to mode register - NIA */
35628 + tmpReg |= KG_SCH_MODE_NIA_PLCR;
35629 + tmpReg |= NIA_ENG_PLCR;
35630 + tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0);
35631 + /* initialize policer profile command - */
35632 + /* configure kgse_ppc */
35633 + if (direct)
35634 + /* use profileId as base, other fields are 0 */
35635 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35636 + else
35637 + {
35638 + if (shift > MAX_PP_SHIFT)
35639 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35640 +
35641 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35642 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35643 +
35644 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35645 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35646 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35647 + ppcTmp |= (uint32_t)profileId;
35648 +
35649 + p_SchemeRegs->kgse_ppc = ppcTmp;
35650 + }
35651 + break;
35652 + case (e_FM_PCD_CC):
35653 + /* mode reg - define NIA */
35654 + tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
35655 +
35656 + p_SchemeRegs->kgse_ccbs = grpBits;
35657 + tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT);
35658 +
35659 + if (p_SchemeParams->kgNextEngineParams.cc.plcrNext)
35660 + {
35661 + if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)
35662 + {
35663 + /* find out if absolute or relative */
35664 + if (absolute)
35665 + 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"));
35666 + if (direct)
35667 + {
35668 + /* mask = 0, base = directProfileId */
35669 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35670 + }
35671 + else
35672 + {
35673 + if (shift > MAX_PP_SHIFT)
35674 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35675 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35676 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35677 +
35678 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35679 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35680 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35681 + ppcTmp |= (uint32_t)profileId;
35682 +
35683 + p_SchemeRegs->kgse_ppc = ppcTmp;
35684 + }
35685 + }
35686 + }
35687 + break;
35688 + case (e_FM_PCD_DONE):
35689 + if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME)
35690 + tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
35691 + else
35692 + tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
35693 + break;
35694 + default:
35695 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported"));
35696 + }
35697 + p_SchemeRegs->kgse_mode = tmpReg;
35698 +
35699 + p_SchemeRegs->kgse_mv = p_Scheme->matchVector;
35700 +
35701 +#if (DPAA_VERSION >= 11)
35702 + if (p_SchemeParams->overrideStorageProfile)
35703 + {
35704 + p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE;
35705 +
35706 + if (p_SchemeParams->storageProfile.direct)
35707 + {
35708 + profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId;
35709 + shift = 0;
35710 + numOfProfiles = 1;
35711 + }
35712 + else
35713 + {
35714 + profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35715 + shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift;
35716 + numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles;
35717 + }
35718 + if (shift > MAX_SP_SHIFT)
35719 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT));
35720 +
35721 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35722 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35723 +
35724 + tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT;
35725 + tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT);
35726 + tmpReg |= (uint32_t)profileId;
35727 +
35728 +
35729 + p_SchemeRegs->kgse_vsp = tmpReg;
35730 +
35731 + p_Scheme->vspe = TRUE;
35732 +
35733 + }
35734 + else
35735 + p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
35736 +#endif /* (DPAA_VERSION >= 11) */
35737 +
35738 + if (p_SchemeParams->useHash)
35739 + {
35740 + p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams;
35741 +
35742 + if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
35743 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range"));
35744 +
35745 + /* configure kgse_dv0 */
35746 + p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0;
35747 +
35748 + /* configure kgse_dv1 */
35749 + p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1;
35750 +
35751 + if (!p_SchemeParams->bypassFqidGeneration)
35752 + {
35753 + if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids))
35754 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2"));
35755 + if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid)
35756 + DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues."));
35757 + }
35758 +
35759 + /* configure kgse_ekdv */
35760 + tmpReg = 0;
35761 + for ( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++)
35762 + {
35763 + switch (p_KeyAndHash->dflts[i].type)
35764 + {
35765 + case (e_FM_PCD_KG_MAC_ADDR):
35766 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT);
35767 + break;
35768 + case (e_FM_PCD_KG_TCI):
35769 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT);
35770 + break;
35771 + case (e_FM_PCD_KG_ENET_TYPE):
35772 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT);
35773 + break;
35774 + case (e_FM_PCD_KG_PPP_SESSION_ID):
35775 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT);
35776 + break;
35777 + case (e_FM_PCD_KG_PPP_PROTOCOL_ID):
35778 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT);
35779 + break;
35780 + case (e_FM_PCD_KG_MPLS_LABEL):
35781 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT);
35782 + break;
35783 + case (e_FM_PCD_KG_IP_ADDR):
35784 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT);
35785 + break;
35786 + case (e_FM_PCD_KG_PROTOCOL_TYPE):
35787 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT);
35788 + break;
35789 + case (e_FM_PCD_KG_IP_TOS_TC):
35790 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT);
35791 + break;
35792 + case (e_FM_PCD_KG_IPV6_FLOW_LABEL):
35793 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35794 + break;
35795 + case (e_FM_PCD_KG_IPSEC_SPI):
35796 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT);
35797 + break;
35798 + case (e_FM_PCD_KG_L4_PORT):
35799 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35800 + break;
35801 + case (e_FM_PCD_KG_TCP_FLAG):
35802 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT);
35803 + break;
35804 + case (e_FM_PCD_KG_GENERIC_FROM_DATA):
35805 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA;
35806 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35807 + numOfSwDefaults ++;
35808 + break;
35809 + case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V):
35810 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V;
35811 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35812 + numOfSwDefaults ++;
35813 + break;
35814 + case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA):
35815 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
35816 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35817 + numOfSwDefaults ++;
35818 + break;
35819 + default:
35820 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35821 + }
35822 + }
35823 + p_SchemeRegs->kgse_ekdv = tmpReg;
35824 +
35825 + p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts));
35826 + if (!p_LocalExtractsArray)
35827 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
35828 +
35829 + /* configure kgse_ekfc and kgse_gec */
35830 + knownTmp = 0;
35831 + for ( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++)
35832 + {
35833 + p_Extract = &p_KeyAndHash->extractArray[i];
35834 + switch (p_Extract->type)
35835 + {
35836 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
35837 + knownTmp |= KG_SCH_KN_PORT_ID;
35838 + /* save in driver structure */
35839 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID);
35840 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35841 + break;
35842 + case (e_FM_PCD_EXTRACT_BY_HDR):
35843 + switch (p_Extract->extractByHdr.hdr)
35844 + {
35845 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
35846 + case (HEADER_TYPE_UDP_LITE):
35847 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35848 + break;
35849 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
35850 + case (HEADER_TYPE_UDP_ENCAP_ESP):
35851 + switch (p_Extract->extractByHdr.type)
35852 + {
35853 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35854 + /* case where extraction from ESP only */
35855 + if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE)
35856 + {
35857 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35858 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE;
35859 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35860 + }
35861 + else
35862 + {
35863 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35864 + p_Extract->extractByHdr.ignoreProtocolValidation = FALSE;
35865 + }
35866 + break;
35867 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35868 + switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp)
35869 + {
35870 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35871 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35872 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35873 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35874 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35875 + break;
35876 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35877 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35878 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35879 + /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/
35880 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35881 + break;
35882 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35883 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35884 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35885 + p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET;
35886 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35887 + break;
35888 + }
35889 + break;
35890 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35891 + switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp)
35892 + {
35893 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35894 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35895 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35896 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35897 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35898 + break;
35899 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35900 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35901 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35902 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE;
35903 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET;
35904 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35905 + break;
35906 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35907 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35908 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35909 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE;
35910 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET;
35911 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35912 + break;
35913 + }
35914 + break;
35915 + }
35916 + break;
35917 + default:
35918 + break;
35919 + }
35920 + switch (p_Extract->extractByHdr.type)
35921 + {
35922 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35923 + generic = TRUE;
35924 + /* get the header code for the generic extract */
35925 + code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation);
35926 + /* set generic register fields */
35927 + offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset;
35928 + size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size;
35929 + break;
35930 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35931 + generic = TRUE;
35932 + /* get the field code for the generic extract */
35933 + code = GetGenFieldCode(p_Extract->extractByHdr.hdr,
35934 + p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex);
35935 + offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset;
35936 + size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
35937 + break;
35938 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35939 + if (!p_Extract->extractByHdr.ignoreProtocolValidation)
35940 + {
35941 + /* if we have a known field for it - use it, otherwise use generic */
35942 + bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex,
35943 + p_Extract->extractByHdr.extractByHdrType.fullField);
35944 + if (bitMask)
35945 + {
35946 + knownTmp |= bitMask;
35947 + /* save in driver structure */
35948 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask);
35949 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35950 + }
35951 + else
35952 + generic = TRUE;
35953 + }
35954 + else
35955 + generic = TRUE;
35956 + if (generic)
35957 + {
35958 + /* tmp - till we cover more headers under generic */
35959 + XX_Free(p_LocalExtractsArray);
35960 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported"));
35961 + }
35962 + break;
35963 + default:
35964 + XX_Free(p_LocalExtractsArray);
35965 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35966 + }
35967 + break;
35968 + case (e_FM_PCD_EXTRACT_NON_HDR):
35969 + /* use generic */
35970 + generic = TRUE;
35971 + offset = 0;
35972 + /* get the field code for the generic extract */
35973 + code = GetGenCode(p_Extract->extractNonHdr.src, &offset);
35974 + offset += p_Extract->extractNonHdr.offset;
35975 + size = p_Extract->extractNonHdr.size;
35976 + break;
35977 + default:
35978 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35979 + }
35980 +
35981 + if (generic)
35982 + {
35983 + /* set generic register fields */
35984 + if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS)
35985 + {
35986 + XX_Free(p_LocalExtractsArray);
35987 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
35988 + }
35989 + if (!code)
35990 + {
35991 + XX_Free(p_LocalExtractsArray);
35992 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
35993 + }
35994 +
35995 + genTmp = KG_SCH_GEN_VALID;
35996 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
35997 + genTmp |= offset;
35998 + if ((size > MAX_KG_SCH_SIZE) || (size < 1))
35999 + {
36000 + XX_Free(p_LocalExtractsArray);
36001 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)"));
36002 + }
36003 + genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT);
36004 + swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code);
36005 + if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL)
36006 + DBG(WARNING, ("No sw default configured"));
36007 + else
36008 + genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT;
36009 +
36010 + genTmp |= KG_SCH_GEN_MASK;
36011 + p_SchemeRegs->kgse_gec[currGenId] = genTmp;
36012 + /* save in driver structure */
36013 + p_LocalExtractsArray->extractsArray[i].id = currGenId++;
36014 + p_LocalExtractsArray->extractsArray[i].known = FALSE;
36015 + generic = FALSE;
36016 + }
36017 + }
36018 + p_SchemeRegs->kgse_ekfc = knownTmp;
36019 +
36020 + selectTmp = 0;
36021 + maskTmp = 0xFFFFFFFF;
36022 + /* configure kgse_bmch, kgse_bmcl and kgse_fqb */
36023 +
36024 + if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
36025 + {
36026 + XX_Free(p_LocalExtractsArray);
36027 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS));
36028 + }
36029 + for ( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++)
36030 + {
36031 + /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */
36032 + id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id;
36033 + /* Get the shift of the select field (depending on i) */
36034 + GET_MASK_SEL_SHIFT(shift,i);
36035 + if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known)
36036 + selectTmp |= id << shift;
36037 + else
36038 + selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift;
36039 +
36040 + /* Get the shift of the offset field (depending on i) - may
36041 + be in kgse_bmch or in kgse_fqb (depending on i) */
36042 + GET_MASK_OFFSET_SHIFT(shift,i);
36043 + if (i<=1)
36044 + selectTmp |= p_KeyAndHash->masks[i].offset << shift;
36045 + else
36046 + fqbTmp |= p_KeyAndHash->masks[i].offset << shift;
36047 +
36048 + /* Get the shift of the mask field (depending on i) */
36049 + GET_MASK_SHIFT(shift,i);
36050 + /* pass all bits */
36051 + maskTmp |= KG_SCH_BITMASK_MASK << shift;
36052 + /* clear bits that need masking */
36053 + maskTmp &= ~(0xFF << shift) ;
36054 + /* set mask bits */
36055 + maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ;
36056 + }
36057 + p_SchemeRegs->kgse_bmch = selectTmp;
36058 + p_SchemeRegs->kgse_bmcl = maskTmp;
36059 + /* kgse_fqb will be written t the end of the routine */
36060 +
36061 + /* configure kgse_hc */
36062 + if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT)
36063 + {
36064 + XX_Free(p_LocalExtractsArray);
36065 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT));
36066 + }
36067 + if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT)
36068 + {
36069 + XX_Free(p_LocalExtractsArray);
36070 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT));
36071 + }
36072 +
36073 + tmpReg = 0;
36074 +
36075 + tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift);
36076 + tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
36077 +
36078 + if (p_KeyAndHash->symmetricHash)
36079 + {
36080 + if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) ||
36081 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) ||
36082 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) ||
36083 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST)))
36084 + {
36085 + XX_Free(p_LocalExtractsArray);
36086 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing"));
36087 + }
36088 + tmpReg |= KG_SCH_HASH_CONFIG_SYM;
36089 + }
36090 + p_SchemeRegs->kgse_hc = tmpReg;
36091 +
36092 + /* build the return array describing the order of the extractions */
36093 +
36094 + /* the last currGenId places of the array
36095 + are for generic extracts that are always last.
36096 + We now sort for the calculation of the order of the known
36097 + extractions we sort the known extracts between orderedArray[0] and
36098 + orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1].
36099 + for the calculation of the order of the generic extractions we use:
36100 + num_of_generic - currGenId
36101 + num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId
36102 + first_generic_index = num_of_known */
36103 + curr = 0;
36104 + for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++)
36105 + {
36106 + if (p_LocalExtractsArray->extractsArray[i].known)
36107 + {
36108 + ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId));
36109 + j = curr;
36110 + /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original
36111 + index in the user's extractions array */
36112 + /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1]
36113 + location */
36114 + while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id <
36115 + p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id))
36116 + {
36117 + p_Scheme->orderedArray[j] =
36118 + p_Scheme->orderedArray[j-1];
36119 + j--;
36120 + }
36121 + p_Scheme->orderedArray[j] = (uint8_t)i;
36122 + curr++;
36123 + }
36124 + else
36125 + {
36126 + /* index is first_generic_index + generic index (id) */
36127 + idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id);
36128 + ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY);
36129 + p_Scheme->orderedArray[idx]= (uint8_t)i;
36130 + }
36131 + }
36132 + XX_Free(p_LocalExtractsArray);
36133 + }
36134 + else
36135 + {
36136 + /* clear all unused registers: */
36137 + p_SchemeRegs->kgse_ekfc = 0;
36138 + p_SchemeRegs->kgse_ekdv = 0;
36139 + p_SchemeRegs->kgse_bmch = 0;
36140 + p_SchemeRegs->kgse_bmcl = 0;
36141 + p_SchemeRegs->kgse_hc = 0;
36142 + p_SchemeRegs->kgse_dv0 = 0;
36143 + p_SchemeRegs->kgse_dv1 = 0;
36144 + }
36145 +
36146 + if (p_SchemeParams->bypassFqidGeneration)
36147 + p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID;
36148 +
36149 + /* configure kgse_spc */
36150 + if ( p_SchemeParams->schemeCounter.update)
36151 + p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value;
36152 +
36153 +
36154 + /* check that are enough generic registers */
36155 + if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS)
36156 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
36157 +
36158 + /* extracted OR mask on Qid */
36159 + for ( i=0 ;i<p_SchemeParams->numOfUsedExtractedOrs ; i++)
36160 + {
36161 +
36162 + p_Scheme->extractedOrs = TRUE;
36163 + /* configure kgse_gec[i] */
36164 + p_ExtractOr = &p_SchemeParams->extractedOrs[i];
36165 + switch (p_ExtractOr->type)
36166 + {
36167 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
36168 + code = KG_SCH_GEN_PARSE_RESULT_N_FQID;
36169 + offset = 0;
36170 + break;
36171 + case (e_FM_PCD_EXTRACT_BY_HDR):
36172 + /* get the header code for the generic extract */
36173 + code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation);
36174 + /* set generic register fields */
36175 + offset = p_ExtractOr->extractionOffset;
36176 + break;
36177 + case (e_FM_PCD_EXTRACT_NON_HDR):
36178 + /* get the field code for the generic extract */
36179 + offset = 0;
36180 + code = GetGenCode(p_ExtractOr->src, &offset);
36181 + offset += p_ExtractOr->extractionOffset;
36182 + break;
36183 + default:
36184 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
36185 + }
36186 +
36187 + /* set generic register fields */
36188 + if (!code)
36189 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
36190 + genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID;
36191 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
36192 + genTmp |= offset;
36193 + if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile)
36194 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile"));
36195 +
36196 + /************************************************************************************
36197 + bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter
36198 + in the following way:
36199 +
36200 + Driver API and implementation:
36201 + ==============================
36202 + FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID.
36203 + if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that
36204 + are not overlapping FQID.
36205 + ------------------------
36206 + | FQID (24) |
36207 + ------------------------
36208 + --------
36209 + | | extracted OR byte
36210 + --------
36211 +
36212 + Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the
36213 + PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that
36214 + are not overlapping PP id.
36215 +
36216 + --------
36217 + | PP (8) |
36218 + --------
36219 + --------
36220 + | | extracted OR byte
36221 + --------
36222 +
36223 + HW implementation
36224 + =================
36225 + FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located
36226 + as the highest byte of that word and may be rotated to effect any part os the FQID or
36227 + the PP.
36228 + ------------------------ --------
36229 + | FQID (24) || PP (8) |
36230 + ------------------------ --------
36231 + --------
36232 + | | extracted OR byte
36233 + --------
36234 +
36235 + ************************************************************************************/
36236 +
36237 + if (p_ExtractOr->bitOffsetInFqid)
36238 + {
36239 + if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET )
36240 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)"));
36241 + if (p_ExtractOr->bitOffsetInFqid<8)
36242 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT);
36243 + else
36244 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT);
36245 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE);
36246 + }
36247 + else /* effect policer profile */
36248 + {
36249 + if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET )
36250 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)"));
36251 + p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile;
36252 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT);
36253 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE);
36254 + }
36255 +
36256 + genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT);
36257 + /* clear bits that need masking */
36258 + genTmp &= ~KG_SCH_GEN_MASK ;
36259 + /* set mask bits */
36260 + genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT);
36261 + p_SchemeRegs->kgse_gec[currGenId++] = genTmp;
36262 +
36263 + }
36264 + /* clear all unused GEC registers */
36265 + for ( i=currGenId ;i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
36266 + p_SchemeRegs->kgse_gec[i] = 0;
36267 +
36268 + /* add base Qid for this scheme */
36269 + /* add configuration for kgse_fqb */
36270 + if (p_SchemeParams->baseFqid & ~0x00FFFFFF)
36271 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1"));
36272 +
36273 + fqbTmp |= p_SchemeParams->baseFqid;
36274 + p_SchemeRegs->kgse_fqb = fqbTmp;
36275 +
36276 + p_Scheme->nextEngine = p_SchemeParams->nextEngine;
36277 + p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction;
36278 +
36279 + return E_OK;
36280 +}
36281 +
36282 +
36283 +/*****************************************************************************/
36284 +/* Inter-module API routines */
36285 +/*****************************************************************************/
36286 +
36287 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet)
36288 +{
36289 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36290 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36291 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36292 + t_Error err = E_OK;
36293 + uint32_t oredVectors = 0;
36294 + int i, j;
36295 +
36296 + /* this routine is protected by the calling routine ! */
36297 + if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS))
36298 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected."));
36299 +
36300 + /* find a new clsPlan group */
36301 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
36302 + if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used)
36303 + break;
36304 + if (i == FM_MAX_NUM_OF_PORTS)
36305 + RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available."));
36306 +
36307 + p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE;
36308 +
36309 + p_Grp->clsPlanGrpId = (uint8_t)i;
36310 +
36311 + if (p_Grp->numOfOptions == 0)
36312 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i;
36313 +
36314 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i];
36315 + p_ClsPlanGrp->netEnvId = p_Grp->netEnvId;
36316 + p_ClsPlanGrp->owners = 0;
36317 + FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId);
36318 + if (p_Grp->numOfOptions != 0)
36319 + FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId);
36320 +
36321 + p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions);
36322 + /* a minimal group of 8 is required */
36323 + if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP)
36324 + p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP;
36325 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36326 + {
36327 + err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry);
36328 +
36329 + if (err)
36330 + RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
36331 + }
36332 + else
36333 + {
36334 + t_FmPcdIpcMsg msg;
36335 + uint32_t replyLength;
36336 + t_FmPcdIpcReply reply;
36337 +
36338 + /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36339 + memset(&reply, 0, sizeof(reply));
36340 + memset(&msg, 0, sizeof(msg));
36341 + memset(&kgAlloc, 0, sizeof(kgAlloc));
36342 + kgAlloc.guestId = p_FmPcd->guestId;
36343 + kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36344 + msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN;
36345 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36346 + replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry));
36347 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36348 + (uint8_t*)&msg,
36349 + sizeof(msg.msgId) + sizeof(kgAlloc),
36350 + (uint8_t*)&reply,
36351 + &replyLength,
36352 + NULL,
36353 + NULL)) != E_OK)
36354 + RETURN_ERROR(MAJOR, err, NO_MSG);
36355 +
36356 + if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)))
36357 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36358 + if ((t_Error)reply.error != E_OK)
36359 + RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG);
36360 +
36361 + p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody);
36362 + }
36363 +
36364 + /* build classification plan entries parameters */
36365 + p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry;
36366 + p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36367 +
36368 + oredVectors = 0;
36369 + for (i = 0; i<p_Grp->numOfOptions; i++)
36370 + {
36371 + oredVectors |= p_Grp->optVectors[i];
36372 + /* save an array of used options - the indexes represent the power of 2 index */
36373 + p_ClsPlanGrp->optArray[i] = p_Grp->options[i];
36374 + }
36375 + /* set the classification plan relevant entries so that all bits
36376 + * relevant to the list of options is cleared
36377 + */
36378 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36379 + p_ClsPlanSet->vectors[j] = ~oredVectors;
36380 +
36381 + for (i = 0; i<p_Grp->numOfOptions; i++)
36382 + {
36383 + /* option i got the place 2^i in the clsPlan array. all entries that
36384 + * have bit i set, should have the vector bit cleared. So each option
36385 + * has one location that it is exclusive (1,2,4,8...) and represent the
36386 + * presence of that option only, and other locations that represent a
36387 + * combination of options.
36388 + * e.g:
36389 + * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2
36390 + * now represents a frame with ethernet-BC header - so the bit
36391 + * representing ethernet-BC should be set and all other option bits
36392 + * should be cleared.
36393 + * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit
36394 + * vector[1] set, but they also have other bits set:
36395 + * 3=1+2, options 0 and 1
36396 + * 6=2+4, options 1 and 2
36397 + * 7=1+2+4, options 0,1,and 2
36398 + * 10=2+8, options 1 and 3
36399 + * etc.
36400 + * */
36401 +
36402 + /* now for each option (i), we set their bits in all entries (j)
36403 + * that contain bit 2^i.
36404 + */
36405 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36406 + {
36407 + if (j & (1<<i))
36408 + p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i];
36409 + }
36410 + }
36411 +
36412 + return E_OK;
36413 +}
36414 +
36415 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId)
36416 +{
36417 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36418 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36419 + t_Error err;
36420 + t_FmPcdIpcMsg msg;
36421 + uint32_t replyLength;
36422 + t_FmPcdIpcReply reply;
36423 +
36424 + /* check that no port is bound to this clsPlan */
36425 + if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners)
36426 + {
36427 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to"));
36428 + return;
36429 + }
36430 +
36431 + FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN);
36432 +
36433 + if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36434 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36435 + else
36436 + FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId);
36437 +
36438 + /* free blocks */
36439 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36440 + KgFreeClsPlanEntries(h_FmPcd,
36441 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp,
36442 + p_FmPcd->guestId,
36443 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry);
36444 + else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36445 + {
36446 + memset(&reply, 0, sizeof(reply));
36447 + memset(&msg, 0, sizeof(msg));
36448 + kgAlloc.guestId = p_FmPcd->guestId;
36449 + kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp;
36450 + kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry;
36451 + msg.msgId = FM_PCD_FREE_KG_CLSPLAN;
36452 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36453 + replyLength = sizeof(uint32_t);
36454 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36455 + (uint8_t*)&msg,
36456 + sizeof(msg.msgId) + sizeof(kgAlloc),
36457 + (uint8_t*)&reply,
36458 + &replyLength,
36459 + NULL,
36460 + NULL);
36461 + if (err != E_OK)
36462 + {
36463 + REPORT_ERROR(MINOR, err, NO_MSG);
36464 + return;
36465 + }
36466 + if (replyLength != sizeof(uint32_t))
36467 + {
36468 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36469 + return;
36470 + }
36471 + if ((t_Error)reply.error != E_OK)
36472 + {
36473 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed"));
36474 + return;
36475 + }
36476 + }
36477 +
36478 + /* clear clsPlan driver structure */
36479 + memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp));
36480 +}
36481 +
36482 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add)
36483 +{
36484 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36485 + uint32_t j, schemesPerPortVector = 0;
36486 + t_FmPcdKgScheme *p_Scheme;
36487 + uint8_t i, relativeSchemeId;
36488 + uint32_t tmp, walking1Mask;
36489 + uint8_t swPortIndex = 0;
36490 +
36491 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36492 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36493 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
36494 +
36495 + /* for each scheme */
36496 + for (i = 0; i<p_BindPort->numOfSchemes; i++)
36497 + {
36498 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
36499 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
36500 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
36501 +
36502 + if (add)
36503 + {
36504 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
36505 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
36506 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
36507 + /* check netEnvId of the port against the scheme netEnvId */
36508 + if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV))
36509 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId"));
36510 +
36511 + /* if next engine is private port policer profile, we need to check that it is valid */
36512 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId);
36513 + if (p_Scheme->nextRelativePlcrProfile)
36514 + {
36515 + for (j = 0;j<p_Scheme->numOfProfiles;j++)
36516 + {
36517 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort);
36518 + if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles)
36519 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range"));
36520 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j)))
36521 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid."));
36522 + }
36523 + }
36524 + if (!p_BindPort->useClsPlan)
36525 + {
36526 + /* This check may be redundant as port is a assigned to the whole NetEnv */
36527 +
36528 + /* if this port does not use clsPlan, it may not be bound to schemes with units that contain
36529 + cls plan options. Schemes that are used only directly, should not be checked.
36530 + it also may not be bound to schemes that go to CC with units that are options - so we OR
36531 + the match vector and the grpBits (= ccUnits) */
36532 + if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits)
36533 + {
36534 + uint8_t netEnvId;
36535 + walking1Mask = 0x80000000;
36536 + netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId;
36537 + tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector;
36538 + tmp |= p_Scheme->ccUnits;
36539 + while (tmp)
36540 + {
36541 + if (tmp & walking1Mask)
36542 + {
36543 + tmp &= ~walking1Mask;
36544 + if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask))
36545 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options"));
36546 + }
36547 + walking1Mask >>= 1;
36548 + }
36549 + }
36550 + }
36551 + }
36552 + /* build vector */
36553 + schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]);
36554 + }
36555 +
36556 + *p_SpReg = schemesPerPortVector;
36557 +
36558 + return E_OK;
36559 +}
36560 +
36561 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36562 +{
36563 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36564 + uint32_t spReg;
36565 + t_Error err = E_OK;
36566 +
36567 + err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE);
36568 + if (err)
36569 + RETURN_ERROR(MAJOR, err, NO_MSG);
36570 +
36571 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE);
36572 + if (err)
36573 + RETURN_ERROR(MAJOR, err, NO_MSG);
36574 +
36575 + IncSchemeOwners(p_FmPcd, p_SchemeBind);
36576 +
36577 + return E_OK;
36578 +}
36579 +
36580 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36581 +{
36582 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36583 + uint32_t spReg;
36584 + t_Error err = E_OK;
36585 +
36586 + err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE);
36587 + if (err)
36588 + RETURN_ERROR(MAJOR, err, NO_MSG);
36589 +
36590 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE);
36591 + if (err)
36592 + RETURN_ERROR(MAJOR, err, NO_MSG);
36593 +
36594 + DecSchemeOwners(p_FmPcd, p_SchemeBind);
36595 +
36596 + return E_OK;
36597 +}
36598 +
36599 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme)
36600 +{
36601 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
36602 +
36603 + return p_Scheme->valid;
36604 +}
36605 +
36606 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId)
36607 +{
36608 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36609 +
36610 + if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT)
36611 + return TRUE;
36612 + else
36613 + return FALSE;
36614 +}
36615 +
36616 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36617 +{
36618 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36619 + uint8_t i, j;
36620 +
36621 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36622 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36623 +
36624 + /* This routine is issued only on master core of master partition -
36625 + either directly or through IPC, so no need for lock */
36626 +
36627 + for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++)
36628 + {
36629 + if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated)
36630 + {
36631 + p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE;
36632 + p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId;
36633 + p_SchemesIds[j] = i;
36634 + j++;
36635 + }
36636 + }
36637 +
36638 + if (j != numOfSchemes)
36639 + {
36640 + /* roll back */
36641 + for (j--; j; j--)
36642 + {
36643 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE;
36644 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0;
36645 + p_SchemesIds[j] = 0;
36646 + }
36647 +
36648 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found"));
36649 + }
36650 +
36651 + return E_OK;
36652 +}
36653 +
36654 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36655 +{
36656 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36657 + uint8_t i;
36658 +
36659 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36660 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36661 +
36662 + /* This routine is issued only on master core of master partition -
36663 + either directly or through IPC */
36664 +
36665 + for (i = 0; i < numOfSchemes; i++)
36666 + {
36667 + if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated)
36668 + {
36669 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated"));
36670 + }
36671 + if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId)
36672 + {
36673 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. "));
36674 + }
36675 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE;
36676 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0;
36677 + }
36678 +
36679 + return E_OK;
36680 +}
36681 +
36682 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First)
36683 +{
36684 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36685 + uint8_t numOfBlocks, blocksFound=0, first=0;
36686 + uint8_t i, j;
36687 +
36688 + /* This routine is issued only on master core of master partition -
36689 + either directly or through IPC, so no need for lock */
36690 +
36691 + if (!numOfClsPlanEntries)
36692 + return E_OK;
36693 +
36694 + if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries)))
36695 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8"));
36696 +
36697 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36698 +
36699 + /* try to find consequent blocks */
36700 + first = 0;
36701 + for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;)
36702 + {
36703 + if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated)
36704 + {
36705 + blocksFound++;
36706 + i++;
36707 + if (blocksFound == numOfBlocks)
36708 + break;
36709 + }
36710 + else
36711 + {
36712 + blocksFound = 0;
36713 + /* advance i to the next aligned address */
36714 + first = i = (uint8_t)(first + numOfBlocks);
36715 + }
36716 + }
36717 +
36718 + if (blocksFound == numOfBlocks)
36719 + {
36720 + *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP);
36721 + for (j = first; j < (first + numOfBlocks); j++)
36722 + {
36723 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE;
36724 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId;
36725 + }
36726 + return E_OK;
36727 + }
36728 + else
36729 + RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan"));
36730 +}
36731 +
36732 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base)
36733 +{
36734 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36735 + uint8_t numOfBlocks;
36736 + uint8_t i, baseBlock;
36737 +
36738 +#ifdef DISABLE_ASSERTIONS
36739 +UNUSED(guestId);
36740 +#endif /* DISABLE_ASSERTIONS */
36741 +
36742 + /* This routine is issued only on master core of master partition -
36743 + either directly or through IPC, so no need for lock */
36744 +
36745 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36746 + ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP));
36747 +
36748 + baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP);
36749 + for (i=baseBlock;i<baseBlock+numOfBlocks;i++)
36750 + {
36751 + ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated);
36752 + ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId);
36753 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE;
36754 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0;
36755 + }
36756 +}
36757 +
36758 +void KgEnable(t_FmPcd *p_FmPcd)
36759 +{
36760 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36761 +
36762 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36763 + fman_kg_enable(p_Regs);
36764 +}
36765 +
36766 +void KgDisable(t_FmPcd *p_FmPcd)
36767 +{
36768 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36769 +
36770 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36771 + fman_kg_disable(p_Regs);
36772 +}
36773 +
36774 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set)
36775 +{
36776 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36777 + struct fman_kg_cp_regs *p_FmPcdKgPortRegs;
36778 + uint32_t tmpKgarReg = 0, intFlags;
36779 + uint16_t i, j;
36780 +
36781 + /* This routine is protected by the calling routine ! */
36782 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36783 + p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs;
36784 +
36785 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36786 + for (i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)
36787 + {
36788 + tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
36789 +
36790 + for (j = i; j < i+8; j++)
36791 + {
36792 + ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1));
36793 + WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]);
36794 + }
36795 +
36796 + if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)
36797 + {
36798 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED"));
36799 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36800 + return;
36801 + }
36802 + }
36803 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36804 +}
36805 +
36806 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
36807 +{
36808 + t_FmPcdKg *p_FmPcdKg;
36809 +
36810 + UNUSED(p_FmPcd);
36811 +
36812 + if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES)
36813 + {
36814 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
36815 + ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES));
36816 + return NULL;
36817 + }
36818 +
36819 + p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg));
36820 + if (!p_FmPcdKg)
36821 + {
36822 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED"));
36823 + return NULL;
36824 + }
36825 + memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg));
36826 +
36827 +
36828 + if (FmIsMaster(p_FmPcd->h_Fm))
36829 + {
36830 + p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm));
36831 + p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions;
36832 + p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0];
36833 + }
36834 +
36835 + p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes;
36836 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes)
36837 + {
36838 + p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
36839 + DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES"));
36840 + }
36841 +
36842 + p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36843 +
36844 + return p_FmPcdKg;
36845 +}
36846 +
36847 +t_Error KgInit(t_FmPcd *p_FmPcd)
36848 +{
36849 + t_Error err = E_OK;
36850 +
36851 + p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock();
36852 + if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36853 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock"));
36854 +
36855 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36856 + err = KgInitMaster(p_FmPcd);
36857 + else
36858 + err = KgInitGuest(p_FmPcd);
36859 +
36860 + if (err != E_OK)
36861 + {
36862 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36863 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36864 + }
36865 +
36866 + return err;
36867 +}
36868 +
36869 +t_Error KgFree(t_FmPcd *p_FmPcd)
36870 +{
36871 + t_FmPcdIpcKgSchemesParams kgAlloc;
36872 + t_Error err = E_OK;
36873 + t_FmPcdIpcMsg msg;
36874 + uint32_t replyLength;
36875 + t_FmPcdIpcReply reply;
36876 +
36877 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR);
36878 +
36879 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36880 + {
36881 + err = FmPcdKgFreeSchemes(p_FmPcd,
36882 + p_FmPcd->p_FmPcdKg->numOfSchemes,
36883 + p_FmPcd->guestId,
36884 + p_FmPcd->p_FmPcdKg->schemesIds);
36885 + if (err)
36886 + RETURN_ERROR(MAJOR, err, NO_MSG);
36887 +
36888 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36889 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36890 +
36891 + return E_OK;
36892 + }
36893 +
36894 + /* guest */
36895 + memset(&reply, 0, sizeof(reply));
36896 + memset(&msg, 0, sizeof(msg));
36897 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
36898 + kgAlloc.guestId = p_FmPcd->guestId;
36899 + ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES);
36900 + memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes);
36901 + msg.msgId = FM_PCD_FREE_KG_SCHEMES;
36902 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36903 + replyLength = sizeof(uint32_t);
36904 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36905 + (uint8_t*)&msg,
36906 + sizeof(msg.msgId) + sizeof(kgAlloc),
36907 + (uint8_t*)&reply,
36908 + &replyLength,
36909 + NULL,
36910 + NULL)) != E_OK)
36911 + RETURN_ERROR(MAJOR, err, NO_MSG);
36912 + if (replyLength != sizeof(uint32_t))
36913 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36914 +
36915 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36916 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36917 +
36918 + return (t_Error)reply.error;
36919 +}
36920 +
36921 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp)
36922 +{
36923 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36924 + t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams;
36925 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36926 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
36927 + t_Error err;
36928 +
36929 + /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules,
36930 + so no need for lock here */
36931 +
36932 + memset(&grpParams, 0, sizeof(grpParams));
36933 + grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN;
36934 + p_GrpParams = &grpParams;
36935 +
36936 + p_GrpParams->netEnvId = netEnvId;
36937 +
36938 + /* Get from the NetEnv the information of the clsPlan (can be already created,
36939 + * or needs to build) */
36940 + err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams);
36941 + if (err)
36942 + RETURN_ERROR(MINOR,err,NO_MSG);
36943 +
36944 + if (p_GrpParams->grpExists)
36945 + {
36946 + /* this group was already updated (at least) in SW */
36947 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36948 + }
36949 + else
36950 + {
36951 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
36952 + if (!p_ClsPlanSet)
36953 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
36954 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
36955 + /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */
36956 + err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet);
36957 + if (err)
36958 + {
36959 + XX_Free(p_ClsPlanSet);
36960 + RETURN_ERROR(MINOR, err, NO_MSG);
36961 + }
36962 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36963 +
36964 + if (p_FmPcd->h_Hc)
36965 + {
36966 + /* write clsPlan entries to memory */
36967 + err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet);
36968 + if (err)
36969 + {
36970 + XX_Free(p_ClsPlanSet);
36971 + RETURN_ERROR(MAJOR, err, NO_MSG);
36972 + }
36973 + }
36974 + else
36975 + /* write clsPlan entries to memory */
36976 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
36977 +
36978 + XX_Free(p_ClsPlanSet);
36979 + }
36980 +
36981 + /* Set caller parameters */
36982 +
36983 + /* mark if this is an empty classification group */
36984 + if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36985 + *p_IsEmptyClsPlanGrp = TRUE;
36986 + else
36987 + *p_IsEmptyClsPlanGrp = FALSE;
36988 +
36989 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId];
36990 +
36991 + /* increment owners number */
36992 + p_ClsPlanGrp->owners++;
36993 +
36994 + /* copy options array for port */
36995 + 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));
36996 +
36997 + /* bind port to the new or existing group */
36998 + err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId);
36999 + if (err)
37000 + RETURN_ERROR(MINOR, err, NO_MSG);
37001 +
37002 + return E_OK;
37003 +}
37004 +
37005 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
37006 +{
37007 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
37008 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId];
37009 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
37010 + t_Error err;
37011 +
37012 + /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules,
37013 + so no need for lock here */
37014 +
37015 + UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId);
37016 +
37017 + /* decrement owners number */
37018 + ASSERT_COND(p_ClsPlanGrp->owners);
37019 + p_ClsPlanGrp->owners--;
37020 +
37021 + if (!p_ClsPlanGrp->owners)
37022 + {
37023 + if (p_FmPcd->h_Hc)
37024 + {
37025 + err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId);
37026 + return err;
37027 + }
37028 + else
37029 + {
37030 + /* clear clsPlan entries in memory */
37031 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
37032 + if (!p_ClsPlanSet)
37033 + {
37034 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
37035 + }
37036 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
37037 +
37038 + p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry;
37039 + p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp;
37040 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
37041 + XX_Free(p_ClsPlanSet);
37042 +
37043 + FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId);
37044 + }
37045 + }
37046 + return E_OK;
37047 +}
37048 +
37049 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId)
37050 +{
37051 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37052 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37053 +
37054 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction;
37055 +}
37056 +
37057 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId)
37058 +{
37059 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37060 +
37061 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37062 +
37063 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag;
37064 +}
37065 +
37066 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId)
37067 +{
37068 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37069 +
37070 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37071 +
37072 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr;
37073 +}
37074 +
37075 +
37076 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId)
37077 +{
37078 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37079 +
37080 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37081 +
37082 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId;
37083 +}
37084 +
37085 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId)
37086 +{
37087 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37088 +
37089 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37090 +
37091 + if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs &&
37092 + p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) ||
37093 + p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile)
37094 + return TRUE;
37095 + else
37096 + return FALSE;
37097 +
37098 +}
37099 +
37100 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId)
37101 +{
37102 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37103 +
37104 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid);
37105 +
37106 + return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine;
37107 +}
37108 +
37109 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId)
37110 +{
37111 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37112 +
37113 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37114 +
37115 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction;
37116 +}
37117 +
37118 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction)
37119 +{
37120 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
37121 +
37122 + /* this routine is protected by calling routine */
37123 +
37124 + ASSERT_COND(p_Scheme->valid);
37125 +
37126 + p_Scheme->requiredAction |= requiredAction;
37127 +}
37128 +
37129 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg)
37130 +{
37131 + return (bool)!!(schemeModeReg & KG_SCH_MODE_EN);
37132 +}
37133 +
37134 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter)
37135 +{
37136 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37137 + FM_KG_KGAR_GO |
37138 + FM_KG_KGAR_WRITE |
37139 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
37140 + DUMMY_PORT_ID |
37141 + (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0));
37142 +}
37143 +
37144 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId)
37145 +{
37146 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37147 + FM_KG_KGAR_GO |
37148 + FM_KG_KGAR_READ |
37149 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
37150 + DUMMY_PORT_ID |
37151 + FM_KG_KGAR_SCM_WSEL_UPDATE_CNT);
37152 +
37153 +}
37154 +
37155 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId)
37156 +{
37157 + return (uint32_t)(FM_KG_KGAR_GO |
37158 + FM_KG_KGAR_WRITE |
37159 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
37160 + DUMMY_PORT_ID |
37161 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37162 + FM_PCD_KG_KGAR_WSEL_MASK);
37163 +
37164 + /* if we ever want to write 1 by 1, use:
37165 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
37166 + */
37167 +}
37168 +
37169 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId)
37170 +{
37171 +
37172 + return (uint32_t)(FM_KG_KGAR_GO |
37173 + FM_KG_KGAR_WRITE |
37174 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37175 + hardwarePortId |
37176 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
37177 +}
37178 +
37179 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId)
37180 +{
37181 +
37182 + return (uint32_t)(FM_KG_KGAR_GO |
37183 + FM_KG_KGAR_READ |
37184 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37185 + hardwarePortId |
37186 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
37187 +}
37188 +
37189 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId)
37190 +{
37191 +
37192 + return (uint32_t)(FM_KG_KGAR_GO |
37193 + FM_KG_KGAR_WRITE |
37194 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37195 + hardwarePortId |
37196 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
37197 +}
37198 +
37199 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp)
37200 +{
37201 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37202 +
37203 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry;
37204 +}
37205 +
37206 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp)
37207 +{
37208 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37209 +
37210 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp;
37211 +}
37212 +
37213 +
37214 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme)
37215 +{
37216 + return ((t_FmPcdKgScheme*)h_Scheme)->schemeId;
37217 +
37218 +}
37219 +
37220 +#if (DPAA_VERSION >= 11)
37221 +bool FmPcdKgGetVspe(t_Handle h_Scheme)
37222 +{
37223 + return ((t_FmPcdKgScheme*)h_Scheme)->vspe;
37224 +
37225 +}
37226 +#endif /* (DPAA_VERSION >= 11) */
37227 +
37228 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)
37229 +{
37230 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37231 + uint8_t i;
37232 +
37233 + for (i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)
37234 + if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId)
37235 + return i;
37236 +
37237 + if (i == p_FmPcd->p_FmPcdKg->numOfSchemes)
37238 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range"));
37239 +
37240 + return FM_PCD_KG_NUM_OF_SCHEMES;
37241 +}
37242 +
37243 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId)
37244 +{
37245 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37246 +
37247 + ASSERT_COND(p_FmPcd);
37248 +
37249 + /* check that schemeId is in range */
37250 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37251 + {
37252 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37253 + return NULL;
37254 + }
37255 +
37256 + if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]))
37257 + return NULL;
37258 +
37259 + return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37260 +}
37261 +
37262 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme)
37263 +{
37264 + return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE;
37265 +}
37266 +
37267 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
37268 +{
37269 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37270 + uint8_t relativeSchemeId, physicalSchemeId;
37271 + uint32_t tmpKgarReg, tmpReg32 = 0, intFlags;
37272 + t_Error err;
37273 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
37274 +
37275 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
37276 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
37277 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
37278 +
37279 + /* Calling function locked all PCD modules, so no need to lock here */
37280 +
37281 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37282 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37283 +
37284 + if (p_FmPcd->h_Hc)
37285 + {
37286 + err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value);
37287 +
37288 + UpdateRequiredActionFlag(h_Scheme,TRUE);
37289 + FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction);
37290 + return err;
37291 + }
37292 +
37293 + physicalSchemeId = p_Scheme->schemeId;
37294 +
37295 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
37296 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
37297 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37298 +
37299 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag ||
37300 + !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction))
37301 + {
37302 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
37303 + {
37304 + switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine)
37305 + {
37306 + case (e_FM_PCD_DONE):
37307 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME)
37308 + {
37309 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37310 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37311 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37312 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37313 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
37314 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA);
37315 + /* call indirect command for scheme write */
37316 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37317 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37318 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37319 + }
37320 + break;
37321 + case (e_FM_PCD_PLCR):
37322 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr ||
37323 + (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs &&
37324 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) ||
37325 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile)
37326 + {
37327 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
37328 + }
37329 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction);
37330 + if (err)
37331 + {
37332 + RETURN_ERROR(MAJOR, err, NO_MSG);
37333 + }
37334 + break;
37335 + default:
37336 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME"));
37337 + }
37338 + }
37339 + if (requiredAction & UPDATE_KG_NIA_CC_WA)
37340 + {
37341 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC)
37342 + {
37343 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37344 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37345 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37346 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37347 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
37348 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
37349 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC);
37350 + /* call indirect command for scheme write */
37351 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37352 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37353 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37354 + }
37355 + }
37356 + if (requiredAction & UPDATE_KG_OPT_MODE)
37357 + {
37358 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37359 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37360 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37361 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value);
37362 + /* call indirect command for scheme write */
37363 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37364 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37365 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37366 + }
37367 + if (requiredAction & UPDATE_KG_NIA)
37368 + {
37369 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37370 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37371 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37372 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37373 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
37374 + tmpReg32 |= value;
37375 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32);
37376 + /* call indirect command for scheme write */
37377 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37378 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37379 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37380 + }
37381 + }
37382 +
37383 + UpdateRequiredActionFlag(h_Scheme, TRUE);
37384 + FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction);
37385 +
37386 + return E_OK;
37387 +}
37388 +/*********************** End of inter-module routines ************************/
37389 +
37390 +
37391 +/****************************************/
37392 +/* API routines */
37393 +/****************************************/
37394 +
37395 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams)
37396 +{
37397 + t_FmPcd *p_FmPcd;
37398 + struct fman_kg_scheme_regs schemeRegs;
37399 + struct fman_kg_scheme_regs *p_MemRegs;
37400 + uint8_t i;
37401 + t_Error err = E_OK;
37402 + uint32_t tmpKgarReg;
37403 + uint32_t intFlags;
37404 + uint8_t physicalSchemeId, relativeSchemeId = 0;
37405 + t_FmPcdKgScheme *p_Scheme;
37406 +
37407 + if (p_SchemeParams->modify)
37408 + {
37409 + p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme;
37410 + p_FmPcd = p_Scheme->h_FmPcd;
37411 +
37412 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37413 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37414 +
37415 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
37416 + {
37417 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37418 + ("Scheme is invalid"));
37419 + return NULL;
37420 + }
37421 +
37422 + if (!KgSchemeFlagTryLock(p_Scheme))
37423 + {
37424 + DBG(TRACE, ("Scheme Try Lock - BUSY"));
37425 + /* Signal to caller BUSY condition */
37426 + p_SchemeParams->id.h_Scheme = NULL;
37427 + return NULL;
37428 + }
37429 + }
37430 + else
37431 + {
37432 + p_FmPcd = (t_FmPcd*)h_FmPcd;
37433 +
37434 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37435 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37436 +
37437 + relativeSchemeId = p_SchemeParams->id.relativeSchemeId;
37438 + /* check that schemeId is in range */
37439 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37440 + {
37441 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37442 + return NULL;
37443 + }
37444 +
37445 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37446 + if (FmPcdKgIsSchemeValidSw(p_Scheme))
37447 + {
37448 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37449 + ("Scheme id (%d)!", relativeSchemeId));
37450 + return NULL;
37451 + }
37452 + /* Clear all fields, scheme may have beed previously used */
37453 + memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme));
37454 +
37455 + p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId];
37456 + p_Scheme->h_FmPcd = p_FmPcd;
37457 +
37458 + p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd);
37459 + if (!p_Scheme->p_Lock)
37460 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!"));
37461 + }
37462 +
37463 + err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs);
37464 + if (err)
37465 + {
37466 + REPORT_ERROR(MAJOR, err, NO_MSG);
37467 + if (p_SchemeParams->modify)
37468 + KgSchemeFlagUnlock(p_Scheme);
37469 + if (!p_SchemeParams->modify &&
37470 + p_Scheme->p_Lock)
37471 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37472 + return NULL;
37473 + }
37474 +
37475 + if (p_FmPcd->h_Hc)
37476 + {
37477 + err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc,
37478 + (t_Handle)p_Scheme,
37479 + &schemeRegs,
37480 + p_SchemeParams->schemeCounter.update);
37481 + if (p_SchemeParams->modify)
37482 + KgSchemeFlagUnlock(p_Scheme);
37483 + if (err)
37484 + {
37485 + if (!p_SchemeParams->modify &&
37486 + p_Scheme->p_Lock)
37487 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37488 + return NULL;
37489 + }
37490 + if (!p_SchemeParams->modify)
37491 + ValidateSchemeSw(p_Scheme);
37492 + return (t_Handle)p_Scheme;
37493 + }
37494 +
37495 + physicalSchemeId = p_Scheme->schemeId;
37496 +
37497 + /* configure all 21 scheme registers */
37498 + p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs;
37499 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37500 + WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc);
37501 + WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs);
37502 + WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode);
37503 + WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv);
37504 + WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0);
37505 + WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1);
37506 + WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv);
37507 + WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc);
37508 + WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch);
37509 + WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl);
37510 + WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc);
37511 + WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc);
37512 + WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb);
37513 + WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om);
37514 + WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp);
37515 + for (i=0 ; i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
37516 + WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]);
37517 +
37518 + /* call indirect command for scheme write */
37519 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update);
37520 +
37521 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37522 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37523 +
37524 + if (!p_SchemeParams->modify)
37525 + ValidateSchemeSw(p_Scheme);
37526 + else
37527 + KgSchemeFlagUnlock(p_Scheme);
37528 +
37529 + return (t_Handle)p_Scheme;
37530 +}
37531 +
37532 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme)
37533 +{
37534 + t_FmPcd *p_FmPcd;
37535 + uint8_t physicalSchemeId;
37536 + uint32_t tmpKgarReg, intFlags;
37537 + t_Error err = E_OK;
37538 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
37539 +
37540 + SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE);
37541 +
37542 + p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd);
37543 +
37544 + UpdateRequiredActionFlag(h_Scheme, FALSE);
37545 +
37546 + /* check that no port is bound to this scheme */
37547 + err = InvalidateSchemeSw(h_Scheme);
37548 + if (err)
37549 + RETURN_ERROR(MINOR, err, NO_MSG);
37550 +
37551 + if (p_FmPcd->h_Hc)
37552 + {
37553 + err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme);
37554 + if (p_Scheme->p_Lock)
37555 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37556 + return err;
37557 + }
37558 +
37559 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37560 +
37561 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37562 + /* clear mode register, including enable bit */
37563 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0);
37564 +
37565 + /* call indirect command for scheme write */
37566 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37567 +
37568 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37569 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37570 +
37571 + if (p_Scheme->p_Lock)
37572 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37573 +
37574 + return E_OK;
37575 +}
37576 +
37577 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme)
37578 +{
37579 + t_FmPcd *p_FmPcd;
37580 + uint32_t tmpKgarReg, spc, intFlags;
37581 + uint8_t physicalSchemeId;
37582 +
37583 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37584 +
37585 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37586 + if (p_FmPcd->h_Hc)
37587 + return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme);
37588 +
37589 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37590 +
37591 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37592 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37593 +
37594 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37595 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37596 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37597 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37598 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37599 + spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc);
37600 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37601 +
37602 + return spc;
37603 +}
37604 +
37605 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value)
37606 +{
37607 + t_FmPcd *p_FmPcd;
37608 + uint32_t tmpKgarReg, intFlags;
37609 + uint8_t physicalSchemeId;
37610 +
37611 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37612 +
37613 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37614 +
37615 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37616 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
37617 +
37618 + if (p_FmPcd->h_Hc)
37619 + return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value);
37620 +
37621 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37622 + /* check that schemeId is in range */
37623 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37624 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37625 +
37626 + /* read specified scheme into scheme registers */
37627 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37628 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37629 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37630 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37631 + {
37632 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37633 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37634 + }
37635 +
37636 + /* change counter value */
37637 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value);
37638 +
37639 + /* call indirect command for scheme write */
37640 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
37641 +
37642 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37643 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37644 +
37645 + return E_OK;
37646 +}
37647 +
37648 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset)
37649 +{
37650 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37651 + struct fman_kg_regs *p_Regs;
37652 +
37653 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37654 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37655 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37656 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37657 +
37658 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37659 + if (!FmIsMaster(p_FmPcd->h_Fm))
37660 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!"));
37661 +
37662 + WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset);
37663 +
37664 + return E_OK;
37665 +}
37666 +
37667 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value)
37668 +{
37669 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37670 + struct fman_kg_regs *p_Regs;
37671 +
37672 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37673 + SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE);
37674 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37675 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37676 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37677 +
37678 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37679 +
37680 + if (!FmIsMaster(p_FmPcd->h_Fm))
37681 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!"));
37682 +
37683 + if (valueId == 0)
37684 + WRITE_UINT32(p_Regs->fmkg_gdv0r,value);
37685 + else
37686 + WRITE_UINT32(p_Regs->fmkg_gdv1r,value);
37687 + return E_OK;
37688 +}
37689 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
37690 new file mode 100644
37691 index 00000000..cb7521a1
37692 --- /dev/null
37693 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
37694 @@ -0,0 +1,206 @@
37695 +/*
37696 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37697 + *
37698 + * Redistribution and use in source and binary forms, with or without
37699 + * modification, are permitted provided that the following conditions are met:
37700 + * * Redistributions of source code must retain the above copyright
37701 + * notice, this list of conditions and the following disclaimer.
37702 + * * Redistributions in binary form must reproduce the above copyright
37703 + * notice, this list of conditions and the following disclaimer in the
37704 + * documentation and/or other materials provided with the distribution.
37705 + * * Neither the name of Freescale Semiconductor nor the
37706 + * names of its contributors may be used to endorse or promote products
37707 + * derived from this software without specific prior written permission.
37708 + *
37709 + *
37710 + * ALTERNATIVELY, this software may be distributed under the terms of the
37711 + * GNU General Public License ("GPL") as published by the Free Software
37712 + * Foundation, either version 2 of that License or (at your option) any
37713 + * later version.
37714 + *
37715 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37716 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37717 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37718 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37719 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37720 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37721 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37722 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37723 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37724 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37725 + */
37726 +
37727 +
37728 +/******************************************************************************
37729 + @File fm_kg.h
37730 +
37731 + @Description FM KG private header
37732 +*//***************************************************************************/
37733 +#ifndef __FM_KG_H
37734 +#define __FM_KG_H
37735 +
37736 +#include "std_ext.h"
37737 +
37738 +/***********************************************************************/
37739 +/* Keygen defines */
37740 +/***********************************************************************/
37741 +/* maskes */
37742 +#if (DPAA_VERSION >= 11)
37743 +#define KG_SCH_VSP_SHIFT_MASK 0x0003f000
37744 +#define KG_SCH_OM_VSPE 0x00000001
37745 +#define KG_SCH_VSP_NO_KSP_EN 0x80000000
37746 +
37747 +#define MAX_SP_SHIFT 23
37748 +#define KG_SCH_VSP_MASK_SHIFT 12
37749 +#define KG_SCH_VSP_SHIFT 24
37750 +#endif /* (DPAA_VERSION >= 11) */
37751 +
37752 +typedef uint32_t t_KnownFieldsMasks;
37753 +#define KG_SCH_KN_PORT_ID 0x80000000
37754 +#define KG_SCH_KN_MACDST 0x40000000
37755 +#define KG_SCH_KN_MACSRC 0x20000000
37756 +#define KG_SCH_KN_TCI1 0x10000000
37757 +#define KG_SCH_KN_TCI2 0x08000000
37758 +#define KG_SCH_KN_ETYPE 0x04000000
37759 +#define KG_SCH_KN_PPPSID 0x02000000
37760 +#define KG_SCH_KN_PPPID 0x01000000
37761 +#define KG_SCH_KN_MPLS1 0x00800000
37762 +#define KG_SCH_KN_MPLS2 0x00400000
37763 +#define KG_SCH_KN_MPLS_LAST 0x00200000
37764 +#define KG_SCH_KN_IPSRC1 0x00100000
37765 +#define KG_SCH_KN_IPDST1 0x00080000
37766 +#define KG_SCH_KN_PTYPE1 0x00040000
37767 +#define KG_SCH_KN_IPTOS_TC1 0x00020000
37768 +#define KG_SCH_KN_IPV6FL1 0x00010000
37769 +#define KG_SCH_KN_IPSRC2 0x00008000
37770 +#define KG_SCH_KN_IPDST2 0x00004000
37771 +#define KG_SCH_KN_PTYPE2 0x00002000
37772 +#define KG_SCH_KN_IPTOS_TC2 0x00001000
37773 +#define KG_SCH_KN_IPV6FL2 0x00000800
37774 +#define KG_SCH_KN_GREPTYPE 0x00000400
37775 +#define KG_SCH_KN_IPSEC_SPI 0x00000200
37776 +#define KG_SCH_KN_IPSEC_NH 0x00000100
37777 +#define KG_SCH_KN_IPPID 0x00000080
37778 +#define KG_SCH_KN_L4PSRC 0x00000004
37779 +#define KG_SCH_KN_L4PDST 0x00000002
37780 +#define KG_SCH_KN_TFLG 0x00000001
37781 +
37782 +typedef uint8_t t_GenericCodes;
37783 +#define KG_SCH_GEN_SHIM1 0x70
37784 +#define KG_SCH_GEN_DEFAULT 0x10
37785 +#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20
37786 +#define KG_SCH_GEN_START_OF_FRM 0x40
37787 +#define KG_SCH_GEN_SHIM2 0x71
37788 +#define KG_SCH_GEN_IP_PID_NO_V 0x72
37789 +#define KG_SCH_GEN_ETH 0x03
37790 +#define KG_SCH_GEN_ETH_NO_V 0x73
37791 +#define KG_SCH_GEN_SNAP 0x04
37792 +#define KG_SCH_GEN_SNAP_NO_V 0x74
37793 +#define KG_SCH_GEN_VLAN1 0x05
37794 +#define KG_SCH_GEN_VLAN1_NO_V 0x75
37795 +#define KG_SCH_GEN_VLAN2 0x06
37796 +#define KG_SCH_GEN_VLAN2_NO_V 0x76
37797 +#define KG_SCH_GEN_ETH_TYPE 0x07
37798 +#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77
37799 +#define KG_SCH_GEN_PPP 0x08
37800 +#define KG_SCH_GEN_PPP_NO_V 0x78
37801 +#define KG_SCH_GEN_MPLS1 0x09
37802 +#define KG_SCH_GEN_MPLS2 0x19
37803 +#define KG_SCH_GEN_MPLS3 0x29
37804 +#define KG_SCH_GEN_MPLS1_NO_V 0x79
37805 +#define KG_SCH_GEN_MPLS_LAST 0x0a
37806 +#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a
37807 +#define KG_SCH_GEN_IPV4 0x0b
37808 +#define KG_SCH_GEN_IPV6 0x1b
37809 +#define KG_SCH_GEN_L3_NO_V 0x7b
37810 +#define KG_SCH_GEN_IPV4_TUNNELED 0x0c
37811 +#define KG_SCH_GEN_IPV6_TUNNELED 0x1c
37812 +#define KG_SCH_GEN_MIN_ENCAP 0x2c
37813 +#define KG_SCH_GEN_IP2_NO_V 0x7c
37814 +#define KG_SCH_GEN_GRE 0x0d
37815 +#define KG_SCH_GEN_GRE_NO_V 0x7d
37816 +#define KG_SCH_GEN_TCP 0x0e
37817 +#define KG_SCH_GEN_UDP 0x1e
37818 +#define KG_SCH_GEN_IPSEC_AH 0x2e
37819 +#define KG_SCH_GEN_SCTP 0x3e
37820 +#define KG_SCH_GEN_DCCP 0x4e
37821 +#define KG_SCH_GEN_IPSEC_ESP 0x6e
37822 +#define KG_SCH_GEN_L4_NO_V 0x7e
37823 +#define KG_SCH_GEN_NEXTHDR 0x7f
37824 +/* shifts */
37825 +#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27
37826 +#define KG_SCH_PP_SHIFT_LOW_SHIFT 12
37827 +#define KG_SCH_PP_MASK_SHIFT 16
37828 +#define KG_SCH_MODE_CCOBASE_SHIFT 24
37829 +#define KG_SCH_DEF_MAC_ADDR_SHIFT 30
37830 +#define KG_SCH_DEF_TCI_SHIFT 28
37831 +#define KG_SCH_DEF_ENET_TYPE_SHIFT 26
37832 +#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24
37833 +#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22
37834 +#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20
37835 +#define KG_SCH_DEF_IP_ADDR_SHIFT 18
37836 +#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16
37837 +#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14
37838 +#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12
37839 +#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10
37840 +#define KG_SCH_DEF_L4_PORT_SHIFT 8
37841 +#define KG_SCH_DEF_TCP_FLAG_SHIFT 6
37842 +#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24
37843 +#define KG_SCH_GEN_MASK_SHIFT 16
37844 +#define KG_SCH_GEN_HT_SHIFT 8
37845 +#define KG_SCH_GEN_SIZE_SHIFT 24
37846 +#define KG_SCH_GEN_DEF_SHIFT 29
37847 +#define FM_PCD_KG_KGAR_NUM_SHIFT 16
37848 +
37849 +/* others */
37850 +#define NUM_OF_SW_DEFAULTS 3
37851 +#define MAX_PP_SHIFT 23
37852 +#define MAX_KG_SCH_SIZE 16
37853 +#define MASK_FOR_GENERIC_BASE_ID 0x20
37854 +#define MAX_HASH_SHIFT 40
37855 +#define MAX_KG_SCH_FQID_BIT_OFFSET 31
37856 +#define MAX_KG_SCH_PP_BIT_OFFSET 15
37857 +#define MAX_DIST_FQID_SHIFT 23
37858 +
37859 +#define GET_MASK_SEL_SHIFT(shift,i) \
37860 +switch (i) { \
37861 + case (0):shift = 26;break; \
37862 + case (1):shift = 20;break; \
37863 + case (2):shift = 10;break; \
37864 + case (3):shift = 4;break; \
37865 + default: \
37866 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37867 +}
37868 +
37869 +#define GET_MASK_OFFSET_SHIFT(shift,i) \
37870 +switch (i) { \
37871 + case (0):shift = 16;break; \
37872 + case (1):shift = 0;break; \
37873 + case (2):shift = 28;break; \
37874 + case (3):shift = 24;break; \
37875 + default: \
37876 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37877 +}
37878 +
37879 +#define GET_MASK_SHIFT(shift,i) \
37880 +switch (i) { \
37881 + case (0):shift = 24;break; \
37882 + case (1):shift = 16;break; \
37883 + case (2):shift = 8;break; \
37884 + case (3):shift = 0;break; \
37885 + default: \
37886 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37887 +}
37888 +
37889 +/***********************************************************************/
37890 +/* Keygen defines */
37891 +/***********************************************************************/
37892 +
37893 +#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100
37894 +#define NO_VALIDATION 0x70
37895 +#define KG_ACTION_REG_TO 1024
37896 +#define KG_MAX_PROFILE 255
37897 +#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF
37898 +
37899 +
37900 +#endif /* __FM_KG_H */
37901 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
37902 new file mode 100644
37903 index 00000000..113777e5
37904 --- /dev/null
37905 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
37906 @@ -0,0 +1,5571 @@
37907 +/*
37908 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37909 + *
37910 + * Redistribution and use in source and binary forms, with or without
37911 + * modification, are permitted provided that the following conditions are met:
37912 + * * Redistributions of source code must retain the above copyright
37913 + * notice, this list of conditions and the following disclaimer.
37914 + * * Redistributions in binary form must reproduce the above copyright
37915 + * notice, this list of conditions and the following disclaimer in the
37916 + * documentation and/or other materials provided with the distribution.
37917 + * * Neither the name of Freescale Semiconductor nor the
37918 + * names of its contributors may be used to endorse or promote products
37919 + * derived from this software without specific prior written permission.
37920 + *
37921 + *
37922 + * ALTERNATIVELY, this software may be distributed under the terms of the
37923 + * GNU General Public License ("GPL") as published by the Free Software
37924 + * Foundation, either version 2 of that License or (at your option) any
37925 + * later version.
37926 + *
37927 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37928 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37929 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37930 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37931 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37932 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37933 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37934 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37935 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37936 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37937 + */
37938 +
37939 +
37940 +/******************************************************************************
37941 + @File fm_manip.c
37942 +
37943 + @Description FM PCD manip ...
37944 + *//***************************************************************************/
37945 +#include "std_ext.h"
37946 +#include "error_ext.h"
37947 +#include "string_ext.h"
37948 +#include "debug_ext.h"
37949 +#include "fm_pcd_ext.h"
37950 +#include "fm_port_ext.h"
37951 +#include "fm_muram_ext.h"
37952 +#include "memcpy_ext.h"
37953 +
37954 +#include "fm_common.h"
37955 +#include "fm_hc.h"
37956 +#include "fm_manip.h"
37957 +
37958 +/****************************************/
37959 +/* static functions */
37960 +/****************************************/
37961 +static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo)
37962 +{
37963 + t_FmPcdManip *p_CurManip = p_Manip;
37964 +
37965 + if (!MANIP_IS_UNIFIED(p_Manip))
37966 + p_CurManip = p_Manip;
37967 + else
37968 + {
37969 + /* go to first unified */
37970 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37971 + p_CurManip = p_CurManip->h_PrevManip;
37972 + }
37973 +
37974 + switch (manipInfo)
37975 + {
37976 + case (e_MANIP_HMCT):
37977 + return p_CurManip->p_Hmct;
37978 + case (e_MANIP_HMTD):
37979 + return p_CurManip->h_Ad;
37980 + case (e_MANIP_HANDLER_TABLE_OWNER):
37981 + return (t_Handle)p_CurManip;
37982 + default:
37983 + return NULL;
37984 + }
37985 +}
37986 +
37987 +static uint16_t GetHmctSize(t_FmPcdManip *p_Manip)
37988 +{
37989 + uint16_t size = 0;
37990 + t_FmPcdManip *p_CurManip = p_Manip;
37991 +
37992 + if (!MANIP_IS_UNIFIED(p_Manip))
37993 + return p_Manip->tableSize;
37994 +
37995 + /* accumulate sizes, starting with the first node */
37996 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37997 + p_CurManip = p_CurManip->h_PrevManip;
37998 +
37999 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
38000 + {
38001 + size += p_CurManip->tableSize;
38002 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
38003 + }
38004 + size += p_CurManip->tableSize; /* add last size */
38005 +
38006 + return (size);
38007 +}
38008 +
38009 +static uint16_t GetDataSize(t_FmPcdManip *p_Manip)
38010 +{
38011 + uint16_t size = 0;
38012 + t_FmPcdManip *p_CurManip = p_Manip;
38013 +
38014 + if (!MANIP_IS_UNIFIED(p_Manip))
38015 + return p_Manip->dataSize;
38016 +
38017 + /* accumulate sizes, starting with the first node */
38018 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
38019 + p_CurManip = p_CurManip->h_PrevManip;
38020 +
38021 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
38022 + {
38023 + size += p_CurManip->dataSize;
38024 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
38025 + }
38026 + size += p_CurManip->dataSize; /* add last size */
38027 +
38028 + return (size);
38029 +}
38030 +
38031 +static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams,
38032 + uint16_t *p_TableSize, uint8_t *p_DataSize)
38033 +{
38034 + uint8_t localDataSize, remain, tableSize = 0, dataSize = 0;
38035 +
38036 + if (p_FmPcdManipParams->u.hdr.rmv)
38037 + {
38038 + switch (p_FmPcdManipParams->u.hdr.rmvParams.type)
38039 + {
38040 + case (e_FM_PCD_MANIP_RMV_GENERIC):
38041 + tableSize += HMCD_BASIC_SIZE;
38042 + break;
38043 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
38044 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
38045 + {
38046 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
38047 +#if (DPAA_VERSION >= 11)
38048 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
38049 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
38050 +#endif /* (DPAA_VERSION >= 11) */
38051 + tableSize += HMCD_BASIC_SIZE;
38052 + break;
38053 + default:
38054 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38055 + ("Unknown byHdr.type"));
38056 + }
38057 + break;
38058 + default:
38059 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38060 + ("Unknown rmvParams.type"));
38061 + }
38062 + }
38063 +
38064 + if (p_FmPcdManipParams->u.hdr.insrt)
38065 + {
38066 + switch (p_FmPcdManipParams->u.hdr.insrtParams.type)
38067 + {
38068 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
38069 + remain =
38070 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
38071 + % 4);
38072 + if (remain)
38073 + localDataSize =
38074 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
38075 + + 4 - remain);
38076 + else
38077 + localDataSize =
38078 + p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
38079 + tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize);
38080 + break;
38081 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
38082 + {
38083 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
38084 + {
38085 +
38086 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
38087 + tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE;
38088 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
38089 + {
38090 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
38091 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
38092 + dataSize +=
38093 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
38094 + break;
38095 + default:
38096 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38097 + }
38098 + break;
38099 +#if (DPAA_VERSION >= 11)
38100 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
38101 + tableSize +=
38102 + (HMCD_BASIC_SIZE + HMCD_PTR_SIZE
38103 + + HMCD_PARAM_SIZE
38104 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
38105 + dataSize += 2;
38106 + break;
38107 +
38108 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
38109 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
38110 + tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE);
38111 +
38112 + break;
38113 +
38114 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
38115 + tableSize +=
38116 + (HMCD_BASIC_SIZE
38117 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38118 + break;
38119 +#endif /* (DPAA_VERSION >= 11) */
38120 + default:
38121 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38122 + ("Unknown byHdr.type"));
38123 + }
38124 + }
38125 + break;
38126 + default:
38127 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38128 + ("Unknown insrtParams.type"));
38129 + }
38130 + }
38131 +
38132 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
38133 + {
38134 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
38135 + {
38136 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
38137 + tableSize += HMCD_BASIC_SIZE;
38138 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38139 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
38140 + {
38141 + tableSize += HMCD_PTR_SIZE;
38142 + dataSize += DSCP_TO_VLAN_TABLE_SIZE;
38143 + }
38144 + break;
38145 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
38146 + tableSize += HMCD_BASIC_SIZE;
38147 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38148 + & HDR_MANIP_IPV4_ID)
38149 + {
38150 + tableSize += HMCD_PARAM_SIZE;
38151 + dataSize += 2;
38152 + }
38153 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38154 + & HDR_MANIP_IPV4_SRC)
38155 + tableSize += HMCD_IPV4_ADDR_SIZE;
38156 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38157 + & HDR_MANIP_IPV4_DST)
38158 + tableSize += HMCD_IPV4_ADDR_SIZE;
38159 + break;
38160 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
38161 + tableSize += HMCD_BASIC_SIZE;
38162 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38163 + & HDR_MANIP_IPV6_SRC)
38164 + tableSize += HMCD_IPV6_ADDR_SIZE;
38165 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38166 + & HDR_MANIP_IPV6_DST)
38167 + tableSize += HMCD_IPV6_ADDR_SIZE;
38168 + break;
38169 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
38170 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38171 + == HDR_MANIP_TCP_UDP_CHECKSUM)
38172 + /* we implement this case with the update-checksum descriptor */
38173 + tableSize += HMCD_BASIC_SIZE;
38174 + else
38175 + /* we implement this case with the TCP/UDP-update descriptor */
38176 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
38177 + break;
38178 + default:
38179 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38180 + ("Unknown fieldUpdateParams.type"));
38181 + }
38182 + }
38183 +
38184 + if (p_FmPcdManipParams->u.hdr.custom)
38185 + {
38186 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
38187 + {
38188 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
38189 + {
38190 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE;
38191 + dataSize +=
38192 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
38193 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38194 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38195 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
38196 + dataSize += 2;
38197 + }
38198 + break;
38199 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
38200 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
38201 + break;
38202 + default:
38203 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38204 + ("Unknown customParams.type"));
38205 + }
38206 + }
38207 +
38208 + *p_TableSize = tableSize;
38209 + *p_DataSize = dataSize;
38210 +
38211 + return E_OK;
38212 +}
38213 +
38214 +static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo,
38215 + uint8_t *parseArrayOffset)
38216 +{
38217 + e_NetHeaderType hdr = p_HdrInfo->hdr;
38218 + e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex;
38219 + bool byField = p_HdrInfo->byField;
38220 + t_FmPcdFields field;
38221 +
38222 + if (byField)
38223 + field = p_HdrInfo->fullField;
38224 +
38225 + if (byField)
38226 + {
38227 + switch (hdr)
38228 + {
38229 + case (HEADER_TYPE_ETH):
38230 + switch (field.eth)
38231 + {
38232 + case (NET_HEADER_FIELD_ETH_TYPE):
38233 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
38234 + break;
38235 + default:
38236 + RETURN_ERROR(
38237 + MAJOR,
38238 + E_NOT_SUPPORTED,
38239 + ("Header manipulation of the type Ethernet with this field not supported"));
38240 + }
38241 + break;
38242 + case (HEADER_TYPE_VLAN):
38243 + switch (field.vlan)
38244 + {
38245 + case (NET_HEADER_FIELD_VLAN_TCI):
38246 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38247 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38248 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
38249 + else
38250 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
38251 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
38252 + break;
38253 + default:
38254 + RETURN_ERROR(
38255 + MAJOR,
38256 + E_NOT_SUPPORTED,
38257 + ("Header manipulation of the type VLAN with this field not supported"));
38258 + }
38259 + break;
38260 + default:
38261 + RETURN_ERROR(
38262 + MAJOR,
38263 + E_NOT_SUPPORTED,
38264 + ("Header manipulation of this header by field not supported"));
38265 + }
38266 + }
38267 + else
38268 + {
38269 + switch (hdr)
38270 + {
38271 + case (HEADER_TYPE_ETH):
38272 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
38273 + break;
38274 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
38275 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
38276 + break;
38277 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
38278 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
38279 + break;
38280 + case (HEADER_TYPE_LLC_SNAP):
38281 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
38282 + break;
38283 + case (HEADER_TYPE_PPPoE):
38284 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
38285 + break;
38286 + case (HEADER_TYPE_MPLS):
38287 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38288 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38289 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
38290 + else
38291 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
38292 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
38293 + break;
38294 + case (HEADER_TYPE_IPv4):
38295 + case (HEADER_TYPE_IPv6):
38296 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38297 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38298 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
38299 + else
38300 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
38301 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
38302 + break;
38303 + case (HEADER_TYPE_MINENCAP):
38304 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
38305 + break;
38306 + case (HEADER_TYPE_GRE):
38307 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
38308 + break;
38309 + case (HEADER_TYPE_TCP):
38310 + case (HEADER_TYPE_UDP):
38311 + case (HEADER_TYPE_IPSEC_AH):
38312 + case (HEADER_TYPE_IPSEC_ESP):
38313 + case (HEADER_TYPE_DCCP):
38314 + case (HEADER_TYPE_SCTP):
38315 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
38316 + break;
38317 + case (HEADER_TYPE_CAPWAP):
38318 + case (HEADER_TYPE_CAPWAP_DTLS):
38319 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
38320 + break;
38321 + default:
38322 + RETURN_ERROR(
38323 + MAJOR,
38324 + E_NOT_SUPPORTED,
38325 + ("Header manipulation of this header is not supported"));
38326 + }
38327 + }
38328 + return E_OK;
38329 +}
38330 +
38331 +static t_Error BuildHmct(t_FmPcdManip *p_Manip,
38332 + t_FmPcdManipParams *p_FmPcdManipParams,
38333 + uint8_t *p_DestHmct, uint8_t *p_DestData, bool new)
38334 +{
38335 + uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData;
38336 + uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr;
38337 + uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData =
38338 + p_DestData;
38339 + t_Handle h_FmPcd = p_Manip->h_FmPcd;
38340 + uint8_t j = 0;
38341 +
38342 + if (p_FmPcdManipParams->u.hdr.rmv)
38343 + {
38344 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38345 + == e_FM_PCD_MANIP_RMV_GENERIC)
38346 + {
38347 + /* initialize HMCD */
38348 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT;
38349 + /* tmp, should be conditional */
38350 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset
38351 + << HMCD_RMV_OFFSET_SHIFT;
38352 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size
38353 + << HMCD_RMV_SIZE_SHIFT;
38354 + }
38355 + else
38356 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38357 + == e_FM_PCD_MANIP_RMV_BY_HDR)
38358 + {
38359 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
38360 + {
38361 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
38362 + {
38363 + uint8_t hmcdOpt;
38364 +
38365 + /* initialize HMCD */
38366 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT;
38367 +
38368 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2)
38369 + {
38370 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET):
38371 + hmcdOpt = HMCD_RMV_L2_ETHERNET;
38372 + break;
38373 + case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS):
38374 + hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS;
38375 + break;
38376 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS):
38377 + hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS;
38378 + break;
38379 + case (e_FM_PCD_MANIP_HDR_RMV_MPLS):
38380 + hmcdOpt = HMCD_RMV_L2_MPLS;
38381 + break;
38382 + case (e_FM_PCD_MANIP_HDR_RMV_PPPOE):
38383 + hmcdOpt = HMCD_RMV_L2_PPPOE;
38384 + break;
38385 + default:
38386 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38387 + }
38388 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38389 + break;
38390 + }
38391 +#if (DPAA_VERSION >= 11)
38392 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
38393 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV)
38394 + << HMCD_OC_SHIFT;
38395 + break;
38396 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
38397 + {
38398 + uint8_t prsArrayOffset;
38399 + t_Error err = E_OK;
38400 +
38401 + tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL)
38402 + << HMCD_OC_SHIFT;
38403 +
38404 + err =
38405 + GetPrOffsetByHeaderOrField(
38406 + &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
38407 + &prsArrayOffset);
38408 + ASSERT_COND(!err);
38409 + /* was previously checked */
38410 +
38411 + tmpReg |= ((uint32_t)prsArrayOffset << 16);
38412 + }
38413 + break;
38414 +#endif /* (DPAA_VERSION >= 11) */
38415 + default:
38416 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38417 + ("manip header remove by hdr type!"));
38418 + }
38419 + }
38420 +
38421 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38422 + /* save a pointer to the "last" indication word */
38423 + p_Last = p_TmpHmct;
38424 + /* advance to next command */
38425 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38426 + }
38427 +
38428 + if (p_FmPcdManipParams->u.hdr.insrt)
38429 + {
38430 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38431 + == e_FM_PCD_MANIP_INSRT_GENERIC)
38432 + {
38433 + /* initialize HMCD */
38434 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace)
38435 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE)
38436 + << HMCD_OC_SHIFT;
38437 + else
38438 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT;
38439 +
38440 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset
38441 + << HMCD_INSRT_OFFSET_SHIFT;
38442 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
38443 + << HMCD_INSRT_SIZE_SHIFT;
38444 +
38445 + size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
38446 + p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data;
38447 +
38448 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38449 + /* save a pointer to the "last" indication word */
38450 + p_Last = p_TmpHmct;
38451 +
38452 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38453 +
38454 + /* initialize data to be inserted */
38455 + /* if size is not a multiple of 4, padd with 0's */
38456 + origSize = size;
38457 + remain = (uint8_t)(size % 4);
38458 + if (remain)
38459 + {
38460 + size += (uint8_t)(4 - remain);
38461 + p_LocalData = (uint32_t *)XX_Malloc(size);
38462 + memset((uint8_t *)p_LocalData, 0, size);
38463 + memcpy((uint8_t *)p_LocalData, p_UsrData, origSize);
38464 + }
38465 + else
38466 + p_LocalData = (uint32_t*)p_UsrData;
38467 +
38468 + /* initialize data and advance pointer to next command */
38469 + MemCpy8(p_TmpHmct, p_LocalData, size);
38470 + p_TmpHmct += size / sizeof(uint32_t);
38471 +
38472 + if (remain)
38473 + XX_Free(p_LocalData);
38474 + }
38475 +
38476 + else
38477 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38478 + == e_FM_PCD_MANIP_INSRT_BY_HDR)
38479 + {
38480 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
38481 + {
38482 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
38483 + {
38484 + uint8_t hmcdOpt;
38485 +
38486 + /* initialize HMCD */
38487 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT)
38488 + << HMCD_OC_SHIFT;
38489 +
38490 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
38491 + {
38492 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
38493 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update)
38494 + hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS;
38495 + else
38496 + hmcdOpt = HMCD_INSRT_L2_MPLS;
38497 + break;
38498 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
38499 + hmcdOpt = HMCD_INSRT_L2_PPPOE;
38500 + break;
38501 + default:
38502 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38503 + }
38504 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38505 +
38506 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38507 + /* save a pointer to the "last" indication word */
38508 + p_Last = p_TmpHmct;
38509 +
38510 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38511 +
38512 + /* set size and pointer of user's data */
38513 + size =
38514 + (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
38515 +
38516 + ASSERT_COND(p_TmpData);
38517 + MemCpy8(
38518 + p_TmpData,
38519 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data,
38520 + size);
38521 + tmpReg =
38522 + (size << HMCD_INSRT_L2_SIZE_SHIFT)
38523 + | (uint32_t)(XX_VirtToPhys(p_TmpData)
38524 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38525 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38526 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38527 + p_TmpData += size;
38528 + }
38529 + break;
38530 +#if (DPAA_VERSION >= 11)
38531 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
38532 + tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT)
38533 + << HMCD_OC_SHIFT;
38534 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum)
38535 + tmpReg |= HMCD_IP_L4_CS_CALC;
38536 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode
38537 + == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS)
38538 + tmpReg |= HMCD_IP_OR_QOS;
38539 + tmpReg |=
38540 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset
38541 + & HMCD_IP_LAST_PID_MASK;
38542 + tmpReg |=
38543 + ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38544 + << HMCD_IP_SIZE_SHIFT)
38545 + & HMCD_IP_SIZE_MASK);
38546 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite)
38547 + tmpReg |= HMCD_IP_DF_MODE;
38548 +
38549 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38550 +
38551 + /* save a pointer to the "last" indication word */
38552 + p_Last = p_TmpHmct;
38553 +
38554 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38555 +
38556 + /* set IP id */
38557 + ASSERT_COND(p_TmpData);
38558 + WRITE_UINT16(
38559 + *(uint16_t*)p_TmpData,
38560 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id);
38561 + WRITE_UINT32(
38562 + *p_TmpHmct,
38563 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38564 + p_TmpData += 2;
38565 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38566 +
38567 + WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset);
38568 + p_TmpHmct += HMCD_PARAM_SIZE / 4;
38569 +
38570 + MemCpy8(
38571 + p_TmpHmct,
38572 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data,
38573 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
38574 + p_TmpHmct +=
38575 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38576 + / 4;
38577 + break;
38578 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
38579 + tmpReg = HMCD_INSRT_UDP_LITE;
38580 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
38581 + tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT)
38582 + << HMCD_OC_SHIFT;
38583 +
38584 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38585 +
38586 + /* save a pointer to the "last" indication word */
38587 + p_Last = p_TmpHmct;
38588 +
38589 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38590 +
38591 + MemCpy8(
38592 + p_TmpHmct,
38593 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38594 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38595 + p_TmpHmct +=
38596 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38597 + / 4;
38598 + break;
38599 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
38600 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT)
38601 + << HMCD_OC_SHIFT;
38602 + tmpReg |= HMCD_CAPWAP_INSRT;
38603 +
38604 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38605 +
38606 + /* save a pointer to the "last" indication word */
38607 + p_Last = p_TmpHmct;
38608 +
38609 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38610 +
38611 + MemCpy8(
38612 + p_TmpHmct,
38613 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38614 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38615 + p_TmpHmct +=
38616 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38617 + / 4;
38618 + break;
38619 +#endif /* (DPAA_VERSION >= 11) */
38620 + default:
38621 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38622 + ("manip header insert by header type!"));
38623 +
38624 + }
38625 + }
38626 + }
38627 +
38628 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
38629 + {
38630 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
38631 + {
38632 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
38633 + /* set opcode */
38634 + tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE)
38635 + << HMCD_OC_SHIFT;
38636 +
38637 + /* set mode & table pointer */
38638 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38639 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
38640 + {
38641 + /* set Mode */
38642 + tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI)
38643 + << HMCD_VLAN_PRI_REP_MODE_SHIFT;
38644 + /* set VPRI default */
38645 + tmpReg |=
38646 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal;
38647 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38648 + /* save a pointer to the "last" indication word */
38649 + p_Last = p_TmpHmct;
38650 + /* write the table pointer into the Manip descriptor */
38651 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38652 +
38653 + tmpReg = 0;
38654 + ASSERT_COND(p_TmpData);
38655 + for (i = 0; i < HMCD_DSCP_VALUES; i++)
38656 + {
38657 + /* first we build from each 8 values a 32bit register */
38658 + tmpReg |=
38659 + (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i])
38660 + << (32 - 4 * (j + 1));
38661 + j++;
38662 + /* Than we write this register to the next table word
38663 + * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */
38664 + if ((i % 8) == 7)
38665 + {
38666 + WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1),
38667 + tmpReg);
38668 + tmpReg = 0;
38669 + j = 0;
38670 + }
38671 + }
38672 +
38673 + WRITE_UINT32(
38674 + *p_TmpHmct,
38675 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38676 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38677 +
38678 + p_TmpData += DSCP_TO_VLAN_TABLE_SIZE;
38679 + }
38680 + else
38681 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38682 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
38683 + {
38684 + /* set Mode */
38685 + /* line commented out as it has no-side-effect ('0' value). */
38686 + /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/;
38687 + /* set VPRI parameter */
38688 + tmpReg |=
38689 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri;
38690 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38691 + /* save a pointer to the "last" indication word */
38692 + p_Last = p_TmpHmct;
38693 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38694 + }
38695 + break;
38696 +
38697 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
38698 + /* set opcode */
38699 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT;
38700 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38701 + & HDR_MANIP_IPV4_TTL)
38702 + tmpReg |= HMCD_IPV4_UPDATE_TTL;
38703 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38704 + & HDR_MANIP_IPV4_TOS)
38705 + {
38706 + tmpReg |= HMCD_IPV4_UPDATE_TOS;
38707 + tmpReg |=
38708 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos
38709 + << HMCD_IPV4_UPDATE_TOS_SHIFT;
38710 + }
38711 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38712 + & HDR_MANIP_IPV4_ID)
38713 + tmpReg |= HMCD_IPV4_UPDATE_ID;
38714 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38715 + & HDR_MANIP_IPV4_SRC)
38716 + tmpReg |= HMCD_IPV4_UPDATE_SRC;
38717 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38718 + & HDR_MANIP_IPV4_DST)
38719 + tmpReg |= HMCD_IPV4_UPDATE_DST;
38720 + /* write the first 4 bytes of the descriptor */
38721 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38722 + /* save a pointer to the "last" indication word */
38723 + p_Last = p_TmpHmct;
38724 +
38725 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38726 +
38727 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38728 + & HDR_MANIP_IPV4_ID)
38729 + {
38730 + ASSERT_COND(p_TmpData);
38731 + WRITE_UINT16(
38732 + *(uint16_t*)p_TmpData,
38733 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id);
38734 + WRITE_UINT32(
38735 + *p_TmpHmct,
38736 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38737 + p_TmpData += 2;
38738 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38739 + }
38740 +
38741 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38742 + & HDR_MANIP_IPV4_SRC)
38743 + {
38744 + WRITE_UINT32(
38745 + *p_TmpHmct,
38746 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src);
38747 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38748 + }
38749 +
38750 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38751 + & HDR_MANIP_IPV4_DST)
38752 + {
38753 + WRITE_UINT32(
38754 + *p_TmpHmct,
38755 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst);
38756 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38757 + }
38758 + break;
38759 +
38760 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
38761 + /* set opcode */
38762 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT;
38763 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38764 + & HDR_MANIP_IPV6_HL)
38765 + tmpReg |= HMCD_IPV6_UPDATE_HL;
38766 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38767 + & HDR_MANIP_IPV6_TC)
38768 + {
38769 + tmpReg |= HMCD_IPV6_UPDATE_TC;
38770 + tmpReg |=
38771 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass
38772 + << HMCD_IPV6_UPDATE_TC_SHIFT;
38773 + }
38774 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38775 + & HDR_MANIP_IPV6_SRC)
38776 + tmpReg |= HMCD_IPV6_UPDATE_SRC;
38777 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38778 + & HDR_MANIP_IPV6_DST)
38779 + tmpReg |= HMCD_IPV6_UPDATE_DST;
38780 + /* write the first 4 bytes of the descriptor */
38781 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38782 + /* save a pointer to the "last" indication word */
38783 + p_Last = p_TmpHmct;
38784 +
38785 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38786 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38787 + & HDR_MANIP_IPV6_SRC)
38788 + {
38789 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38790 + {
38791 + memcpy(&tmp_ipv6_addr,
38792 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i],
38793 + sizeof(uint32_t));
38794 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38795 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38796 + }
38797 + }
38798 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38799 + & HDR_MANIP_IPV6_DST)
38800 + {
38801 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38802 + {
38803 + memcpy(&tmp_ipv6_addr,
38804 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i],
38805 + sizeof(uint32_t));
38806 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38807 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38808 + }
38809 + }
38810 + break;
38811 +
38812 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
38813 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38814 + == HDR_MANIP_TCP_UDP_CHECKSUM)
38815 + {
38816 + /* we implement this case with the update-checksum descriptor */
38817 + /* set opcode */
38818 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM)
38819 + << HMCD_OC_SHIFT;
38820 + /* write the first 4 bytes of the descriptor */
38821 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38822 + /* save a pointer to the "last" indication word */
38823 + p_Last = p_TmpHmct;
38824 +
38825 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38826 + }
38827 + else
38828 + {
38829 + /* we implement this case with the TCP/UDP update descriptor */
38830 + /* set opcode */
38831 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE)
38832 + << HMCD_OC_SHIFT;
38833 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38834 + & HDR_MANIP_TCP_UDP_DST)
38835 + tmpReg |= HMCD_TCP_UDP_UPDATE_DST;
38836 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38837 + & HDR_MANIP_TCP_UDP_SRC)
38838 + tmpReg |= HMCD_TCP_UDP_UPDATE_SRC;
38839 + /* write the first 4 bytes of the descriptor */
38840 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38841 + /* save a pointer to the "last" indication word */
38842 + p_Last = p_TmpHmct;
38843 +
38844 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38845 +
38846 + tmpReg = 0;
38847 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38848 + & HDR_MANIP_TCP_UDP_SRC)
38849 + tmpReg |=
38850 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src)
38851 + << HMCD_TCP_UDP_UPDATE_SRC_SHIFT;
38852 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38853 + & HDR_MANIP_TCP_UDP_DST)
38854 + tmpReg |=
38855 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst);
38856 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38857 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38858 + }
38859 + break;
38860 +
38861 + default:
38862 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38863 + ("Unknown fieldUpdateParams.type"));
38864 + }
38865 + }
38866 +
38867 + if (p_FmPcdManipParams->u.hdr.custom)
38868 + {
38869 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
38870 + {
38871 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
38872 + /* set opcode */
38873 + tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT;
38874 +
38875 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl)
38876 + tmpReg |= HMCD_IP_REPLACE_TTL_HL;
38877 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38878 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6)
38879 + /* line commented out as it has no-side-effect ('0' value). */
38880 + /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/;
38881 + else
38882 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38883 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38884 + {
38885 + tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6;
38886 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)
38887 + tmpReg |= HMCD_IP_REPLACE_ID;
38888 + }
38889 + else
38890 + RETURN_ERROR(
38891 + MINOR,
38892 + E_NOT_SUPPORTED,
38893 + ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set."));
38894 +
38895 + /* write the first 4 bytes of the descriptor */
38896 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38897 + /* save a pointer to the "last" indication word */
38898 + p_Last = p_TmpHmct;
38899 +
38900 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38901 +
38902 + size =
38903 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
38904 + ASSERT_COND(p_TmpData);
38905 + MemCpy8(
38906 + p_TmpData,
38907 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr,
38908 + size);
38909 + tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT);
38910 + tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData)
38911 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38912 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38913 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38914 + p_TmpData += size;
38915 +
38916 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38917 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38918 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
38919 + {
38920 + WRITE_UINT16(
38921 + *(uint16_t*)p_TmpData,
38922 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id);
38923 + WRITE_UINT32(
38924 + *p_TmpHmct,
38925 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38926 + p_TmpData += 2;
38927 + }
38928 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38929 + break;
38930 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
38931 + /* set opcode */
38932 + tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT;
38933 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT;
38934 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT;
38935 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT;
38936 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38937 + tmpReg |= HMCD_GEN_FIELD_MASK_EN;
38938 +
38939 + /* write the first 4 bytes of the descriptor */
38940 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38941 + /* save a pointer to the "last" indication word */
38942 + p_Last = p_TmpHmct;
38943 +
38944 + p_TmpHmct += HMCD_BASIC_SIZE/4;
38945 +
38946 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38947 + {
38948 + tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT;
38949 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT;
38950 + /* write the next 4 bytes of the descriptor */
38951 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38952 + }
38953 + p_TmpHmct += HMCD_PARAM_SIZE/4;
38954 + break;
38955 + default:
38956 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38957 + ("Unknown customParams.type"));
38958 + }
38959 + }
38960 +
38961 + /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table
38962 + the old table and should be freed */
38963 + if (p_FmPcdManipParams->h_NextManip
38964 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
38965 + && (MANIP_DONT_REPARSE(p_Manip)))
38966 + {
38967 + if (new)
38968 + {
38969 + /* If this is the first time this manip is created we need to free unused memory. If it
38970 + * is a dynamic changes case, the memory used is either the CC shadow or the existing
38971 + * table - no allocation, no free */
38972 + MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip);
38973 +
38974 + p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST;
38975 + }
38976 + }
38977 + else
38978 + {
38979 + ASSERT_COND(p_Last);
38980 + /* set the "last" indication on the last command of the current table */
38981 + WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST);
38982 + }
38983 +
38984 + return E_OK;
38985 +}
38986 +
38987 +static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip,
38988 + t_FmPcdManipParams *p_FmPcdManipParams)
38989 +{
38990 + t_FmPcdManip *p_CurManip;
38991 + t_Error err;
38992 + uint32_t nextSize = 0, totalSize;
38993 + uint16_t tmpReg;
38994 + uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr;
38995 +
38996 + /* set Manip structure */
38997 +
38998 + p_Manip->dontParseAfterManip =
38999 + p_FmPcdManipParams->u.hdr.dontParseAfterManip;
39000 +
39001 + if (p_FmPcdManipParams->h_NextManip)
39002 + { /* Next Header manipulation exists */
39003 + p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip);
39004 +
39005 + if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip)
39006 + nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip)
39007 + + GetDataSize(p_FmPcdManipParams->h_NextManip));
39008 + else /* either parsing is required or next manip is Frag; no table merging. */
39009 + p_Manip->cascaded = TRUE;
39010 + /* pass up the "cascaded" attribute. The whole chain is cascaded
39011 + * if something is cascaded along the way. */
39012 + if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip))
39013 + p_Manip->cascaded = TRUE;
39014 + }
39015 +
39016 + /* Allocate new table */
39017 + /* calculate table size according to manip parameters */
39018 + err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize,
39019 + &p_Manip->dataSize);
39020 + if (err)
39021 + RETURN_ERROR(MINOR, err, NO_MSG);
39022 +
39023 + totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize);
39024 +
39025 + p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem(
39026 + ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4);
39027 + if (!p_Manip->p_Hmct)
39028 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed"));
39029 +
39030 + if (p_Manip->dataSize)
39031 + p_Manip->p_Data =
39032 + (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize));
39033 +
39034 + /* update shadow size to allow runtime replacement of Header manipulation */
39035 + /* The allocated shadow is divided as follows:
39036 + 0 . . . 16 . . .
39037 + --------------------------------
39038 + | Shadow | Shadow HMTD |
39039 + | HMTD | Match Table |
39040 + | (16 bytes) | (maximal size) |
39041 + --------------------------------
39042 + */
39043 +
39044 + err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16),
39045 + (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN);
39046 + if (err != E_OK)
39047 + {
39048 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
39049 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39050 + ("MURAM allocation for HdrManip node shadow"));
39051 + }
39052 +
39053 + if (p_FmPcdManipParams->h_NextManip
39054 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
39055 + && (MANIP_DONT_REPARSE(p_Manip)))
39056 + {
39057 + p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip,
39058 + e_MANIP_HMCT);
39059 + p_CurManip = p_FmPcdManipParams->h_NextManip;
39060 + /* Run till the last Manip (which is the first to configure) */
39061 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39062 + p_CurManip = p_CurManip->h_NextManip;
39063 +
39064 + while (p_CurManip)
39065 + {
39066 + /* If this is a unified table, point to the part of the table
39067 + * which is the relative offset in HMCT.
39068 + */
39069 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
39070 + (p_Manip->tableSize +
39071 + (PTR_TO_UINT(p_CurManip->p_Hmct) -
39072 + PTR_TO_UINT(p_OldHmct))));
39073 + if (p_CurManip->p_Data)
39074 + p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
39075 + (p_Manip->tableSize +
39076 + (PTR_TO_UINT(p_CurManip->p_Data) -
39077 + PTR_TO_UINT(p_OldHmct))));
39078 + else
39079 + p_TmpDataPtr = NULL;
39080 +
39081 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39082 + p_TmpDataPtr, FALSE);
39083 + /* update old manip table pointer */
39084 + MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr);
39085 + MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr);
39086 +
39087 + p_CurManip = p_CurManip->h_PrevManip;
39088 + }
39089 + /* We copied the HMCT to create a new large HMCT so we can free the old one */
39090 + FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip),
39091 + p_OldHmct);
39092 + }
39093 +
39094 + /* Fill table */
39095 + err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct,
39096 + p_Manip->p_Data, TRUE);
39097 + if (err)
39098 + {
39099 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
39100 + RETURN_ERROR(MINOR, err, NO_MSG);
39101 + }
39102 +
39103 + /* Build HMTD (table descriptor) */
39104 + tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */
39105 +
39106 + /* add parseAfterManip */
39107 + if (!p_Manip->dontParseAfterManip)
39108 + tmpReg |= HMTD_CFG_PRS_AFTER_HM;
39109 +
39110 + /* create cascade */
39111 + /*if (p_FmPcdManipParams->h_NextManip
39112 + && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/
39113 + if (p_Manip->cascaded)
39114 + {
39115 + uint16_t nextAd;
39116 + /* indicate that there's another HM table descriptor */
39117 + tmpReg |= HMTD_CFG_NEXT_AD_EN;
39118 + /* get address of next HMTD (table descriptor; h_Ad).
39119 + * If the next HMTD was removed due to table unifing, get the address
39120 + * of the "next next" as written in the h_Ad of the next h_Manip node.
39121 + */
39122 + if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST)
39123 + nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
39124 + else
39125 + nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx;
39126 +
39127 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd);
39128 + }
39129 +
39130 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg);
39131 + WRITE_UINT32(
39132 + ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr,
39133 + (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
39134 +
39135 + WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC);
39136 +
39137 + if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST)
39138 + {
39139 + /* The HMTD of the next Manip is never going to be used */
39140 + if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate)
39141 + FM_MURAM_FreeMem(
39142 + ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram,
39143 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
39144 + else
39145 + XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
39146 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL;
39147 + }
39148 +
39149 + return E_OK;
39150 +}
39151 +
39152 +static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip,
39153 + t_FmPcdManipParams *p_FmPcdManipParams)
39154 +{
39155 + uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL;
39156 + uint16_t newSize;
39157 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
39158 + t_Error err;
39159 + t_FmPcdManip *p_CurManip = p_Manip;
39160 +
39161 + err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize);
39162 + if (err)
39163 + RETURN_ERROR(MINOR, err, NO_MSG);
39164 +
39165 + /* check coherency of new table parameters */
39166 + if (newSize > p_Manip->tableSize)
39167 + RETURN_ERROR(
39168 + MINOR,
39169 + E_INVALID_VALUE,
39170 + ("New Hdr Manip configuration requires larger size than current one (command table)."));
39171 + if (newDataSize > p_Manip->dataSize)
39172 + RETURN_ERROR(
39173 + MINOR,
39174 + E_INVALID_VALUE,
39175 + ("New Hdr Manip configuration requires larger size than current one (data)."));
39176 + if (p_FmPcdManipParams->h_NextManip)
39177 + RETURN_ERROR(
39178 + MINOR, E_INVALID_VALUE,
39179 + ("New Hdr Manip configuration can not contain h_NextManip."));
39180 + if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize))
39181 + RETURN_ERROR(
39182 + MINOR,
39183 + E_INVALID_VALUE,
39184 + ("New Hdr Manip configuration in a chained manipulation requires different size than current one."));
39185 + if (p_Manip->dontParseAfterManip
39186 + != p_FmPcdManipParams->u.hdr.dontParseAfterManip)
39187 + RETURN_ERROR(
39188 + MINOR,
39189 + E_INVALID_VALUE,
39190 + ("New Hdr Manip configuration differs in dontParseAfterManip value."));
39191 +
39192 + p_Manip->tableSize = newSize;
39193 + p_Manip->dataSize = newDataSize;
39194 +
39195 + /* Build the new table in the shadow */
39196 + if (!MANIP_IS_UNIFIED(p_Manip))
39197 + {
39198 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
39199 + if (p_Manip->p_Data)
39200 + p_TmpDataPtr =
39201 + (uint8_t*)PTR_MOVE(p_TmpHmctPtr,
39202 + (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct)));
39203 +
39204 + BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data,
39205 + FALSE);
39206 + }
39207 + else
39208 + {
39209 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
39210 + ASSERT_COND(p_WholeHmct);
39211 +
39212 + /* Run till the last Manip (which is the first to configure) */
39213 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39214 + p_CurManip = p_CurManip->h_NextManip;
39215 +
39216 + while (p_CurManip)
39217 + {
39218 + /* If this is a non-head node in a unified table, point to the part of the shadow
39219 + * which is the relative offset in HMCT.
39220 + * else, point to the beginning of the
39221 + * shadow table (we save 16 for the HMTD.
39222 + */
39223 + p_TmpHmctPtr =
39224 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
39225 + (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct)));
39226 + if (p_CurManip->p_Data)
39227 + p_TmpDataPtr =
39228 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
39229 + (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct)));
39230 +
39231 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39232 + p_TmpDataPtr, FALSE);
39233 + p_CurManip = p_CurManip->h_PrevManip;
39234 + }
39235 + }
39236 +
39237 + return E_OK;
39238 +}
39239 +
39240 +static t_Error CreateManipActionBackToOrig(
39241 + t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams)
39242 +{
39243 + uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr;
39244 + t_FmPcdManip *p_CurManip = p_Manip;
39245 +
39246 + /* Build the new table in the shadow */
39247 + if (!MANIP_IS_UNIFIED(p_Manip))
39248 + BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data,
39249 + FALSE);
39250 + else
39251 + {
39252 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
39253 + ASSERT_COND(p_WholeHmct);
39254 +
39255 + /* Run till the last Manip (which is the first to configure) */
39256 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39257 + p_CurManip = p_CurManip->h_NextManip;
39258 +
39259 + while (p_CurManip)
39260 + {
39261 + /* If this is a unified table, point to the part of the table
39262 + * which is the relative offset in HMCT.
39263 + */
39264 + p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/
39265 + p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/
39266 +
39267 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39268 + p_TmpDataPtr, FALSE);
39269 +
39270 + p_CurManip = p_CurManip->h_PrevManip;
39271 + }
39272 + }
39273 +
39274 + return E_OK;
39275 +}
39276 +
39277 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
39278 +static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
39279 +{
39280 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
39281 + t_Handle p_Ad;
39282 + uint32_t tmpReg32 = 0;
39283 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
39284 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
39285 +
39286 + switch (p_Manip->opcode)
39287 + {
39288 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
39289 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
39290 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
39291 + {
39292 + tmpReg32 =
39293 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
39294 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
39295 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets =
39296 + tmpReg32;
39297 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
39298 + p_Manip->icOffset = icOffset;
39299 + }
39300 + else
39301 + {
39302 + if (p_Manip->icOffset != icOffset)
39303 + RETURN_ERROR(
39304 + MAJOR,
39305 + E_INVALID_VALUE,
39306 + ("this manipulation was updated previously by different value"););
39307 + }
39308 + break;
39309 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
39310 + if (p_Manip->h_Frag)
39311 + {
39312 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
39313 + {
39314 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
39315 + tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
39316 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
39317 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
39318 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
39319 + p_Manip->icOffset = icOffset;
39320 + }
39321 + else
39322 + {
39323 + if (p_Manip->icOffset != icOffset)
39324 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
39325 + }
39326 + }
39327 + break;
39328 + }
39329 +
39330 + return E_OK;
39331 +}
39332 +
39333 +static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(
39334 + t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
39335 +{
39336 +
39337 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39338 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39339 + t_Error err;
39340 + uint32_t tmpReg32;
39341 +
39342 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39343 +
39344 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
39345 + SANITY_CHECK_RETURN_ERROR(
39346 + (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX),
39347 + E_INVALID_STATE);
39348 + SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
39349 +
39350 + if (p_Manip->updateParams)
39351 + {
39352 + if ((!(p_Manip->updateParams & OFFSET_OF_PR))
39353 + || (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39354 + RETURN_ERROR(
39355 + MAJOR, E_INVALID_STATE,
39356 + ("in this stage parameters from Port has not be updated"));
39357 +
39358 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39359 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39360 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39361 +
39362 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39363 + if (err)
39364 + RETURN_ERROR(MAJOR, err, NO_MSG);
39365 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39366 + RETURN_ERROR(
39367 + MAJOR, E_INVALID_STATE,
39368 + ("Parser result offset wasn't configured previousely"));
39369 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39370 + ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
39371 +#endif
39372 + }
39373 + else
39374 + if (validate)
39375 + {
39376 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39377 + || (p_Manip->updateParams & OFFSET_OF_PR))
39378 + RETURN_ERROR(
39379 + MAJOR, E_INVALID_STATE,
39380 + ("in this stage parameters from Port has be updated"));
39381 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39382 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39383 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39384 +
39385 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39386 + if (err)
39387 + RETURN_ERROR(MAJOR, err, NO_MSG);
39388 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39389 + RETURN_ERROR(
39390 + MAJOR, E_INVALID_STATE,
39391 + ("Parser result offset wasn't configured previousely"));
39392 +
39393 + }
39394 +
39395 + ASSERT_COND(p_Ad);
39396 +
39397 + if (p_Manip->updateParams & OFFSET_OF_PR)
39398 + {
39399 + tmpReg32 = 0;
39400 + tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
39401 + WRITE_UINT32(p_Ad->matchTblPtr,
39402 + (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
39403 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39404 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39405 + }
39406 + else
39407 + if (validate)
39408 + {
39409 + tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
39410 + if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
39411 + RETURN_ERROR(
39412 + MAJOR,
39413 + E_INVALID_STATE,
39414 + ("this manipulation was updated previousely by different value"););
39415 + }
39416 +
39417 + return E_OK;
39418 +}
39419 +
39420 +static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
39421 +{
39422 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39423 + t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
39424 + uint32_t tmpReg32 = 0;
39425 +
39426 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39427 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39428 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39429 + 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);
39430 +
39431 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39432 +
39433 + if (p_Manip->updateParams)
39434 + {
39435 +
39436 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39437 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39438 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39439 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39440 + if (!p_SavedManipParams)
39441 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39442 + p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
39443 +
39444 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39445 + tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16);
39446 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39447 +
39448 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39449 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39450 + }
39451 + else if (validate)
39452 + {
39453 +
39454 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39455 + if (!p_SavedManipParams)
39456 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39457 + if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)
39458 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39459 + }
39460 +
39461 + return E_OK;
39462 +}
39463 +
39464 +static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort,
39465 + t_FmPcdManip *p_Manip,
39466 + t_Handle h_Ad,
39467 + bool validate,
39468 + t_Handle h_FmTree)
39469 +{
39470 + t_AdOfTypeContLookup *p_Ad;
39471 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39472 + t_Error err;
39473 + uint32_t tmpReg32 = 0;
39474 + t_FmPcdCcSavedManipParams *p_SavedManipParams;
39475 +
39476 + UNUSED(h_Ad);
39477 +
39478 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39479 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39480 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39481 + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) ||
39482 + (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
39483 +
39484 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39485 +
39486 + if (p_Manip->updateParams)
39487 + {
39488 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39489 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39490 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39491 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39492 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39493 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39494 + /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */
39495 + fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1;
39496 +
39497 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39498 + if (err)
39499 + RETURN_ERROR(MAJOR, err, NO_MSG);
39500 +
39501 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39502 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39503 +
39504 + p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
39505 + p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39506 +
39507 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39508 + ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
39509 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39510 +
39511 + FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams);
39512 + }
39513 + else if (validate)
39514 + {
39515 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) ||
39516 + ((p_Manip->updateParams & OFFSET_OF_DATA)))
39517 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39518 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39519 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39520 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39521 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39522 + if (err)
39523 + RETURN_ERROR(MAJOR, err, NO_MSG);
39524 +
39525 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39526 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39527 + }
39528 +
39529 + if (p_Manip->updateParams)
39530 + {
39531 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39532 + tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
39533 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39534 +
39535 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39536 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39537 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39538 + }
39539 + else if (validate)
39540 + {
39541 + if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)
39542 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39543 + }
39544 +
39545 + return E_OK;
39546 +}
39547 +
39548 +static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
39549 + t_Handle h_FmPort,
39550 + t_FmPcdManip *p_Manip,
39551 + t_Handle h_Ad,
39552 + bool validate)
39553 +{
39554 + t_CapwapReasmPram *p_ReassmTbl;
39555 + t_Error err;
39556 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39557 + uint8_t i = 0;
39558 + uint16_t size;
39559 + uint32_t tmpReg32;
39560 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
39561 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
39562 +
39563 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39564 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39565 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
39566 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
39567 + SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
39568 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
39569 +
39570 + if (p_Manip->h_FmPcd != h_FmPcd)
39571 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
39572 + ("handler of PCD previously was initiated by different value"));
39573 +
39574 + UNUSED(h_Ad);
39575 +
39576 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39577 + p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
39578 +
39579 + if (p_Manip->updateParams)
39580 + {
39581 + if ((!(p_Manip->updateParams & NUM_OF_TASKS) &&
39582 + !(p_Manip->updateParams & OFFSET_OF_DATA) &&
39583 + !(p_Manip->updateParams & OFFSET_OF_PR) &&
39584 + !(p_Manip->updateParams & HW_PORT_ID)) ||
39585 + ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) ||
39586 + (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) ||
39587 + (p_Manip->shadowUpdateParams & HW_PORT_ID)))
39588 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39589 +
39590 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39591 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39592 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39593 +
39594 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39595 + if (err)
39596 + RETURN_ERROR(MAJOR, err, NO_MSG);
39597 +
39598 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39599 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
39600 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39601 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
39602 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39603 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39604 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39605 + ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
39606 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39607 + }
39608 + else if (validate)
39609 + {
39610 + if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) &&
39611 + !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
39612 + !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) &&
39613 + !(p_Manip->shadowUpdateParams & HW_PORT_ID)) &&
39614 + ((p_Manip->updateParams & NUM_OF_TASKS) ||
39615 + (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) ||
39616 + (p_Manip->updateParams & HW_PORT_ID)))
39617 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39618 +
39619 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39620 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39621 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39622 +
39623 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39624 + if (err)
39625 + RETURN_ERROR(MAJOR, err, NO_MSG);
39626 +
39627 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39628 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously"));
39629 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39630 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously"));
39631 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39632 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39633 + }
39634 +
39635 + if (p_Manip->updateParams)
39636 + {
39637 + if (p_Manip->updateParams & NUM_OF_TASKS)
39638 + {
39639 + /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */
39640 + size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks);
39641 + if (size > 255)
39642 + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
39643 +
39644 + p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
39645 +
39646 + /*p_ReassmFrmDescrIndxPoolTbl*/
39647 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl =
39648 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39649 + (uint32_t)(size + 1),
39650 + 4);
39651 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
39652 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table"));
39653 +
39654 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
39655 +
39656 + for ( i = 0; i < size; i++)
39657 + WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
39658 +
39659 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
39660 +
39661 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
39662 +
39663 + /*p_ReassmFrmDescrPoolTbl*/
39664 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl =
39665 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39666 + (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
39667 + 4);
39668 +
39669 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
39670 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table"));
39671 +
39672 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
39673 +
39674 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
39675 +
39676 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
39677 +
39678 + /*p_TimeOutTbl*/
39679 +
39680 + p_Manip->capwapFragParams.p_TimeOutTbl =
39681 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39682 + (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
39683 + 4);
39684 +
39685 + if (!p_Manip->capwapFragParams.p_TimeOutTbl)
39686 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table"));
39687 +
39688 + MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
39689 +
39690 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
39691 + WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
39692 +
39693 + p_Manip->updateParams &= ~NUM_OF_TASKS;
39694 + p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
39695 + }
39696 +
39697 + if (p_Manip->updateParams & OFFSET_OF_DATA)
39698 + {
39699 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39700 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39701 + tmpReg32|= p_Manip->capwapFragParams.dataOffset;
39702 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39703 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39704 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39705 + }
39706 +
39707 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39708 + {
39709 + p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
39710 +
39711 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39712 + tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
39713 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39714 +
39715 + tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
39716 + tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24;
39717 + WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
39718 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39719 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39720 + }
39721 + else
39722 + {
39723 + p_Manip->capwapFragParams.prOffset = 0xff;
39724 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39725 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39726 + }
39727 +
39728 + p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
39729 + p_Manip->updateParams &= ~HW_PORT_ID;
39730 + p_Manip->shadowUpdateParams |= HW_PORT_ID;
39731 +
39732 + /*timeout hc */
39733 + ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames;
39734 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24;
39735 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
39736 + ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2;
39737 + return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
39738 + }
39739 +
39740 + else if (validate)
39741 + {
39742 + if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId)
39743 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
39744 + if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks)
39745 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
39746 +
39747 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39748 + {
39749 + if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
39750 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39751 + }
39752 + else
39753 + {
39754 + if (p_Manip->capwapFragParams.prOffset != 0xff)
39755 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39756 + }
39757 + if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset)
39758 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
39759 + }
39760 +
39761 + return E_OK;
39762 +}
39763 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
39764 +
39765 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
39766 +{
39767 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39768 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 };
39769 + t_Error err = E_OK;
39770 + uint8_t result;
39771 + uint32_t bitFor1Micro, tsbs, log2num;
39772 +
39773 + ASSERT_COND(p_FmPcd);
39774 + ASSERT_COND(h_ReasmCommonPramTbl);
39775 +
39776 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39777 + if (bitFor1Micro == 0)
39778 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39779 +
39780 + bitFor1Micro = 32 - bitFor1Micro;
39781 + LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num);
39782 + tsbs = bitFor1Micro - log2num;
39783 +
39784 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(
39785 + h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
39786 + ccReassmTimeoutParams.tsbs = (uint8_t)tsbs;
39787 + ccReassmTimeoutParams.activate = TRUE;
39788 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams,
39789 + &result)) != E_OK)
39790 + RETURN_ERROR(MAJOR, err, NO_MSG);
39791 +
39792 + switch (result)
39793 + {
39794 + case (0):
39795 + return E_OK;
39796 + case (1):
39797 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM"));
39798 + case (2):
39799 + RETURN_ERROR(
39800 + MAJOR, E_NO_MEMORY,
39801 + ("failed to allocate internal buffer from the HC-Port"));
39802 + case (3):
39803 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
39804 + ("'Disable Timeout Task' with invalid IPRCPT"));
39805 + case (4):
39806 + RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks"));
39807 + case (5):
39808 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command"));
39809 + default:
39810 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
39811 + }
39812 + return E_OK;
39813 +}
39814 +
39815 +static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip)
39816 +{
39817 + uint32_t tmpReg32 = 0, i, bitFor1Micro;
39818 + uint64_t tmpReg64, size;
39819 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
39820 + t_Error err = E_OK;
39821 +
39822 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39823 + if (bitFor1Micro == 0)
39824 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39825 +
39826 + /* Allocation of the Reassembly Common Parameters table. This table is located in the
39827 + MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */
39828 + p_Manip->reassmParams.p_ReassCommonTbl =
39829 + (t_ReassCommonTbl *)FM_MURAM_AllocMem(
39830 + p_FmPcd->h_FmMuram,
39831 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE,
39832 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN);
39833 +
39834 + if (!p_Manip->reassmParams.p_ReassCommonTbl)
39835 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39836 + ("MURAM alloc for Reassembly common parameters table"));
39837 +
39838 + MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0,
39839 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE);
39840 +
39841 + /* Setting the TimeOut Mode.*/
39842 + tmpReg32 = 0;
39843 + if (p_Manip->reassmParams.timeOutMode
39844 + == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
39845 + tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES;
39846 +
39847 + /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID.
39848 + In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/
39849 + tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames;
39850 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid,
39851 + tmpReg32);
39852 +
39853 + /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/
39854 + size = p_Manip->reassmParams.maxNumFramesInProcess + 129;
39855 +
39856 + /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */
39857 + p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr =
39858 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39859 + (uint32_t)(size * 2),
39860 + 256));
39861 + if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
39862 + RETURN_ERROR(
39863 + MAJOR, E_NO_MEMORY,
39864 + ("MURAM alloc for Reassembly frame descriptor indexes pool"));
39865 +
39866 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr),
39867 + 0, (uint32_t)(size * 2));
39868 +
39869 + /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to
39870 + the maximum number of frames that are allowed to be reassembled simultaneously + 128.
39871 + The last entry in this pool must contain the index zero*/
39872 + for (i = 0; i < (size - 1); i++)
39873 + WRITE_UINT16(
39874 + *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)),
39875 + (uint16_t)(i+1));
39876 +
39877 + /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */
39878 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39879 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr))
39880 + - p_FmPcd->physicalMuramBase);
39881 + WRITE_UINT32(
39882 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr,
39883 + tmpReg32);
39884 +
39885 + /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory.
39886 + The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/
39887 + p_Manip->reassmParams.reassFrmDescrPoolTblAddr =
39888 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64));
39889 +
39890 + if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
39891 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39892 +
39893 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0,
39894 + (uint32_t)(size * 64));
39895 +
39896 + /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/
39897 + tmpReg64 = (uint64_t)(XX_VirtToPhys(
39898 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)));
39899 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39900 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39901 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39902 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39903 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39904 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39905 + WRITE_UINT32(
39906 + p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi,
39907 + (uint32_t)(tmpReg64 >> 32));
39908 + WRITE_UINT32(
39909 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow,
39910 + (uint32_t)tmpReg64);
39911 +
39912 + /*Allocation of the TimeOut table - This table resides in the MURAM.
39913 + The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/
39914 + p_Manip->reassmParams.timeOutTblAddr =
39915 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8));
39916 +
39917 + if (!p_Manip->reassmParams.timeOutTblAddr)
39918 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39919 + ("MURAM alloc for Reassembly timeout table"));
39920 +
39921 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0,
39922 + (uint16_t)(size * 8));
39923 +
39924 + /* Sets the TimeOut table offset from MURAM */
39925 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39926 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr))
39927 + - p_FmPcd->physicalMuramBase);
39928 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr,
39929 + tmpReg32);
39930 +
39931 + /* Sets the Expiration Delay */
39932 + tmpReg32 = 0;
39933 + tmpReg32 |= (((uint32_t)(1 << bitFor1Micro))
39934 + * p_Manip->reassmParams.timeoutThresholdForReassmProcess);
39935 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay,
39936 + tmpReg32);
39937 +
39938 + err = FmPcdRegisterReassmPort(p_FmPcd,
39939 + p_Manip->reassmParams.p_ReassCommonTbl);
39940 + if (err != E_OK)
39941 + {
39942 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
39943 + p_Manip->reassmParams.p_ReassCommonTbl);
39944 + RETURN_ERROR(MAJOR, err, ("port registration"));
39945 + }
39946 +
39947 + return err;
39948 +}
39949 +
39950 +static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
39951 +{
39952 + t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
39953 + uint32_t tmpReg32, autoLearnHashTblSize;
39954 + uint32_t numOfWays, setSize, setSizeCode, keySize;
39955 + uint32_t waySize, numOfSets, numOfEntries;
39956 + uint64_t tmpReg64;
39957 + uint16_t minFragSize;
39958 + uint16_t maxReassemSize;
39959 + uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr;
39960 + t_ReassTbl **p_ReassTbl;
39961 +
39962 + switch (hdr)
39963 + {
39964 + case HEADER_TYPE_IPv4:
39965 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl;
39966 + p_AutoLearnHashTblAddr =
39967 + &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr;
39968 + p_AutoLearnSetLockTblAddr =
39969 + &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr;
39970 + minFragSize = p_Manip->reassmParams.ip.minFragSize[0];
39971 + maxReassemSize = 0;
39972 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0];
39973 + keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */
39974 + break;
39975 + case HEADER_TYPE_IPv6:
39976 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl;
39977 + p_AutoLearnHashTblAddr =
39978 + &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr;
39979 + p_AutoLearnSetLockTblAddr =
39980 + &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr;
39981 + minFragSize = p_Manip->reassmParams.ip.minFragSize[1];
39982 + maxReassemSize = 0;
39983 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1];
39984 + keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */
39985 + if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH)
39986 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways"));
39987 + break;
39988 + case HEADER_TYPE_CAPWAP:
39989 + p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl;
39990 + p_AutoLearnHashTblAddr =
39991 + &p_Manip->reassmParams.capwap.autoLearnHashTblAddr;
39992 + p_AutoLearnSetLockTblAddr =
39993 + &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr;
39994 + minFragSize = 0;
39995 + maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize;
39996 + numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry;
39997 + keySize = 4;
39998 + break;
39999 + default:
40000 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
40001 + }
40002 + keySize += 2; /* 2 bytes reserved for RFDIndex */
40003 +#if (DPAA_VERSION >= 11)
40004 + keySize += 2; /* 2 bytes reserved */
40005 +#endif /* (DPAA_VERSION >= 11) */
40006 + waySize = ROUND_UP(keySize, 8);
40007 +
40008 + /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/
40009 + *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem(
40010 + p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE,
40011 + FM_PCD_MANIP_REASM_TABLE_ALIGN);
40012 + if (!*p_ReassTbl)
40013 + RETURN_ERROR( MAJOR, E_NO_MEMORY,
40014 + ("MURAM alloc for Reassembly specific parameters table"));
40015 + memset(*p_ReassTbl, 0, sizeof(t_ReassTbl));
40016 +
40017 + /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/
40018 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl)
40019 + - p_FmPcd->physicalMuramBase);
40020 + WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32);
40021 +
40022 + /* Calculate set size (set size is rounded-up to next power of 2) */
40023 + NEXT_POWER_OF_2(numOfWays * waySize, setSize);
40024 +
40025 + /* Get set size code */
40026 + LOG2(setSize, setSizeCode);
40027 +
40028 + /* Sets ways number and set size code */
40029 + WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize,
40030 + (uint16_t)((numOfWays << 8) | setSizeCode));
40031 +
40032 + /* It is recommended that the total number of entries in this table
40033 + (number of sets * number of ways) will be twice the number of frames that
40034 + are expected to be reassembled simultaneously.*/
40035 + numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2);
40036 +
40037 + /* sets number calculation - number of entries = number of sets * number of ways */
40038 + numOfSets = numOfEntries / numOfWays;
40039 +
40040 + /* Sets AutoLearnHashKeyMask*/
40041 + NEXT_POWER_OF_2(numOfSets, numOfSets);
40042 +
40043 + WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask,
40044 + (uint16_t)(numOfSets - 1));
40045 +
40046 + /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory.
40047 + The size of this table is determined by the number of sets and the set size.
40048 + Table size = set size * number of sets
40049 + This table base address should be aligned to SetSize.*/
40050 + autoLearnHashTblSize = numOfSets * setSize;
40051 +
40052 + *p_AutoLearnHashTblAddr =
40053 + PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize));
40054 + if (!*p_AutoLearnHashTblAddr)
40055 + {
40056 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
40057 + *p_ReassTbl = NULL;
40058 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
40059 + }
40060 + MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize);
40061 +
40062 + /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */
40063 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
40064 + & FM_PCD_MANIP_REASM_LIODN_MASK)
40065 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
40066 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
40067 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
40068 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
40069 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
40070 + WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi,
40071 + (uint32_t)(tmpReg64 >> 32));
40072 + WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
40073 +
40074 + /* Allocation of the Set Lock table - This table resides in external memory
40075 + The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes.
40076 + This table resides in external memory and its base address should be 4-byte aligned */
40077 + *p_AutoLearnSetLockTblAddr =
40078 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4));
40079 + if (!*p_AutoLearnSetLockTblAddr)
40080 + {
40081 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
40082 + *p_ReassTbl = NULL;
40083 + XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
40084 + *p_AutoLearnHashTblAddr = 0;
40085 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
40086 + }
40087 + MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4));
40088 +
40089 + /* sets Set Lock table pointer and liodn offset*/
40090 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
40091 + & FM_PCD_MANIP_REASM_LIODN_MASK)
40092 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
40093 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
40094 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
40095 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
40096 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr));
40097 + WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi,
40098 + (uint32_t)(tmpReg64 >> 32));
40099 + WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
40100 +
40101 + /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */
40102 + WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize);
40103 +
40104 + WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize);
40105 +
40106 + return E_OK;
40107 +}
40108 +
40109 +static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams,
40110 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
40111 + t_Handle h_Ad, bool validate)
40112 +{
40113 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40114 + uint32_t tmpReg32;
40115 + t_Error err;
40116 + t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams;
40117 +#if (DPAA_VERSION >= 11)
40118 + t_FmPcdCtrlParamsPage *p_ParamsPage;
40119 +#endif /* (DPAA_VERSION >= 11) */
40120 +
40121 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
40122 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE);
40123 + SANITY_CHECK_RETURN_ERROR(
40124 + (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY),
40125 + E_INVALID_STATE);
40126 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
40127 + SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams,
40128 + E_INVALID_HANDLE);
40129 +
40130 + UNUSED(h_Ad);
40131 +
40132 + if (!p_Manip->updateParams)
40133 + return E_OK;
40134 +
40135 + if (p_Manip->h_FmPcd != h_FmPcd)
40136 + RETURN_ERROR(
40137 + MAJOR, E_INVALID_STATE,
40138 + ("handler of PCD previously was initiated by different value"));
40139 +
40140 + if (p_Manip->updateParams)
40141 + {
40142 + if ((!(p_Manip->updateParams
40143 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))
40144 + || ((p_Manip->shadowUpdateParams
40145 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))))
40146 + RETURN_ERROR(
40147 + MAJOR, E_INVALID_STATE,
40148 + ("in this stage parameters from Port has not be updated"));
40149 +
40150 + fmPortGetSetCcParams.setCcParams.type = 0;
40151 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
40152 + {
40153 + fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE;
40154 + fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF;
40155 + }
40156 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV;
40157 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
40158 + != E_OK)
40159 + RETURN_ERROR(MAJOR, err, NO_MSG);
40160 + if (fmPortGetSetCcParams.getCcParams.type
40161 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV))
40162 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40163 + ("offset of the data wasn't configured previously"));
40164 + if (p_Manip->updateParams
40165 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))
40166 + {
40167 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40168 + uint8_t *p_Ptr, i, totalNumOfTnums;
40169 +
40170 + totalNumOfTnums =
40171 + (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks
40172 + + fmPortGetSetCcParams.getCcParams.numOfExtraTasks);
40173 +
40174 + p_Manip->reassmParams.internalBufferPoolAddr =
40175 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40176 + (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS),
40177 + BMI_FIFO_UNITS));
40178 + if (!p_Manip->reassmParams.internalBufferPoolAddr)
40179 + RETURN_ERROR(
40180 + MAJOR, E_NO_MEMORY,
40181 + ("MURAM alloc for Reassembly internal buffers pool"));
40182 + MemSet8(
40183 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr),
40184 + 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS));
40185 +
40186 + p_Manip->reassmParams.internalBufferPoolManagementIndexAddr =
40187 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40188 + (uint32_t)(5 + totalNumOfTnums),
40189 + 4));
40190 + if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
40191 + RETURN_ERROR(
40192 + MAJOR,
40193 + E_NO_MEMORY,
40194 + ("MURAM alloc for Reassembly internal buffers management"));
40195 +
40196 + p_Ptr =
40197 + (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr);
40198 + WRITE_UINT32(
40199 + *(uint32_t*)p_Ptr,
40200 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase));
40201 + for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++)
40202 + WRITE_UINT8(*p_Ptr, i);
40203 + WRITE_UINT8(*p_Ptr, 0xFF);
40204 +
40205 + tmpReg32 =
40206 + (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT)
40207 + | ((uint32_t)(XX_VirtToPhys(
40208 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr))
40209 + - p_FmPcd->physicalMuramBase));
40210 + WRITE_UINT32(
40211 + p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement,
40212 + tmpReg32);
40213 +
40214 + p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
40215 + | DISCARD_MASK);
40216 + p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
40217 + | DISCARD_MASK);
40218 + }
40219 + }
40220 +
40221 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
40222 + {
40223 + if (p_Manip->reassmParams.capwap.h_Scheme)
40224 + {
40225 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40226 + p_Manip->reassmParams.capwap.h_Scheme;
40227 + p_PcdParams->p_KgParams->numOfSchemes++;
40228 + }
40229 +
40230 + }
40231 + else
40232 + {
40233 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
40234 + {
40235 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40236 + p_Manip->reassmParams.ip.h_Ipv4Scheme;
40237 + p_PcdParams->p_KgParams->numOfSchemes++;
40238 + }
40239 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
40240 + {
40241 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40242 + p_Manip->reassmParams.ip.h_Ipv6Scheme;
40243 + p_PcdParams->p_KgParams->numOfSchemes++;
40244 + }
40245 +#if (DPAA_VERSION >= 11)
40246 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6)
40247 + {
40248 + if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
40249 + (void**)&p_ParamsPage)) != E_OK)
40250 + RETURN_ERROR(MAJOR, err, NO_MSG);
40251 +
40252 + tmpReg32 = NIA_ENG_KG;
40253 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
40254 + {
40255 + tmpReg32 |= NIA_KG_DIRECT;
40256 + tmpReg32 |= NIA_KG_CC_EN;
40257 + tmpReg32 |= FmPcdKgGetSchemeId(
40258 + p_Manip->reassmParams.ip.h_Ipv4Scheme);
40259 + WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32);
40260 + }
40261 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
40262 + {
40263 + tmpReg32 &= ~NIA_AC_MASK;
40264 + tmpReg32 |= NIA_KG_DIRECT;
40265 + tmpReg32 |= NIA_KG_CC_EN;
40266 + tmpReg32 |= FmPcdKgGetSchemeId(
40267 + p_Manip->reassmParams.ip.h_Ipv6Scheme);
40268 + WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32);
40269 + }
40270 + }
40271 +#else
40272 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6)
40273 + {
40274 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask,
40275 + fmPortGetSetCcParams.getCcParams.discardMask);
40276 + }
40277 +#endif /* (DPAA_VERSION >= 11) */
40278 + }
40279 + return E_OK;
40280 +}
40281 +
40282 +#if (DPAA_VERSION == 10)
40283 +static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid)
40284 +{
40285 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
40286 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
40287 + t_Error err;
40288 +
40289 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
40290 +
40291 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
40292 +
40293 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS;
40294 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
40295 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
40296 + RETURN_ERROR(MAJOR, err, NO_MSG);
40297 +
40298 + if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0)
40299 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed,"
40300 + "Failed to release %d buffers to the BM (missing FBPRs)",
40301 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers));
40302 +
40303 + return E_OK;
40304 +}
40305 +
40306 +static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid)
40307 +{
40308 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
40309 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
40310 + t_Error err;
40311 +
40312 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
40313 +
40314 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
40315 +
40316 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
40317 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
40318 + RETURN_ERROR(MAJOR, err, NO_MSG);
40319 +
40320 + return E_OK;
40321 +}
40322 +#endif /* (DPAA_VERSION == 10) */
40323 +
40324 +static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
40325 +{
40326 + if (p_Manip->h_Ad)
40327 + {
40328 + if (p_Manip->muramAllocate)
40329 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
40330 + else
40331 + XX_Free(p_Manip->h_Ad);
40332 + p_Manip->h_Ad = NULL;
40333 + }
40334 + if (p_Manip->p_Template)
40335 + {
40336 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
40337 + p_Manip->p_Template = NULL;
40338 + }
40339 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40340 + if (p_Manip->h_Frag)
40341 + {
40342 + if (p_Manip->capwapFragParams.p_AutoLearnHashTbl)
40343 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40344 + p_Manip->capwapFragParams.p_AutoLearnHashTbl);
40345 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
40346 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40347 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl);
40348 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
40349 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40350 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl);
40351 + if (p_Manip->capwapFragParams.p_TimeOutTbl)
40352 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40353 + p_Manip->capwapFragParams.p_TimeOutTbl);
40354 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
40355 +
40356 + }
40357 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40358 + if (p_Manip->frag)
40359 + {
40360 + if (p_Manip->fragParams.p_Frag)
40361 + {
40362 +#if (DPAA_VERSION == 10)
40363 + FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid);
40364 +#endif /* (DPAA_VERSION == 10) */
40365 +
40366 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
40367 + }
40368 + }
40369 + else
40370 + if (p_Manip->reassm)
40371 + {
40372 + FmPcdUnregisterReassmPort(p_FmPcd,
40373 + p_Manip->reassmParams.p_ReassCommonTbl);
40374 +
40375 + if (p_Manip->reassmParams.timeOutTblAddr)
40376 + FM_MURAM_FreeMem(
40377 + p_FmPcd->h_FmMuram,
40378 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr));
40379 + if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
40380 + XX_FreeSmart(
40381 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr));
40382 + if (p_Manip->reassmParams.p_ReassCommonTbl)
40383 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40384 + p_Manip->reassmParams.p_ReassCommonTbl);
40385 + if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
40386 + FM_MURAM_FreeMem(
40387 + p_FmPcd->h_FmMuram,
40388 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr));
40389 + if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
40390 + FM_MURAM_FreeMem(
40391 + p_FmPcd->h_FmMuram,
40392 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr));
40393 + if (p_Manip->reassmParams.internalBufferPoolAddr)
40394 + FM_MURAM_FreeMem(
40395 + p_FmPcd->h_FmMuram,
40396 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr));
40397 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP)
40398 + {
40399 +
40400 + }
40401 + else
40402 + {
40403 + if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)
40404 + XX_FreeSmart(
40405 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr));
40406 + if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)
40407 + XX_FreeSmart(
40408 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr));
40409 + if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)
40410 + XX_FreeSmart(
40411 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr));
40412 + if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)
40413 + XX_FreeSmart(
40414 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr));
40415 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
40416 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40417 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl);
40418 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
40419 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40420 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl);
40421 + if (p_Manip->reassmParams.ip.h_Ipv6Ad)
40422 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad);
40423 + if (p_Manip->reassmParams.ip.h_Ipv4Ad)
40424 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad);
40425 + }
40426 + }
40427 +
40428 + if (p_Manip->p_StatsTbl)
40429 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
40430 +}
40431 +
40432 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40433 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
40434 +{
40435 + if (p_ManipParams->u.hdr.rmv)
40436 + {
40437 + switch (p_ManipParams->u.hdr.rmvParams.type)
40438 + {
40439 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40440 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40441 + {
40442 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) :
40443 + if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include)
40444 + {
40445 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40446 + {
40447 + case (HEADER_TYPE_CAPWAP_DTLS) :
40448 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40449 + p_Manip->muramAllocate = TRUE;
40450 + if (p_ManipParams->u.hdr.insrt)
40451 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
40452 + if (p_ManipParams->fragOrReasm)
40453 + {
40454 + if (!p_ManipParams->fragOrReasmParams.frag)
40455 + {
40456 + switch (p_ManipParams->fragOrReasmParams.hdr)
40457 + {
40458 + case (HEADER_TYPE_CAPWAP):
40459 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40460 + break;
40461 + default:
40462 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
40463 + }
40464 + }
40465 + else
40466 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
40467 + }
40468 + break;
40469 + default:
40470 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
40471 + }
40472 + }
40473 + else
40474 + {
40475 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40476 + {
40477 + case (HEADER_TYPE_CAPWAP_DTLS) :
40478 + case (HEADER_TYPE_CAPWAP) :
40479 + if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt)
40480 + 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"));
40481 + p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40482 + p_Manip->muramAllocate = TRUE;
40483 + p_ManipParams->u.hdr.insrt = TRUE; //internal frame header
40484 + break;
40485 + default :
40486 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40487 + }
40488 + }
40489 + break;
40490 + default :
40491 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40492 + }
40493 + break;
40494 + default:
40495 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40496 + }
40497 + }
40498 + else if (p_ManipParams->u.hdr.insrt)
40499 + {
40500 + switch (p_ManipParams->u.hdr.insrtParams.type)
40501 + {
40502 + case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) :
40503 +
40504 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
40505 + p_Manip->muramAllocate = FALSE;
40506 + if (p_ManipParams->fragOrReasm)
40507 + {
40508 + if (p_ManipParams->fragOrReasmParams.frag)
40509 + {
40510 + switch (p_ManipParams->fragOrReasmParams.hdr)
40511 + {
40512 + case (HEADER_TYPE_CAPWAP):
40513 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40514 + break;
40515 + default:
40516 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
40517 + }
40518 + }
40519 + else
40520 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
40521 + }
40522 + break;
40523 +
40524 + default:
40525 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
40526 + }
40527 + }
40528 + else if (p_ManipParams->fragOrReasm)
40529 + {
40530 + if (p_ManipParams->fragOrReasmParams.frag)
40531 + {
40532 + switch (p_ManipParams->fragOrReasmParams.hdr)
40533 + {
40534 + case (HEADER_TYPE_CAPWAP):
40535 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40536 + p_Manip->muramAllocate = FALSE;
40537 + break;
40538 + default:
40539 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
40540 + }
40541 + }
40542 + else
40543 + {
40544 + switch (p_ManipParams->fragOrReasmParams.hdr)
40545 + {
40546 + case (HEADER_TYPE_CAPWAP):
40547 + 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"));
40548 + default:
40549 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
40550 + }
40551 + }
40552 +
40553 + }
40554 + else
40555 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
40556 +
40557 + p_Manip->insrt = p_ManipParams->u.hdr.insrt;
40558 + p_Manip->rmv = p_ManipParams->u.hdr.rmv;
40559 +
40560 + return E_OK;
40561 +}
40562 +
40563 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40564 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip,
40565 + t_FmPcdManipParams *p_ManipParams)
40566 +{
40567 + switch (p_ManipParams->type)
40568 + {
40569 + case e_FM_PCD_MANIP_HDR:
40570 + /* Check that next-manip is not already used */
40571 + if (p_ManipParams->h_NextManip)
40572 + {
40573 + if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip))
40574 + RETURN_ERROR(
40575 + MAJOR, E_INVALID_STATE,
40576 + ("h_NextManip is already a part of another chain"));
40577 + if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40578 + != e_FM_PCD_MANIP_HDR) &&
40579 + (MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40580 + != e_FM_PCD_MANIP_FRAG))
40581 + RETURN_ERROR(
40582 + MAJOR,
40583 + E_NOT_SUPPORTED,
40584 + ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation."));
40585 + }
40586 +
40587 + if (p_ManipParams->u.hdr.rmv)
40588 + {
40589 + switch (p_ManipParams->u.hdr.rmvParams.type)
40590 + {
40591 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40592 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40593 + {
40594 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
40595 + break;
40596 +#if (DPAA_VERSION >= 11)
40597 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
40598 + break;
40599 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
40600 + {
40601 + t_Error err;
40602 + uint8_t prsArrayOffset;
40603 +
40604 + err =
40605 + GetPrOffsetByHeaderOrField(
40606 + &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
40607 + &prsArrayOffset);
40608 + if (err)
40609 + RETURN_ERROR(MAJOR, err, NO_MSG);
40610 + break;
40611 + }
40612 +#endif /* (DPAA_VERSION >= 11) */
40613 + default:
40614 + RETURN_ERROR(
40615 + MAJOR,
40616 + E_INVALID_STATE,
40617 + ("invalid type of remove manipulation"));
40618 + }
40619 + break;
40620 + case (e_FM_PCD_MANIP_RMV_GENERIC):
40621 + break;
40622 + default:
40623 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40624 + ("invalid type of remove manipulation"));
40625 + }
40626 + p_Manip->opcode = HMAN_OC;
40627 + p_Manip->muramAllocate = TRUE;
40628 + p_Manip->rmv = TRUE;
40629 + }
40630 + else
40631 + if (p_ManipParams->u.hdr.insrt)
40632 + {
40633 + switch (p_ManipParams->u.hdr.insrtParams.type)
40634 + {
40635 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
40636 + {
40637 + switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type)
40638 + {
40639 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
40640 + /* nothing to check */
40641 + break;
40642 +#if (DPAA_VERSION >= 11)
40643 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
40644 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
40645 + % 4)
40646 + RETURN_ERROR(
40647 + MAJOR,
40648 + E_INVALID_VALUE,
40649 + ("IP inserted header must be of size which is a multiple of four bytes"));
40650 + break;
40651 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
40652 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40653 + % 4)
40654 + RETURN_ERROR(
40655 + MAJOR,
40656 + E_INVALID_VALUE,
40657 + ("CAPWAP inserted header must be of size which is a multiple of four bytes"));
40658 + break;
40659 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
40660 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
40661 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40662 + != 8)
40663 + RETURN_ERROR(
40664 + MAJOR,
40665 + E_INVALID_VALUE,
40666 + ("Inserted header must be of size 8"));
40667 + break;
40668 +#endif /* (DPAA_VERSION >= 11) */
40669 + default:
40670 + RETURN_ERROR(
40671 + MAJOR,
40672 + E_INVALID_STATE,
40673 + ("unsupported insert by header type"));
40674 + }
40675 + }
40676 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
40677 + break;
40678 + default:
40679 + RETURN_ERROR(
40680 + MAJOR,
40681 + E_INVALID_STATE,
40682 + ("for only insert manipulation unsupported type"));
40683 + }
40684 + p_Manip->opcode = HMAN_OC;
40685 + p_Manip->muramAllocate = TRUE;
40686 + p_Manip->insrt = TRUE;
40687 + }
40688 + else
40689 + if (p_ManipParams->u.hdr.fieldUpdate)
40690 + {
40691 + /* Check parameters */
40692 + if (p_ManipParams->u.hdr.fieldUpdateParams.type
40693 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN)
40694 + {
40695 + if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40696 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
40697 + && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri
40698 + > 7))
40699 + RETURN_ERROR(
40700 + MAJOR, E_INVALID_VALUE,
40701 + ("vpri should get values of 0-7 "));
40702 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40703 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
40704 + {
40705 + int i;
40706 +
40707 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal
40708 + > 7)
40709 + RETURN_ERROR(
40710 + MAJOR,
40711 + E_INVALID_VALUE,
40712 + ("vpriDefVal should get values of 0-7 "));
40713 + for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS;
40714 + i++)
40715 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]
40716 + & 0xf0)
40717 + RETURN_ERROR(
40718 + MAJOR,
40719 + E_INVALID_VALUE,
40720 + ("dscpToVpriTabl value out of range (0-15)"));
40721 + }
40722 +
40723 + }
40724 +
40725 + p_Manip->opcode = HMAN_OC;
40726 + p_Manip->muramAllocate = TRUE;
40727 + p_Manip->fieldUpdate = TRUE;
40728 + }
40729 + else
40730 + if (p_ManipParams->u.hdr.custom)
40731 + {
40732 + if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE)
40733 + {
40734 +
40735 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) ||
40736 + (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8))
40737 + RETURN_ERROR(
40738 + MAJOR, E_INVALID_VALUE,
40739 + ("size should get values of 1-8 "));
40740 +
40741 + if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7)
40742 + RETURN_ERROR(
40743 + MAJOR, E_INVALID_VALUE,
40744 + ("srcOffset should be <= 7"));
40745 +
40746 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset +
40747 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8)
40748 + RETURN_ERROR(
40749 + MAJOR, E_INVALID_VALUE,
40750 + ("(srcOffset + size) should be <= 8"));
40751 +
40752 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset +
40753 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256)
40754 + RETURN_ERROR(
40755 + MAJOR, E_INVALID_VALUE,
40756 + ("(dstOffset + size) should be <= 256"));
40757 +
40758 + }
40759 +
40760 + p_Manip->opcode = HMAN_OC;
40761 + p_Manip->muramAllocate = TRUE;
40762 + p_Manip->custom = TRUE;
40763 + }
40764 + break;
40765 + case e_FM_PCD_MANIP_REASSEM:
40766 + if (p_ManipParams->h_NextManip)
40767 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40768 + ("next manip with reassembly"));
40769 + switch (p_ManipParams->u.reassem.hdr)
40770 + {
40771 + case (HEADER_TYPE_IPv4):
40772 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4;
40773 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40774 + break;
40775 + case (HEADER_TYPE_IPv6):
40776 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6;
40777 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40778 + break;
40779 +#if (DPAA_VERSION >= 11)
40780 + case (HEADER_TYPE_CAPWAP):
40781 + p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP;
40782 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40783 + break;
40784 +#endif /* (DPAA_VERSION >= 11) */
40785 + default:
40786 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40787 + ("header for reassembly"));
40788 + }
40789 + break;
40790 + case e_FM_PCD_MANIP_FRAG:
40791 + if (p_ManipParams->h_NextManip)
40792 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40793 + ("next manip with fragmentation"));
40794 + switch (p_ManipParams->u.frag.hdr)
40795 + {
40796 + case (HEADER_TYPE_IPv4):
40797 + case (HEADER_TYPE_IPv6):
40798 + p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION;
40799 + break;
40800 +#if (DPAA_VERSION >= 11)
40801 + case (HEADER_TYPE_CAPWAP):
40802 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40803 + break;
40804 +#endif /* (DPAA_VERSION >= 11) */
40805 + default:
40806 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40807 + ("header for fragmentation"));
40808 + }
40809 + p_Manip->muramAllocate = TRUE;
40810 + break;
40811 + case e_FM_PCD_MANIP_SPECIAL_OFFLOAD:
40812 + switch (p_ManipParams->u.specialOffload.type)
40813 + {
40814 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC):
40815 + p_Manip->opcode = HMAN_OC_IPSEC_MANIP;
40816 + p_Manip->muramAllocate = TRUE;
40817 + break;
40818 +#if (DPAA_VERSION >= 11)
40819 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP):
40820 + p_Manip->opcode = HMAN_OC_CAPWAP_MANIP;
40821 + p_Manip->muramAllocate = TRUE;
40822 + break;
40823 +#endif /* (DPAA_VERSION >= 11) */
40824 + default:
40825 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40826 + ("special offload type"));
40827 + }
40828 + break;
40829 + default:
40830 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type"));
40831 + }
40832 +
40833 + return E_OK;
40834 +}
40835 +#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40836 +
40837 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40838 +
40839 +static t_Error UpdateIndxStats(t_Handle h_FmPcd,
40840 + t_Handle h_FmPort,
40841 + t_FmPcdManip *p_Manip)
40842 +{
40843 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40844 + uint32_t tmpReg32 = 0;
40845 + t_AdOfTypeContLookup *p_Ad;
40846 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40847 + t_Error err;
40848 +
40849 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
40850 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40851 +
40852 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40853 + if (p_Manip->h_FmPcd != h_FmPcd)
40854 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40855 + ("handler of PCD previously was initiated by different value"));
40856 +
40857 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
40858 +
40859 + if (!p_Manip->p_StatsTbl)
40860 + {
40861 +
40862 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40863 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40864 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40865 + if (err)
40866 + RETURN_ERROR(MAJOR, err, NO_MSG);
40867 +
40868 + tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
40869 +
40870 + p_Manip->p_StatsTbl =
40871 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40872 + (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
40873 + 4);
40874 + if (!p_Manip->p_StatsTbl)
40875 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table"));
40876 +
40877 + MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
40878 +
40879 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
40880 +
40881 + if (p_Manip->cnia)
40882 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
40883 +
40884 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
40885 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40886 + }
40887 + else
40888 + {
40889 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40890 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40891 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40892 + if (err)
40893 + RETURN_ERROR(MAJOR, err, NO_MSG);
40894 + }
40895 +
40896 + return E_OK;
40897 +}
40898 +
40899 +static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
40900 +{
40901 + t_AdOfTypeContLookup *p_Ad;
40902 + uint32_t tmpReg32 = 0;
40903 + uint8_t prsArrayOffset = 0;
40904 + t_Error err;
40905 +
40906 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
40907 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
40908 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40909 +
40910 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40911 + if (p_Manip->rmv)
40912 + {
40913 + err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset);
40914 + if (err)
40915 + RETURN_ERROR(MAJOR, err, NO_MSG);
40916 +
40917 + tmpReg32 |= (uint32_t)prsArrayOffset << 24;
40918 + tmpReg32 |= HMAN_RMV_HDR;
40919 + }
40920 +
40921 + if (p_Manip->insrt)
40922 + tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
40923 +
40924 + tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40925 +
40926 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40927 +
40928 + tmpReg32 = 0;
40929 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40930 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40931 +
40932 + return E_OK;
40933 +}
40934 +
40935 +static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip,
40936 + bool caamUsed)
40937 +{
40938 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40939 + uint32_t tmpReg32 = 0;
40940 +
40941 + SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE);
40942 +
40943 + p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
40944 +
40945 + tmpReg32 = 0;
40946 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40947 + *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
40948 +
40949 + tmpReg32 = 0;
40950 + tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
40951 + tmpReg32 |= (uint32_t)0x16 << 16;
40952 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
40953 +
40954 + if (caamUsed)
40955 + *(uint32_t *)&p_Ad->gmask = 0xf0000000;
40956 +
40957 + return E_OK;
40958 +}
40959 +
40960 +static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
40961 +{
40962 + t_AdOfTypeContLookup *p_Ad;
40963 + uint32_t tmpReg32 = 0;
40964 + t_Error err = E_OK;
40965 +
40966 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40967 +
40968 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40969 +
40970 + tmpReg32 = 0;
40971 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40972 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40973 +
40974 + tmpReg32 = 0;
40975 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40976 +
40977 +
40978 + if (p_Manip->h_Frag)
40979 + {
40980 + p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
40981 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
40982 + }
40983 +
40984 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40985 +
40986 + return err;
40987 +}
40988 +
40989 +static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,
40990 + t_FmPcdManip *p_Manip,
40991 + t_FmPcd *p_FmPcd,
40992 + uint8_t poolId)
40993 +{
40994 + t_Handle p_Table;
40995 + uint32_t tmpReg32 = 0;
40996 + int i = 0;
40997 + uint8_t log2Num;
40998 + uint8_t numOfSets;
40999 + uint32_t j = 0;
41000 + uint32_t bitFor1Micro;
41001 +
41002 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
41003 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
41004 +
41005 + if (!p_FmPcd->h_Hc)
41006 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
41007 + if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
41008 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
41009 + if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
41010 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
41011 + if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
41012 + DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly"));
41013 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
41014 + {
41015 + if ((p_ManipParams->maxNumFramesInProcess < 4) ||
41016 + (p_ManipParams->maxNumFramesInProcess > 512))
41017 + 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"));
41018 + }
41019 + else
41020 + {
41021 + if ((p_ManipParams->maxNumFramesInProcess < 8) ||
41022 + (p_ManipParams->maxNumFramesInProcess > 2048))
41023 + 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"));
41024 + }
41025 +
41026 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
41027 + if (bitFor1Micro == 0)
41028 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
41029 +
41030 + p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
41031 +
41032 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41033 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
41034 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
41035 + if (!p_Manip->h_Frag)
41036 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table"));
41037 +
41038 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
41039 +
41040 + p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
41041 +
41042 + p_Manip->capwapFragParams.p_AutoLearnHashTbl =
41043 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41044 + (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
41045 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
41046 +
41047 + if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl)
41048 + RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table"));
41049 +
41050 + MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
41051 +
41052 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
41053 +
41054 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
41055 +
41056 + tmpReg32 = 0;
41057 + if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
41058 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
41059 + if (p_ManipParams->haltOnDuplicationFrag)
41060 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
41061 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
41062 + {
41063 + i = 8;
41064 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
41065 + }
41066 + else
41067 + i = 4;
41068 +
41069 + numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
41070 + LOG2(numOfSets, log2Num);
41071 + tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
41072 +
41073 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
41074 +
41075 + for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++)
41076 + if (((j / i) % 2)== 0)
41077 + WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
41078 +
41079 + tmpReg32 = 0x00008000;
41080 + tmpReg32 |= (uint32_t)poolId << 16;
41081 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
41082 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
41083 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
41084 +
41085 + p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
41086 +
41087 + p_Manip->capwapFragParams.sgBpid = poolId;
41088 +
41089 + p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
41090 + p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
41091 + p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro;
41092 +
41093 + tmpReg32 = 0;
41094 + tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
41095 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
41096 +
41097 + return E_OK;
41098 +}
41099 +
41100 +static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,
41101 + t_FmPcdManip *p_Manip,
41102 + t_FmPcd *p_FmPcd,
41103 + uint8_t poolId)
41104 +{
41105 + t_AdOfTypeContLookup *p_Ad;
41106 + uint32_t tmpReg32 = 0;
41107 +
41108 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
41109 +
41110 + p_Manip->updateParams |= OFFSET_OF_DATA;
41111 +
41112 + p_Manip->frag = TRUE;
41113 +
41114 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41115 + FM_PCD_CC_AD_ENTRY_SIZE,
41116 + FM_PCD_CC_AD_TABLE_ALIGN);
41117 + if (!p_Manip->h_Frag)
41118 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor"));
41119 +
41120 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41121 +
41122 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
41123 +
41124 + tmpReg32 = 0;
41125 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
41126 +
41127 + if (p_ManipParams->headerOptionsCompr)
41128 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
41129 + tmpReg32 |= ((uint32_t)poolId << 8);
41130 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41131 +
41132 + tmpReg32 = 0;
41133 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41134 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41135 +
41136 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
41137 + p_Manip->capwapFragParams.sgBpid = poolId;
41138 +
41139 + return E_OK;
41140 +}
41141 +
41142 +static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
41143 +{
41144 + t_AdOfTypeContLookup *p_Ad;
41145 + uint32_t tmpReg32 = 0;
41146 +
41147 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
41148 +
41149 + UNUSED(p_FmPcd);
41150 +
41151 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41152 +
41153 + tmpReg32 = 0;
41154 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
41155 + if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
41156 + tmpReg32 |= (uint32_t)0x16 << 16;
41157 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41158 +
41159 + tmpReg32 = 0;
41160 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41161 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41162 +
41163 + return E_OK;
41164 +}
41165 +
41166 +static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
41167 +{
41168 + t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate;
41169 + uint8_t tmpReg8 = 0xff;
41170 + t_AdOfTypeContLookup *p_Ad;
41171 + bool ipModify = FALSE;
41172 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41173 + uint16_t tmpReg16 = 0;
41174 + t_Error err = E_OK;
41175 + uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0;
41176 + uint8_t *p_Template = NULL;
41177 +
41178 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
41179 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
41180 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
41181 + SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
41182 +
41183 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41184 + if (p_Manip->insrt)
41185 + {
41186 + if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
41187 + (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
41188 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
41189 +
41190 + if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
41191 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
41192 +
41193 + if (p_InsrtByTemplate->size > 128)
41194 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
41195 +
41196 + if (p_InsrtByTemplate->size)
41197 + {
41198 + p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41199 + p_InsrtByTemplate->size,
41200 + FM_PCD_CC_AD_TABLE_ALIGN);
41201 + if(!p_Manip->p_Template)
41202 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
41203 +
41204 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
41205 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
41206 + *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
41207 + }
41208 +
41209 + tmpReg32 = 0;
41210 +
41211 + p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
41212 +
41213 + if (!p_Template)
41214 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
41215 +
41216 + memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
41217 +
41218 + if (p_InsrtByTemplate->modifyOuterIp)
41219 + {
41220 + ipModify = TRUE;
41221 +
41222 + tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
41223 +
41224 + if((tmpReg8 & 0xf0) == 0x40)
41225 + tmpReg8 = 4;
41226 + else if((tmpReg8 & 0xf0) == 0x60)
41227 + tmpReg8 = 6;
41228 + else
41229 + tmpReg8 = 0xff;
41230 +
41231 + if (tmpReg8 != 0xff)
41232 + {
41233 + if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
41234 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
41235 + if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
41236 + {
41237 +
41238 + if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
41239 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
41240 + extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
41241 + blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
41242 + extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
41243 + /*IP header template - IP totalLength -
41244 + (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
41245 + in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
41246 + second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
41247 + }
41248 + if (blockSize)
41249 + {
41250 + if (!POWER_OF_2(blockSize))
41251 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
41252 + }
41253 +
41254 + }
41255 + if (tmpReg8 == 4)
41256 + {
41257 + if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
41258 + 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"));
41259 +
41260 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
41261 +
41262 + if (blockSize)
41263 + blockSize -= 1;
41264 +
41265 + if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
41266 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
41267 +
41268 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND
41269 + 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
41270 +
41271 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00;
41272 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
41273 +
41274 + /*IP header template - relevant only for ipv4 CheckSum = 0*/
41275 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
41276 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
41277 +
41278 + /*UDP checksum has to be 0*/
41279 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
41280 + {
41281 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
41282 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
41283 +
41284 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
41285 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
41286 +
41287 + }
41288 +
41289 + if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
41290 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
41291 +
41292 + tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
41293 + }
41294 + else if (tmpReg8 == 6)
41295 + {
41296 + /*TODO - add check for maximum value of blockSize;*/
41297 + if (blockSize)
41298 + LOG2(blockSize, log2Num);
41299 + tmpRegNia |= (uint32_t)log2Num << 24;
41300 +
41301 + // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength
41302 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40);
41303 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
41304 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
41305 + {
41306 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
41307 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
41308 + if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88)
41309 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite"));
41310 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00;
41311 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08;
41312 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00;
41313 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
41314 + }
41315 + }
41316 + else
41317 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
41318 + }
41319 +
41320 + tmpReg32 = tmpReg16 = tmpReg8 = 0;
41321 + /*TODO - check it*/
41322 + if (p_InsrtByTemplate->modifyOuterVlan)
41323 + {
41324 + if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
41325 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
41326 +
41327 + memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
41328 + if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
41329 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
41330 +
41331 + memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
41332 + tmpReg8 &= 0x1f;
41333 + tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
41334 +
41335 + p_Template[14] = tmpReg8;
41336 + }
41337 +
41338 + MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
41339 +
41340 + XX_Free(p_Template);
41341 + }
41342 +
41343 + tmpReg32 = 0;
41344 + if (p_Manip->h_Frag)
41345 + {
41346 + tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
41347 + tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
41348 + }
41349 + else
41350 + tmpReg32 = 0xffff0000;
41351 +
41352 + if (ipModify)
41353 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
41354 + else
41355 + tmpReg32 |= (uint32_t)0x0000ff00;
41356 +
41357 + tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
41358 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
41359 +
41360 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41361 + *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
41362 +
41363 + return err;
41364 +}
41365 +
41366 +static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
41367 +{
41368 +
41369 + switch (p_StatsParams->type)
41370 + {
41371 + case (e_FM_PCD_STATS_PER_FLOWID):
41372 + p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS;
41373 + p_Manip->muramAllocate = TRUE;
41374 + break;
41375 + default:
41376 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
41377 + }
41378 +
41379 + return E_OK;
41380 +}
41381 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
41382 +
41383 +static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
41384 +{
41385 + t_AdOfTypeContLookup *p_Ad;
41386 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41387 + uint32_t tmpReg32;
41388 + t_Error err = E_OK;
41389 +
41390 + /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly
41391 + function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then
41392 + two separate IP Reassembly Parameter tables are required.*/
41393 + if ((err = CreateReassTable(p_Manip, hdr)) != E_OK)
41394 + RETURN_ERROR(MAJOR, err, NO_MSG);
41395 +
41396 + /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/
41397 + tmpReg32 = 0;
41398 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41399 +
41400 + /* Gets the required Action descriptor table pointer */
41401 + switch (hdr)
41402 + {
41403 + case HEADER_TYPE_IPv4:
41404 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad;
41405 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41406 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41407 + - (p_FmPcd->physicalMuramBase));
41408 + break;
41409 + case HEADER_TYPE_IPv6:
41410 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad;
41411 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41412 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41413 + - (p_FmPcd->physicalMuramBase));
41414 + break;
41415 + case HEADER_TYPE_CAPWAP:
41416 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad;
41417 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41418 + p_Manip->reassmParams.capwap.p_ReassTbl)
41419 + - (p_FmPcd->physicalMuramBase));
41420 + break;
41421 + default:
41422 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
41423 + }
41424 +
41425 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41426 +
41427 + /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/
41428 + /* mark the Scatter/Gather table offset to be set later on when the port will be known */
41429 + p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK);
41430 +
41431 + if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4))
41432 + {
41433 +#if (DPAA_VERSION == 10)
41434 + tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8);
41435 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41436 +#endif /* (DPAA_VERSION == 10) */
41437 +#if (DPAA_VERSION >= 11)
41438 + if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0)
41439 + {
41440 + tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK
41441 + | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid);
41442 + WRITE_UINT32(p_Ad->gmask, tmpReg32);
41443 + }
41444 +#endif /* (DPAA_VERSION >= 11) */
41445 + /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/
41446 + tmpReg32 = 0;
41447 + tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
41448 + }
41449 +#if (DPAA_VERSION >= 11)
41450 + else
41451 + if (hdr == HEADER_TYPE_CAPWAP)
41452 + {
41453 + tmpReg32 = 0;
41454 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY;
41455 + }
41456 +#endif /* (DPAA_VERSION >= 11) */
41457 +
41458 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41459 +
41460 + p_Manip->reassm = TRUE;
41461 +
41462 + return E_OK;
41463 +}
41464 +
41465 +static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
41466 +{
41467 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41468 +
41469 + /* Allocation if IPv4 Action descriptor */
41470 + p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart(
41471 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41472 + FM_PCD_CC_AD_TABLE_ALIGN);
41473 + if (!p_Manip->reassmParams.ip.h_Ipv4Ad)
41474 + {
41475 + ReleaseManipHandler(p_Manip, p_FmPcd);
41476 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41477 + ("Allocation of IPv4 table descriptor"));
41478 + }
41479 +
41480 + memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41481 +
41482 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41483 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4);
41484 +}
41485 +
41486 +static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
41487 +{
41488 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41489 +
41490 + /* Allocation if IPv6 Action descriptor */
41491 + p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart(
41492 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41493 + FM_PCD_CC_AD_TABLE_ALIGN);
41494 + if (!p_Manip->reassmParams.ip.h_Ipv6Ad)
41495 + {
41496 + ReleaseManipHandler(p_Manip, p_FmPcd);
41497 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41498 + ("Allocation of IPv6 table descriptor"));
41499 + }
41500 +
41501 + memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41502 +
41503 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41504 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6);
41505 +}
41506 +
41507 +static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
41508 + t_FmPcdManip *p_Manip)
41509 +{
41510 + uint32_t maxSetNumber = 10000;
41511 + t_FmPcdManipReassemIpParams reassmManipParams =
41512 + p_ManipReassmParams->u.ipReassem;
41513 + t_Error res;
41514 +
41515 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
41516 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
41517 + E_INVALID_HANDLE);
41518 +
41519 + /* Check validation of user's parameter.*/
41520 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
41521 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
41522 + RETURN_ERROR(
41523 + MAJOR, E_INVALID_VALUE,
41524 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
41525 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
41526 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
41527 + if (reassmManipParams.maxNumFramesInProcess
41528 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
41529 + RETURN_ERROR(
41530 + MAJOR,
41531 + E_INVALID_VALUE,
41532 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
41533 +
41534 + if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6)
41535 + && (reassmManipParams.minFragSize[1] < 256))
41536 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256"));
41537 +
41538 + /* Saves user's reassembly manipulation parameters */
41539 + p_Manip->reassmParams.ip.relativeSchemeId[0] =
41540 + reassmManipParams.relativeSchemeId[0];
41541 + p_Manip->reassmParams.ip.relativeSchemeId[1] =
41542 + reassmManipParams.relativeSchemeId[1];
41543 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] =
41544 + reassmManipParams.numOfFramesPerHashEntry[0];
41545 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] =
41546 + reassmManipParams.numOfFramesPerHashEntry[1];
41547 + p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0];
41548 + p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1];
41549 + p_Manip->reassmParams.maxNumFramesInProcess =
41550 + reassmManipParams.maxNumFramesInProcess;
41551 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
41552 + p_Manip->reassmParams.fqidForTimeOutFrames =
41553 + reassmManipParams.fqidForTimeOutFrames;
41554 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
41555 + reassmManipParams.timeoutThresholdForReassmProcess;
41556 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
41557 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
41558 +#if (DPAA_VERSION == 10)
41559 + p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid;
41560 +#endif /* (DPAA_VERSION == 10) */
41561 +#if (DPAA_VERSION >= 11)
41562 + if (reassmManipParams.nonConsistentSpFqid != 0)
41563 + {
41564 + p_Manip->reassmParams.ip.nonConsistentSpFqid =
41565 + reassmManipParams.nonConsistentSpFqid;
41566 + }
41567 +#endif /* (DPAA_VERSION >= 11) */
41568 +
41569 + /* Creates and initializes the IP Reassembly common parameter table */
41570 + CreateReassCommonTable(p_Manip);
41571 +
41572 + /* Creation of IPv4 reassembly manipulation */
41573 + if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41574 + || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4))
41575 + {
41576 + res = SetIpv4ReassmManip(p_Manip);
41577 + if (res != E_OK)
41578 + return res;
41579 + }
41580 +
41581 + /* Creation of IPv6 reassembly manipulation */
41582 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41583 + {
41584 + res = SetIpv6ReassmManip(p_Manip);
41585 + if (res != E_OK)
41586 + return res;
41587 + }
41588 +
41589 + return E_OK;
41590 +}
41591 +
41592 +static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd,
41593 + t_FmPcdKgSchemeParams *p_Scheme,
41594 + t_Handle h_CcTree, bool ipv4,
41595 + uint8_t groupId)
41596 +{
41597 + uint32_t j;
41598 + uint8_t res;
41599 +
41600 + /* Configures scheme's network environment parameters */
41601 + p_Scheme->netEnvParams.numOfDistinctionUnits = 2;
41602 + if (ipv4)
41603 + res = FmPcdNetEnvGetUnitId(
41604 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41605 + HEADER_TYPE_IPv4, FALSE, 0);
41606 + else
41607 + res = FmPcdNetEnvGetUnitId(
41608 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41609 + HEADER_TYPE_IPv6, FALSE, 0);
41610 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41611 + p_Scheme->netEnvParams.unitIds[0] = res;
41612 +
41613 + res = FmPcdNetEnvGetUnitId(
41614 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41615 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
41616 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41617 + p_Scheme->netEnvParams.unitIds[1] = res;
41618 +
41619 + /* Configures scheme's next engine parameters*/
41620 + p_Scheme->nextEngine = e_FM_PCD_CC;
41621 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
41622 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
41623 + p_Scheme->useHash = TRUE;
41624 +
41625 + /* Configures scheme's key*/
41626 + if (ipv4 == TRUE)
41627 + {
41628 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4;
41629 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41630 + e_FM_PCD_EXTRACT_BY_HDR;
41631 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41632 + e_FM_PCD_EXTRACT_FULL_FIELD;
41633 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41634 + HEADER_TYPE_IPv4;
41635 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 =
41636 + NET_HEADER_FIELD_IPv4_DST_IP;
41637 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41638 + e_FM_PCD_EXTRACT_BY_HDR;
41639 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41640 + e_FM_PCD_EXTRACT_FULL_FIELD;
41641 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41642 + HEADER_TYPE_IPv4;
41643 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 =
41644 + NET_HEADER_FIELD_IPv4_SRC_IP;
41645 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41646 + e_FM_PCD_EXTRACT_BY_HDR;
41647 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41648 + e_FM_PCD_EXTRACT_FULL_FIELD;
41649 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41650 + HEADER_TYPE_IPv4;
41651 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 =
41652 + NET_HEADER_FIELD_IPv4_PROTO;
41653 + p_Scheme->keyExtractAndHashParams.extractArray[3].type =
41654 + e_FM_PCD_EXTRACT_BY_HDR;
41655 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr =
41656 + HEADER_TYPE_IPv4;
41657 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type =
41658 + e_FM_PCD_EXTRACT_FROM_HDR;
41659 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation =
41660 + FALSE;
41661 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size =
41662 + 2;
41663 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset =
41664 + 4;
41665 + }
41666 + else /* IPv6 */
41667 + {
41668 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3;
41669 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41670 + e_FM_PCD_EXTRACT_BY_HDR;
41671 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41672 + e_FM_PCD_EXTRACT_FULL_FIELD;
41673 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41674 + HEADER_TYPE_IPv6;
41675 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 =
41676 + NET_HEADER_FIELD_IPv6_DST_IP;
41677 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41678 + e_FM_PCD_EXTRACT_BY_HDR;
41679 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41680 + e_FM_PCD_EXTRACT_FULL_FIELD;
41681 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41682 + HEADER_TYPE_IPv6;
41683 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 =
41684 + NET_HEADER_FIELD_IPv6_SRC_IP;
41685 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41686 + e_FM_PCD_EXTRACT_BY_HDR;
41687 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41688 + HEADER_TYPE_USER_DEFINED_SHIM2;
41689 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41690 + e_FM_PCD_EXTRACT_FROM_HDR;
41691 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size =
41692 + 4;
41693 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset =
41694 + 4;
41695 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation =
41696 + TRUE;
41697 + }
41698 +
41699 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304;
41700 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314;
41701 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts =
41702 + FM_PCD_KG_NUM_OF_DEFAULT_GROUPS;
41703 + for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++)
41704 + {
41705 + p_Scheme->keyExtractAndHashParams.dflts[j].type =
41706 + (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */
41707 + p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect =
41708 + e_FM_PCD_KG_DFLT_GBL_0;
41709 + }
41710 +}
41711 +
41712 +static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip,
41713 + t_FmPcdManipReassemIpStats *p_Stats)
41714 +{
41715 + ASSERT_COND(p_Manip);
41716 + ASSERT_COND(p_Stats);
41717 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
41718 +
41719 + p_Stats->timeout =
41720 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
41721 + p_Stats->rfdPoolBusy =
41722 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
41723 + p_Stats->internalBufferBusy =
41724 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
41725 + p_Stats->externalBufferBusy =
41726 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
41727 + p_Stats->sgFragments =
41728 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
41729 + p_Stats->dmaSemaphoreDepletion =
41730 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
41731 +#if (DPAA_VERSION >= 11)
41732 + p_Stats->nonConsistentSp =
41733 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
41734 +#endif /* (DPAA_VERSION >= 11) */
41735 +
41736 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41737 + {
41738 + p_Stats->specificHdrStatistics[0].successfullyReassembled =
41739 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter);
41740 + p_Stats->specificHdrStatistics[0].validFragments =
41741 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter);
41742 + p_Stats->specificHdrStatistics[0].processedFragments =
41743 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter);
41744 + p_Stats->specificHdrStatistics[0].malformedFragments =
41745 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter);
41746 + p_Stats->specificHdrStatistics[0].autoLearnBusy =
41747 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter);
41748 + p_Stats->specificHdrStatistics[0].discardedFragments =
41749 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter);
41750 + p_Stats->specificHdrStatistics[0].moreThan16Fragments =
41751 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter);
41752 + }
41753 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41754 + {
41755 + p_Stats->specificHdrStatistics[1].successfullyReassembled =
41756 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter);
41757 + p_Stats->specificHdrStatistics[1].validFragments =
41758 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter);
41759 + p_Stats->specificHdrStatistics[1].processedFragments =
41760 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter);
41761 + p_Stats->specificHdrStatistics[1].malformedFragments =
41762 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter);
41763 + p_Stats->specificHdrStatistics[1].autoLearnBusy =
41764 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter);
41765 + p_Stats->specificHdrStatistics[1].discardedFragments =
41766 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter);
41767 + p_Stats->specificHdrStatistics[1].moreThan16Fragments =
41768 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter);
41769 + }
41770 + return E_OK;
41771 +}
41772 +
41773 +static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip,
41774 + t_FmPcdManipFragIpStats *p_Stats)
41775 +{
41776 + t_AdOfTypeContLookup *p_Ad;
41777 +
41778 + ASSERT_COND(p_Manip);
41779 + ASSERT_COND(p_Stats);
41780 + ASSERT_COND(p_Manip->h_Ad);
41781 + ASSERT_COND(p_Manip->fragParams.p_Frag);
41782 +
41783 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41784 +
41785 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
41786 + p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase)
41787 + & 0x00ffffff;
41788 + p_Stats->generatedFragments =
41789 + GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr);
41790 +
41791 + return E_OK;
41792 +}
41793 +
41794 +static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams,
41795 + t_FmPcdManip *p_Manip)
41796 +{
41797 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
41798 + t_FmPcd *p_FmPcd;
41799 +#if (DPAA_VERSION == 10)
41800 + t_Error err = E_OK;
41801 +#endif /* (DPAA_VERSION == 10) */
41802 +
41803 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
41804 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
41805 + E_INVALID_VALUE);
41806 +
41807 + p_FmPcd = p_Manip->h_FmPcd;
41808 + /* Allocation of fragmentation Action Descriptor */
41809 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
41810 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
41811 + FM_PCD_CC_AD_TABLE_ALIGN);
41812 + if (!p_Manip->fragParams.p_Frag)
41813 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41814 + ("MURAM alloc for Fragmentation table descriptor"));
41815 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41816 +
41817 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
41818 + pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION;
41819 +
41820 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
41821 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
41822 + ccAdBaseReg |= (p_ManipParams->dontFragAction
41823 + << FM_PCD_MANIP_IP_FRAG_DF_SHIFT);
41824 +
41825 +
41826 + /* Set Scatter/Gather BPid */
41827 + if (p_ManipParams->sgBpidEn)
41828 + {
41829 + ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN;
41830 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
41831 + << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT)
41832 + & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK);
41833 + }
41834 +
41835 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
41836 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr))
41837 + - p_FmPcd->physicalMuramBase);
41838 +#if (DPAA_VERSION == 10)
41839 + gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41840 +#else
41841 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41842 +#endif /* (DPAA_VERSION == 10) */
41843 +
41844 + /* Set all Ad registers */
41845 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
41846 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
41847 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
41848 +
41849 + /* Saves user's fragmentation manipulation parameters */
41850 + p_Manip->frag = TRUE;
41851 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
41852 +
41853 +#if (DPAA_VERSION == 10)
41854 + p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid;
41855 +
41856 + /* scratch buffer pool initialization */
41857 + if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK)
41858 + {
41859 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
41860 + p_Manip->fragParams.p_Frag = NULL;
41861 + RETURN_ERROR(MAJOR, err, NO_MSG);
41862 + }
41863 +#endif /* (DPAA_VERSION == 10) */
41864 +
41865 + return E_OK;
41866 +}
41867 +
41868 +static t_Error IPManip(t_FmPcdManip *p_Manip)
41869 +{
41870 + t_Error err = E_OK;
41871 + t_FmPcd *p_FmPcd;
41872 + t_AdOfTypeContLookup *p_Ad;
41873 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41874 +
41875 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41876 + p_FmPcd = p_Manip->h_FmPcd;
41877 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41878 +
41879 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41880 +
41881 + tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION;
41882 + if (p_Manip->frag == TRUE)
41883 + {
41884 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
41885 + - (p_FmPcd->physicalMuramBase));
41886 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
41887 + << FM_PCD_MANIP_IP_MTU_SHIFT;
41888 + }
41889 +
41890 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41891 + tmpReg32 |= HMAN_OC_IP_MANIP;
41892 +
41893 +#if (DPAA_VERSION >= 11)
41894 + tmpRegNia |= FM_PCD_MANIP_IP_CNIA;
41895 +#endif /* (DPAA_VERSION >= 11) */
41896 +
41897 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41898 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
41899 + WRITE_UINT32(p_Ad->gmask, 0);
41900 + /* Total frame counter - MUST be initialized to zero.*/
41901 +
41902 + return err;
41903 +}
41904 +
41905 +static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
41906 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
41907 + t_Handle h_Ad, bool validate)
41908 +{
41909 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41910 + t_Error err;
41911 +
41912 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41913 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION),
41914 + E_INVALID_STATE);
41915 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
41916 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
41917 +
41918 + UNUSED(h_FmPcd);
41919 + UNUSED(h_Ad);
41920 + UNUSED(h_PcdParams);
41921 + UNUSED(validate);
41922 + UNUSED(p_Manip);
41923 +
41924 + fmPortGetSetCcParams.setCcParams.type = 0;
41925 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
41926 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
41927 + RETURN_ERROR(MAJOR, err, NO_MSG);
41928 +
41929 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
41930 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
41931 +
41932 + return E_OK;
41933 +}
41934 +
41935 +static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams,
41936 + t_FmPcdManip *p_Manip)
41937 +{
41938 + t_AdOfTypeContLookup *p_Ad;
41939 + t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams;
41940 + t_Error err = E_OK;
41941 + uint32_t tmpReg32 = 0;
41942 + uint32_t power;
41943 +
41944 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41945 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
41946 +
41947 + p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec;
41948 +
41949 + SANITY_CHECK_RETURN_ERROR(
41950 + !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption,
41951 + E_INVALID_VALUE);
41952 + SANITY_CHECK_RETURN_ERROR(
41953 + !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption,
41954 + E_INVALID_VALUE);
41955 + SANITY_CHECK_RETURN_ERROR(
41956 + !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen,
41957 + E_INVALID_VALUE);
41958 + SANITY_CHECK_RETURN_ERROR(
41959 + !p_IPSecParams->arwSize || p_IPSecParams->arwAddr,
41960 + E_INVALID_VALUE);
41961 + SANITY_CHECK_RETURN_ERROR(
41962 + !p_IPSecParams->arwSize || p_IPSecParams->decryption,
41963 + E_INVALID_VALUE);
41964 + SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE);
41965 +
41966 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41967 +
41968 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41969 + tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0;
41970 + tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0;
41971 + tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0;
41972 + tmpReg32 |=
41973 + (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0;
41974 + tmpReg32 |=
41975 + (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0;
41976 + if (p_IPSecParams->arwSize)
41977 + tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM)
41978 + & (FM_MURAM_SIZE-1));
41979 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41980 +
41981 + tmpReg32 = 0;
41982 + if (p_IPSecParams->arwSize) {
41983 + NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power);
41984 + LOG2(power, power);
41985 + tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT;
41986 + }
41987 +
41988 + if (p_ManipParams->h_NextManip)
41989 + tmpReg32 |=
41990 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)-
41991 + (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4;
41992 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41993 +
41994 + tmpReg32 = HMAN_OC_IPSEC_MANIP;
41995 + tmpReg32 |= p_IPSecParams->outerIPHdrLen
41996 + << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT;
41997 + if (p_ManipParams->h_NextManip)
41998 + tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN;
41999 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42000 +
42001 + return err;
42002 +}
42003 +
42004 +static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip)
42005 +{
42006 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
42007 +
42008 + /* Allocation if CAPWAP Action descriptor */
42009 + p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart(
42010 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
42011 + FM_PCD_CC_AD_TABLE_ALIGN);
42012 + if (!p_Manip->reassmParams.capwap.h_Ad)
42013 + {
42014 + ReleaseManipHandler(p_Manip, p_FmPcd);
42015 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42016 + ("Allocation of CAPWAP table descriptor"));
42017 + }
42018 +
42019 + memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42020 +
42021 + /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */
42022 + return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP);
42023 +}
42024 +
42025 +static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd,
42026 + t_FmPcdKgSchemeParams *p_Scheme,
42027 + t_Handle h_CcTree, uint8_t groupId)
42028 +{
42029 + uint8_t res;
42030 +
42031 + /* Configures scheme's network environment parameters */
42032 + p_Scheme->netEnvParams.numOfDistinctionUnits = 1;
42033 + res = FmPcdNetEnvGetUnitId(
42034 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
42035 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
42036 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
42037 + p_Scheme->netEnvParams.unitIds[0] = res;
42038 +
42039 + /* Configures scheme's next engine parameters*/
42040 + p_Scheme->nextEngine = e_FM_PCD_CC;
42041 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
42042 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
42043 + p_Scheme->useHash = TRUE;
42044 +
42045 + /* Configures scheme's key*/
42046 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2;
42047 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
42048 + e_FM_PCD_EXTRACT_NON_HDR;
42049 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src =
42050 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT;
42051 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action =
42052 + e_FM_PCD_ACTION_NONE;
42053 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20;
42054 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4;
42055 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
42056 + e_FM_PCD_EXTRACT_NON_HDR;
42057 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src =
42058 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE;
42059 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action =
42060 + e_FM_PCD_ACTION_NONE;
42061 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0;
42062 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1;
42063 +
42064 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0;
42065 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0;
42066 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1;
42067 + p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
42068 + p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0;
42069 +}
42070 +
42071 +#if (DPAA_VERSION >= 11)
42072 +static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip,
42073 + t_FmPcdManipReassemCapwapStats *p_Stats)
42074 +{
42075 + ASSERT_COND(p_Manip);
42076 + ASSERT_COND(p_Stats);
42077 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
42078 +
42079 + p_Stats->timeout =
42080 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
42081 + p_Stats->rfdPoolBusy =
42082 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
42083 + p_Stats->internalBufferBusy =
42084 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
42085 + p_Stats->externalBufferBusy =
42086 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
42087 + p_Stats->sgFragments =
42088 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
42089 + p_Stats->dmaSemaphoreDepletion =
42090 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
42091 + p_Stats->exceedMaxReassemblyFrameLen =
42092 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
42093 +
42094 + p_Stats->successfullyReassembled =
42095 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter);
42096 + p_Stats->validFragments =
42097 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter);
42098 + p_Stats->processedFragments =
42099 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter);
42100 + p_Stats->malformedFragments =
42101 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter);
42102 + p_Stats->autoLearnBusy =
42103 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter);
42104 + p_Stats->discardedFragments =
42105 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter);
42106 + p_Stats->moreThan16Fragments =
42107 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter);
42108 +
42109 + return E_OK;
42110 +}
42111 +
42112 +static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip,
42113 + t_FmPcdManipFragCapwapStats *p_Stats)
42114 +{
42115 + t_AdOfTypeContLookup *p_Ad;
42116 +
42117 + ASSERT_COND(p_Manip);
42118 + ASSERT_COND(p_Stats);
42119 + ASSERT_COND(p_Manip->h_Ad);
42120 + ASSERT_COND(p_Manip->fragParams.p_Frag);
42121 +
42122 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42123 +
42124 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
42125 +
42126 + return E_OK;
42127 +}
42128 +
42129 +static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
42130 + t_FmPcdManip *p_Manip)
42131 +{
42132 + uint32_t maxSetNumber = 10000;
42133 + t_FmPcdManipReassemCapwapParams reassmManipParams =
42134 + p_ManipReassmParams->u.capwapReassem;
42135 + t_Error res;
42136 +
42137 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
42138 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
42139 + E_INVALID_HANDLE);
42140 +
42141 + /* Check validation of user's parameter.*/
42142 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
42143 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
42144 + RETURN_ERROR(
42145 + MAJOR, E_INVALID_VALUE,
42146 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
42147 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
42148 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
42149 + if (reassmManipParams.maxNumFramesInProcess
42150 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
42151 + RETURN_ERROR(
42152 + MAJOR,
42153 + E_INVALID_VALUE,
42154 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
42155 +
42156 + /* Saves user's reassembly manipulation parameters */
42157 + p_Manip->reassmParams.capwap.relativeSchemeId =
42158 + reassmManipParams.relativeSchemeId;
42159 + p_Manip->reassmParams.capwap.numOfFramesPerHashEntry =
42160 + reassmManipParams.numOfFramesPerHashEntry;
42161 + p_Manip->reassmParams.capwap.maxRessembledsSize =
42162 + reassmManipParams.maxReassembledFrameLength;
42163 + p_Manip->reassmParams.maxNumFramesInProcess =
42164 + reassmManipParams.maxNumFramesInProcess;
42165 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
42166 + p_Manip->reassmParams.fqidForTimeOutFrames =
42167 + reassmManipParams.fqidForTimeOutFrames;
42168 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
42169 + reassmManipParams.timeoutThresholdForReassmProcess;
42170 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
42171 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
42172 +
42173 + /* Creates and initializes the Reassembly common parameter table */
42174 + CreateReassCommonTable(p_Manip);
42175 +
42176 + res = SetCapwapReassmManip(p_Manip);
42177 + if (res != E_OK)
42178 + return res;
42179 +
42180 + return E_OK;
42181 +}
42182 +
42183 +static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams,
42184 + t_FmPcdManip *p_Manip)
42185 +{
42186 + t_FmPcd *p_FmPcd;
42187 + t_AdOfTypeContLookup *p_Ad;
42188 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
42189 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
42190 +
42191 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
42192 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
42193 + E_INVALID_VALUE);
42194 + p_FmPcd = p_Manip->h_FmPcd;
42195 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
42196 +
42197 + /* Allocation of fragmentation Action Descriptor */
42198 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
42199 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
42200 + FM_PCD_CC_AD_TABLE_ALIGN);
42201 + if (!p_Manip->fragParams.p_Frag)
42202 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42203 + ("MURAM alloc for Fragmentation table descriptor"));
42204 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42205 +
42206 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
42207 + pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
42208 +
42209 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
42210 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
42211 + ccAdBaseReg |=
42212 + (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN :
42213 + 0;
42214 +
42215 + /* Set Scatter/Gather BPid */
42216 + if (p_ManipParams->sgBpidEn)
42217 + {
42218 + ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN;
42219 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
42220 + << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT)
42221 + & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK);
42222 + }
42223 +
42224 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
42225 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr))
42226 + - p_FmPcd->physicalMuramBase);
42227 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
42228 +
42229 + /* Set all Ad registers */
42230 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
42231 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
42232 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
42233 +
42234 + /* Saves user's fragmentation manipulation parameters */
42235 + p_Manip->frag = TRUE;
42236 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
42237 +
42238 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42239 +
42240 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
42241 + - (p_FmPcd->physicalMuramBase));
42242 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
42243 + << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT;
42244 +
42245 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42246 + tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK;
42247 +
42248 + tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA;
42249 +
42250 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42251 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
42252 + WRITE_UINT32(p_Ad->gmask, 0);
42253 + /* Total frame counter - MUST be initialized to zero.*/
42254 +
42255 + return E_OK;
42256 +}
42257 +
42258 +static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
42259 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
42260 + t_Handle h_Ad, bool validate)
42261 +{
42262 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
42263 + t_Error err;
42264 +
42265 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
42266 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION),
42267 + E_INVALID_STATE);
42268 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
42269 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
42270 +
42271 + UNUSED(h_FmPcd);
42272 + UNUSED(h_Ad);
42273 + UNUSED(h_PcdParams);
42274 + UNUSED(validate);
42275 + UNUSED(p_Manip);
42276 +
42277 + fmPortGetSetCcParams.setCcParams.type = 0;
42278 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
42279 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
42280 + RETURN_ERROR(MAJOR, err, NO_MSG);
42281 +
42282 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
42283 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
42284 +
42285 + return E_OK;
42286 +}
42287 +
42288 +static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams,
42289 + t_FmPcdManip *p_Manip)
42290 +{
42291 + t_AdOfTypeContLookup *p_Ad;
42292 + t_FmPcdManipSpecialOffloadCapwapParams *p_Params;
42293 + t_Error err = E_OK;
42294 + uint32_t tmpReg32 = 0;
42295 +
42296 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
42297 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
42298 +
42299 + p_Params = &p_ManipParams->u.specialOffload.u.capwap;
42300 +
42301 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42302 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42303 + tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0;
42304 + /* TODO - add 'qosSrc' */
42305 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42306 +
42307 + tmpReg32 = HMAN_OC_CAPWAP_MANIP;
42308 + if (p_ManipParams->h_NextManip)
42309 + {
42310 + WRITE_UINT32(
42311 + p_Ad->matchTblPtr,
42312 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
42313 +
42314 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN;
42315 + }
42316 +
42317 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42318 +
42319 + return err;
42320 +}
42321 +#endif /* (DPAA_VERSION >= 11) */
42322 +
42323 +static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params,
42324 + bool stats)
42325 +{
42326 + t_FmPcdManip *p_Manip;
42327 + t_Error err;
42328 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42329 +
42330 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
42331 + if (!p_Manip)
42332 + {
42333 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
42334 + return NULL;
42335 + }
42336 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
42337 +
42338 + p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type;
42339 + memcpy((uint8_t*)&p_Manip->manipParams, p_Params,
42340 + sizeof(p_Manip->manipParams));
42341 +
42342 + if (!stats)
42343 + err = CheckManipParamsAndSetType(p_Manip,
42344 + (t_FmPcdManipParams *)p_Params);
42345 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42346 + else
42347 + err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
42348 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42349 + else
42350 + {
42351 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!"));
42352 + XX_Free(p_Manip);
42353 + return NULL;
42354 + }
42355 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42356 + if (err)
42357 + {
42358 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type"));
42359 + XX_Free(p_Manip);
42360 + return NULL;
42361 + }
42362 +
42363 + if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY))
42364 + {
42365 + /* In Case of reassembly manipulation the reassembly action descriptor will
42366 + be defines later on */
42367 + if (p_Manip->muramAllocate)
42368 + {
42369 + p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(
42370 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
42371 + FM_PCD_CC_AD_TABLE_ALIGN);
42372 + if (!p_Manip->h_Ad)
42373 + {
42374 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor"));
42375 + ReleaseManipHandler(p_Manip, p_FmPcd);
42376 + XX_Free(p_Manip);
42377 + return NULL;
42378 + }
42379 +
42380 + MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42381 + }
42382 + else
42383 + {
42384 + p_Manip->h_Ad = (t_Handle)XX_Malloc(
42385 + FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42386 + if (!p_Manip->h_Ad)
42387 + {
42388 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
42389 + ReleaseManipHandler(p_Manip, p_FmPcd);
42390 + XX_Free(p_Manip);
42391 + return NULL;
42392 + }
42393 +
42394 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42395 + }
42396 + }
42397 +
42398 + p_Manip->h_FmPcd = h_FmPcd;
42399 +
42400 + return p_Manip;
42401 +}
42402 +
42403 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
42404 + t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst)
42405 +{
42406 + t_CcNodeInformation *p_CcNodeInformation;
42407 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL;
42408 + t_List *p_Pos;
42409 + int i = 0;
42410 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
42411 + t_CcNodeInformation ccNodeInfo;
42412 +
42413 + LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst)
42414 + {
42415 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
42416 + p_NodePtrOnCurrentMdfManip =
42417 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
42418 +
42419 + ASSERT_COND(p_NodePtrOnCurrentMdfManip);
42420 +
42421 + /* Search in the previous node which exact index points on this current modified node for getting AD */
42422 + for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++)
42423 + {
42424 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine
42425 + == e_FM_PCD_CC)
42426 + {
42427 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip
42428 + == (t_Handle)p_CrntMdfManip)
42429 + {
42430 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj)
42431 + p_AdTablePtOnCrntCurrentMdfNode =
42432 + p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
42433 + else
42434 + p_AdTablePtOnCrntCurrentMdfNode =
42435 + PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
42436 +
42437 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
42438 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
42439 + EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL);
42440 + }
42441 + }
42442 + }
42443 +
42444 + ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys);
42445 + }
42446 +}
42447 +
42448 +static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd,
42449 + t_FmPcd *p_FmPcd)
42450 +{
42451 + t_Error err;
42452 +
42453 + /* Copy the HMTD */
42454 + MemCpy8(p_Dest, (uint8_t*)p_Src, 16);
42455 + /* Replace the HMCT table pointer */
42456 + WRITE_UINT32(
42457 + ((t_Hmtd *)p_Dest)->hmcdBasePtr,
42458 + (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase));
42459 + /* Call Host Command to replace HMTD by a new HMTD */
42460 + err = FmHcPcdCcDoDynamicChange(
42461 + p_FmPcd->h_Hc,
42462 + (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase),
42463 + (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase));
42464 + if (err)
42465 + REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners."));
42466 +}
42467 +
42468 +static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42469 + t_Handle h_FmPort, t_Handle h_Manip,
42470 + t_Handle h_Ad, bool validate, int level,
42471 + t_Handle h_FmTree)
42472 +{
42473 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42474 + t_Error err = E_OK;
42475 +
42476 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42477 +
42478 + UNUSED(level);
42479 + UNUSED(h_FmTree);
42480 +
42481 + switch (p_Manip->opcode)
42482 + {
42483 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42484 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42485 + err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort,
42486 + p_Manip,
42487 + h_Ad,
42488 + validate);
42489 + break;
42490 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42491 + if (!p_Manip->h_Frag)
42492 + break;
42493 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42494 + err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
42495 + break;
42496 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42497 + if (p_Manip->h_Frag)
42498 + err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
42499 + break;
42500 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42501 + err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
42502 + break;
42503 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42504 + case (HMAN_OC_IP_REASSEMBLY):
42505 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42506 + validate);
42507 + break;
42508 + case (HMAN_OC_IP_FRAGMENTATION):
42509 + err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42510 + h_Ad, validate);
42511 + break;
42512 +#if (DPAA_VERSION >= 11)
42513 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42514 + err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42515 + h_Ad, validate);
42516 + break;
42517 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42518 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42519 + validate);
42520 + break;
42521 +#endif /* (DPAA_VERSION >= 11) */
42522 + default:
42523 + return E_OK;
42524 + }
42525 +
42526 + return err;
42527 +}
42528 +
42529 +static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad,
42530 + bool validate, int level,
42531 + t_Handle h_FmTree)
42532 +{
42533 +
42534 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42535 + t_Error err = E_OK;
42536 +
42537 + UNUSED(level);
42538 +
42539 + switch (p_Manip->opcode)
42540 + {
42541 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42542 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42543 + RETURN_ERROR(
42544 + MAJOR,
42545 + E_INVALID_STATE,
42546 + ("modify node with this type of manipulation is not suppported"));
42547 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42548 +
42549 + if (p_Manip->h_Frag)
42550 + {
42551 + if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS)
42552 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)
42553 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
42554 + RETURN_ERROR(
42555 + MAJOR,
42556 + E_INVALID_STATE,
42557 + ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function"));
42558 + }
42559 + break;
42560 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42561 + if (p_Manip->h_Frag)
42562 + err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
42563 + break;
42564 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42565 + default:
42566 + return E_OK;
42567 + }
42568 +
42569 + return err;
42570 +}
42571 +
42572 +/*****************************************************************************/
42573 +/* Inter-module API routines */
42574 +/*****************************************************************************/
42575 +
42576 +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42577 + t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad,
42578 + bool validate, int level, t_Handle h_FmTree,
42579 + bool modify)
42580 +{
42581 + t_Error err;
42582 +
42583 + if (!modify)
42584 + err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip,
42585 + h_Ad, validate, level, h_FmTree);
42586 + else
42587 + err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
42588 +
42589 + return err;
42590 +}
42591 +
42592 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
42593 +{
42594 +
42595 + uint32_t intFlags;
42596 +
42597 + intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock);
42598 + if (add)
42599 + ((t_FmPcdManip *)h_Manip)->owner++;
42600 + else
42601 + {
42602 + ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
42603 + ((t_FmPcdManip *)h_Manip)->owner--;
42604 + }
42605 + XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags);
42606 +}
42607 +
42608 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
42609 +{
42610 + ASSERT_COND(h_Manip);
42611 + return &((t_FmPcdManip *)h_Manip)->nodesLst;
42612 +}
42613 +
42614 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
42615 +{
42616 + ASSERT_COND(h_Manip);
42617 + return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
42618 +}
42619 +
42620 +t_Error FmPcdManipCheckParamsForCcNextEngine(
42621 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
42622 + uint32_t *requiredAction)
42623 +{
42624 + t_FmPcdManip *p_Manip;
42625 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42626 + t_Error err = E_OK;
42627 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/
42628 + bool pointFromCc = TRUE;
42629 +
42630 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
42631 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip,
42632 + E_NULL_POINTER);
42633 +
42634 + p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
42635 + *requiredAction = 0;
42636 +
42637 + while (p_Manip)
42638 + {
42639 + switch (p_Manip->opcode)
42640 + {
42641 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42642 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42643 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42644 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42645 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42646 + p_Manip->cnia = TRUE;
42647 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42648 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42649 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42650 + p_Manip->ownerTmp++;
42651 + break;
42652 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42653 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42654 + && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42655 + RETURN_ERROR(
42656 + MAJOR,
42657 + E_INVALID_STATE,
42658 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
42659 + p_Manip->ownerTmp++;
42660 + break;
42661 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42662 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)
42663 + && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
42664 + != CC_PC_GENERIC_IC_HASH_INDEXED))
42665 + 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"));
42666 + err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip,
42667 + FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
42668 + if (err)
42669 + RETURN_ERROR(MAJOR, err, NO_MSG);
42670 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42671 + break;
42672 + #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42673 + case (HMAN_OC_IP_FRAGMENTATION):
42674 + case (HMAN_OC_IP_REASSEMBLY):
42675 +#if (DPAA_VERSION >= 11)
42676 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42677 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42678 +#endif /* (DPAA_VERSION >= 11) */
42679 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42680 + RETURN_ERROR(
42681 + MAJOR,
42682 + E_INVALID_STATE,
42683 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42684 + p_Manip->ownerTmp++;
42685 + break;
42686 + case (HMAN_OC_IPSEC_MANIP):
42687 +#if (DPAA_VERSION >= 11)
42688 + case (HMAN_OC_CAPWAP_MANIP):
42689 +#endif /* (DPAA_VERSION >= 11) */
42690 + p_Manip->ownerTmp++;
42691 + break;
42692 + case (HMAN_OC):
42693 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
42694 + && MANIP_IS_CASCADED(p_Manip))
42695 + RETURN_ERROR(
42696 + MINOR,
42697 + E_INVALID_STATE,
42698 + ("Can't have a cascaded manipulation when and Next Engine is CC"));
42699 + if (!MANIP_IS_FIRST(p_Manip) && pointFromCc)
42700 + RETURN_ERROR(
42701 + MAJOR,
42702 + E_INVALID_STATE,
42703 + ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)"));
42704 + break;
42705 + default:
42706 + RETURN_ERROR(
42707 + MAJOR, E_INVALID_STATE,
42708 + ("invalid type of header manipulation for this state"));
42709 + }
42710 + p_Manip = p_Manip->h_NextManip;
42711 + pointFromCc = FALSE;
42712 + }
42713 + return E_OK;
42714 +}
42715 +
42716 +
42717 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,
42718 + t_Handle h_FmPcdCcNode)
42719 +{
42720 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42721 + t_Error err = E_OK;
42722 +
42723 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42724 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
42725 +
42726 + switch (p_Manip->opcode)
42727 + {
42728 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42729 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42730 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42731 + RETURN_ERROR(
42732 + MAJOR,
42733 + E_INVALID_VALUE,
42734 + ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
42735 + break;
42736 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42737 + if (p_Manip->h_Frag)
42738 + {
42739 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42740 + RETURN_ERROR(
42741 + MAJOR,
42742 + E_INVALID_VALUE,
42743 + ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
42744 + err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
42745 + if (err)
42746 + RETURN_ERROR(MAJOR, err, NO_MSG);
42747 + }
42748 + break;
42749 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42750 + default:
42751 + break;
42752 + }
42753 +
42754 + return err;
42755 +}
42756 +
42757 +void FmPcdManipUpdateAdResultForCc(
42758 + t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
42759 + t_Handle p_Ad, t_Handle *p_AdNewPtr)
42760 +{
42761 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42762 +
42763 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42764 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42765 +
42766 + ASSERT_COND(p_Manip);
42767 + ASSERT_COND(p_CcNextEngineParams);
42768 + ASSERT_COND(p_Ad);
42769 + ASSERT_COND(p_AdNewPtr);
42770 +
42771 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42772 +
42773 + /* According to "type", either build & initialize a new AD (p_AdNew) or initialize
42774 + * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */
42775 + switch (p_Manip->opcode)
42776 + {
42777 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42778 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42779 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42780 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42781 + *p_AdNewPtr = p_Manip->h_Ad;
42782 + break;
42783 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42784 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42785 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,
42786 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
42787 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,
42788 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
42789 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,
42790 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
42791 + *p_AdNewPtr = NULL;
42792 + break;
42793 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42794 + case (HMAN_OC_IPSEC_MANIP):
42795 +#if (DPAA_VERSION >= 11)
42796 + case (HMAN_OC_CAPWAP_MANIP):
42797 +#endif /* (DPAA_VERSION >= 11) */
42798 + *p_AdNewPtr = p_Manip->h_Ad;
42799 + break;
42800 + case (HMAN_OC_IP_FRAGMENTATION):
42801 +#if (DPAA_VERSION >= 11)
42802 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42803 +#endif /* (DPAA_VERSION >= 11) */
42804 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE)
42805 + && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid))
42806 + {
42807 + memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad,
42808 + sizeof(t_AdOfTypeContLookup));
42809 +#if (DPAA_VERSION >= 11)
42810 + WRITE_UINT32(
42811 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42812 + GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA);
42813 +#endif /* (DPAA_VERSION >= 11) */
42814 + *p_AdNewPtr = NULL;
42815 + }
42816 + else
42817 + *p_AdNewPtr = p_Manip->h_Ad;
42818 + break;
42819 + case (HMAN_OC_IP_REASSEMBLY):
42820 + if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip))
42821 + {
42822 + if (!p_Manip->reassmParams.ip.ipv6Assigned)
42823 + {
42824 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad;
42825 + p_Manip->reassmParams.ip.ipv6Assigned = TRUE;
42826 + FmPcdManipUpdateOwner(h_Manip, FALSE);
42827 + }
42828 + else
42829 + {
42830 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42831 + p_Manip->reassmParams.ip.ipv6Assigned = FALSE;
42832 + }
42833 + }
42834 + else
42835 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42836 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42837 + sizeof(t_AdOfTypeContLookup));
42838 + *p_AdNewPtr = NULL;
42839 + break;
42840 +#if (DPAA_VERSION >= 11)
42841 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42842 + *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad;
42843 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42844 + sizeof(t_AdOfTypeContLookup));
42845 + *p_AdNewPtr = NULL;
42846 + break;
42847 +#endif /* (DPAA_VERSION >= 11) */
42848 + case (HMAN_OC):
42849 + /* Allocate and initialize HMTD */
42850 + *p_AdNewPtr = p_Manip->h_Ad;
42851 + break;
42852 + default:
42853 + break;
42854 + }
42855 +}
42856 +
42857 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad,
42858 + t_Handle *p_AdNewPtr,
42859 + uint32_t adTableOffset)
42860 +{
42861 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42862 +
42863 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42864 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42865 + ASSERT_COND(p_Manip);
42866 +
42867 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42868 +
42869 + switch (p_Manip->opcode)
42870 + {
42871 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42872 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42873 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42874 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
42875 + WRITE_UINT32(
42876 + ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,
42877 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
42878 + WRITE_UINT32(
42879 + ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,
42880 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
42881 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,
42882 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
42883 + WRITE_UINT32(
42884 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42885 + (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
42886 + *p_AdNewPtr = NULL;
42887 + break;
42888 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42889 + case (HMAN_OC):
42890 + /* Initialize HMTD within the match table*/
42891 + MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42892 + /* copy the existing HMTD *//* ask Alla - memcpy??? */
42893 + memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd));
42894 + /* update NADEN to be "1"*/
42895 + WRITE_UINT16(
42896 + ((t_Hmtd *)p_Ad)->cfg,
42897 + (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN));
42898 + /* update next action descriptor */
42899 + WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx,
42900 + (uint16_t)(adTableOffset >> 4));
42901 + /* mark that Manip's HMTD is not used */
42902 + *p_AdNewPtr = NULL;
42903 + break;
42904 +
42905 + default:
42906 + break;
42907 + }
42908 +}
42909 +
42910 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
42911 + t_Handle h_CcTree, t_Handle h_Manip,
42912 + bool isIpv4, uint8_t groupId)
42913 +{
42914 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42915 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
42916 + t_Handle h_Scheme;
42917 +
42918 + ASSERT_COND(p_FmPcd);
42919 + ASSERT_COND(h_NetEnv);
42920 + ASSERT_COND(p_Manip);
42921 +
42922 + /* scheme was already build, no need to check for IPv6 */
42923 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
42924 + return E_OK;
42925 +
42926 + if (isIpv4) {
42927 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
42928 + if (h_Scheme) {
42929 + /* scheme was found */
42930 + p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
42931 + return E_OK;
42932 + }
42933 + } else {
42934 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
42935 + if (h_Scheme) {
42936 + /* scheme was found */
42937 + p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
42938 + return E_OK;
42939 + }
42940 + }
42941 +
42942 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
42943 + if (!p_SchemeParams)
42944 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42945 + ("Memory allocation failed for scheme"));
42946 +
42947 + /* Configures the IPv4 or IPv6 scheme*/
42948 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
42949 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
42950 + p_SchemeParams->id.relativeSchemeId = (uint8_t)(
42951 + (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] :
42952 + p_Manip->reassmParams.ip.relativeSchemeId[1]);
42953 + p_SchemeParams->schemeCounter.update = TRUE;
42954 +#if (DPAA_VERSION >= 11)
42955 + p_SchemeParams->alwaysDirect = TRUE;
42956 + p_SchemeParams->bypassFqidGeneration = TRUE;
42957 +#else
42958 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1;
42959 + p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/
42960 +#endif /* (DPAA_VERSION >= 11) */
42961 +
42962 + setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId);
42963 +
42964 + /* Sets the new scheme */
42965 + if (isIpv4)
42966 + p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet(
42967 + p_FmPcd, p_SchemeParams);
42968 + else
42969 + p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet(
42970 + p_FmPcd, p_SchemeParams);
42971 +
42972 + XX_Free(p_SchemeParams);
42973 +
42974 + return E_OK;
42975 +}
42976 +
42977 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
42978 +{
42979 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42980 +
42981 + ASSERT_COND(p_Manip);
42982 +
42983 + if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
42984 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
42985 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
42986 +
42987 + if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
42988 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
42989 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
42990 +
42991 + return E_OK;
42992 +}
42993 +
42994 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)
42995 +{
42996 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42997 +
42998 + ASSERT_COND(p_Manip);
42999 +
43000 + return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6);
43001 +}
43002 +
43003 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
43004 + t_Handle h_CcTree, t_Handle h_Manip,
43005 + uint8_t groupId)
43006 +{
43007 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
43008 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
43009 +
43010 + ASSERT_COND(p_FmPcd);
43011 + ASSERT_COND(h_NetEnv);
43012 + ASSERT_COND(p_Manip);
43013 +
43014 + /* scheme was already build, no need to check for IPv6 */
43015 + if (p_Manip->reassmParams.capwap.h_Scheme)
43016 + return E_OK;
43017 +
43018 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
43019 + if (!p_SchemeParams)
43020 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
43021 + ("Memory allocation failed for scheme"));
43022 +
43023 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
43024 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
43025 + p_SchemeParams->id.relativeSchemeId =
43026 + (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId;
43027 + p_SchemeParams->schemeCounter.update = TRUE;
43028 + p_SchemeParams->bypassFqidGeneration = TRUE;
43029 +
43030 + setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId);
43031 +
43032 + p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd,
43033 + p_SchemeParams);
43034 +
43035 + XX_Free(p_SchemeParams);
43036 +
43037 + return E_OK;
43038 +}
43039 +
43040 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)
43041 +{
43042 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
43043 +
43044 + ASSERT_COND(p_Manip);
43045 +
43046 + if (p_Manip->reassmParams.capwap.h_Scheme)
43047 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme);
43048 +
43049 + return E_OK;
43050 +}
43051 +
43052 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43053 +t_Handle FmPcdManipApplSpecificBuild(void)
43054 +{
43055 + t_FmPcdManip *p_Manip;
43056 +
43057 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
43058 + if (!p_Manip)
43059 + {
43060 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
43061 + return NULL;
43062 + }
43063 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
43064 +
43065 + p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
43066 + p_Manip->muramAllocate = FALSE;
43067 +
43068 + p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
43069 + if (!p_Manip->h_Ad)
43070 + {
43071 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
43072 + XX_Free(p_Manip);
43073 + return NULL;
43074 + }
43075 +
43076 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
43077 +
43078 + /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/
43079 + /*Application specific = type of flowId index, move internal frame header from data to IC,
43080 + SEC errors check*/
43081 + if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK)
43082 + {
43083 + XX_Free(p_Manip->h_Ad);
43084 + XX_Free(p_Manip);
43085 + return NULL;
43086 + }
43087 + return p_Manip;
43088 +}
43089 +
43090 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)
43091 +{
43092 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
43093 + ASSERT_COND(h_Manip);
43094 +
43095 + return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE);
43096 +}
43097 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43098 +/*********************** End of inter-module routines ************************/
43099 +
43100 +/****************************************/
43101 +/* API Init unit functions */
43102 +/****************************************/
43103 +
43104 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd,
43105 + t_FmPcdManipParams *p_ManipParams)
43106 +{
43107 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
43108 + t_FmPcdManip *p_Manip;
43109 + t_Error err;
43110 +
43111 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
43112 + SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL);
43113 +
43114 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
43115 + if (!p_Manip)
43116 + return NULL;
43117 +
43118 + if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY)
43119 + || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION)
43120 + || (p_Manip->opcode == HMAN_OC)
43121 + || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)
43122 +#if (DPAA_VERSION >= 11)
43123 + || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP)
43124 + || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION)
43125 + || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
43126 +#endif /* (DPAA_VERSION >= 11) */
43127 + ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd)))
43128 + {
43129 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
43130 + XX_Free(p_Manip);
43131 + return NULL;
43132 + }
43133 + p_Manip->h_Spinlock = XX_InitSpinlock();
43134 + if (!p_Manip->h_Spinlock)
43135 + {
43136 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43137 + ReleaseManipHandler(p_Manip, p_FmPcd);
43138 + XX_Free(p_Manip);
43139 + return NULL;
43140 + }INIT_LIST(&p_Manip->nodesLst);
43141 +
43142 + switch (p_Manip->opcode)
43143 + {
43144 + case (HMAN_OC_IP_REASSEMBLY):
43145 + /* IpReassembly */
43146 + err = IpReassembly(&p_ManipParams->u.reassem, p_Manip);
43147 + break;
43148 + case (HMAN_OC_IP_FRAGMENTATION):
43149 + /* IpFragmentation */
43150 + err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip);
43151 + if (err)
43152 + break;
43153 + err = IPManip(p_Manip);
43154 + break;
43155 + case (HMAN_OC_IPSEC_MANIP):
43156 + err = IPSecManip(p_ManipParams, p_Manip);
43157 + break;
43158 +#if (DPAA_VERSION >= 11)
43159 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43160 + /* CapwapReassembly */
43161 + err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip);
43162 + break;
43163 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43164 + /* CapwapFragmentation */
43165 + err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag,
43166 + p_Manip);
43167 + break;
43168 + case (HMAN_OC_CAPWAP_MANIP):
43169 + err = CapwapManip(p_ManipParams, p_Manip);
43170 + break;
43171 +#endif /* (DPAA_VERSION >= 11) */
43172 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43173 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
43174 + /* HmanType1 */
43175 + err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip);
43176 + break;
43177 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43178 + err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams,
43179 + p_Manip,
43180 + p_FmPcd,
43181 + p_ManipParams->fragOrReasmParams.sgBpid);
43182 + if (err)
43183 + {
43184 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43185 + ReleaseManipHandler(p_Manip, p_FmPcd);
43186 + XX_Free(p_Manip);
43187 + return NULL;
43188 + }
43189 + if (p_Manip->insrt)
43190 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
43191 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
43192 + /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
43193 + err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd);
43194 + break;
43195 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43196 + err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams,
43197 + p_Manip,
43198 + p_FmPcd,
43199 + p_ManipParams->fragOrReasmParams.sgBpid);
43200 + if (err)
43201 + {
43202 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43203 + ReleaseManipHandler(p_Manip, p_FmPcd);
43204 + XX_Free(p_Manip);
43205 + return NULL;
43206 + }
43207 + if (p_Manip->rmv)
43208 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
43209 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
43210 + /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
43211 + err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
43212 + break;
43213 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
43214 + /*Application Specific type 1*/
43215 + err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE);
43216 + break;
43217 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43218 + case (HMAN_OC):
43219 + /* New Manip */
43220 + err = CreateManipActionNew(p_Manip, p_ManipParams);
43221 + break;
43222 + default:
43223 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43224 + ReleaseManipHandler(p_Manip, p_FmPcd);
43225 + XX_Free(p_Manip);
43226 + return NULL;
43227 + }
43228 +
43229 + if (err)
43230 + {
43231 + REPORT_ERROR(MAJOR, err, NO_MSG);
43232 + ReleaseManipHandler(p_Manip, p_FmPcd);
43233 + XX_Free(p_Manip);
43234 + return NULL;
43235 + }
43236 +
43237 + if (p_ManipParams->h_NextManip)
43238 + {
43239 + /* in the check routine we've verified that h_NextManip has no owners
43240 + * and that only supported types are allowed. */
43241 + p_Manip->h_NextManip = p_ManipParams->h_NextManip;
43242 + /* save a "prev" pointer in h_NextManip */
43243 + MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip);
43244 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE);
43245 + }
43246 +
43247 + return p_Manip;
43248 +}
43249 +
43250 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip,
43251 + t_FmPcdManipParams *p_ManipParams)
43252 +{
43253 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip;
43254 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd);
43255 + t_Error err;
43256 + uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL;
43257 + t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos;
43258 + t_CcNodeInformation *p_CcNodeInfo;
43259 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
43260 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
43261 +
43262 + INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip);
43263 +
43264 + if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR)
43265 + || (p_Manip->type != e_FM_PCD_MANIP_HDR))
43266 + RETURN_ERROR(
43267 + MINOR,
43268 + E_NOT_SUPPORTED,
43269 + ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation."));
43270 +
43271 + ASSERT_COND(p_Manip->opcode == HMAN_OC);
43272 + ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip);
43273 + memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams,
43274 + sizeof(p_Manip->manipParams));
43275 + p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip;
43276 +
43277 + /* The replacement of the HdrManip depends on the node type.*/
43278 + /*
43279 + * (1) If this is an independent node, all its owners should be updated.
43280 + *
43281 + * (2) If it is the head of a cascaded chain (it does not have a "prev" but
43282 + * it has a "next" and it has a "cascaded" indication), the next
43283 + * node remains unchanged, and the behavior is as in (1).
43284 + *
43285 + * (3) If it is not the head, but a part of a cascaded chain, in can be
43286 + * also replaced as a regular node with just one owner.
43287 + *
43288 + * (4) If it is a part of a chain implemented as a unified table, the
43289 + * whole table is replaced and the owners of the head node must be updated.
43290 + *
43291 + */
43292 + /* lock shadow */
43293 + if (!p_FmPcd->p_CcShadow)
43294 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
43295 +
43296 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
43297 + return ERROR_CODE(E_BUSY);
43298 +
43299 + /* this routine creates a new manip action in the CC Shadow. */
43300 + err = CreateManipActionShadow(p_Manip, p_ManipParams);
43301 + if (err)
43302 + RETURN_ERROR(MINOR, err, NO_MSG);
43303 +
43304 + /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC)
43305 + * replace only HMTD and no lcok is required. Otherwise
43306 + * lock the whole PCD
43307 + * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */
43308 + if (!FmPcdLockTryLockAll(p_FmPcd))
43309 + {
43310 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
43311 + return ERROR_CODE(E_BUSY);
43312 + }
43313 +
43314 + p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
43315 +
43316 + p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip,
43317 + e_MANIP_HANDLER_TABLE_OWNER);
43318 + ASSERT_COND(p_FirstManip);
43319 +
43320 + if (!LIST_IsEmpty(&p_FirstManip->nodesLst))
43321 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
43322 + p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip);
43323 +
43324 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43325 + ASSERT_COND(p_Hmtd);
43326 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct,
43327 + ((t_FmPcd*)(p_Manip->h_FmPcd)));
43328 +
43329 + LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43330 + {
43331 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43332 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43333 + p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43334 + }
43335 +
43336 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
43337 + ASSERT_COND(p_WholeHmct);
43338 +
43339 + /* re-build the HMCT n the original location */
43340 + err = CreateManipActionBackToOrig(p_Manip, p_ManipParams);
43341 + if (err)
43342 + {
43343 + RELEASE_LOCK(p_FmPcd->shadowLock);
43344 + RETURN_ERROR(MINOR, err, NO_MSG);
43345 + }
43346 +
43347 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43348 + ASSERT_COND(p_Hmtd);
43349 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct,
43350 + ((t_FmPcd*)p_Manip->h_FmPcd));
43351 +
43352 + /* If LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list.
43353 + * For each p_Hmct (from list+fixed):
43354 + * call Host Command to replace HMTD by a new one */LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43355 + {
43356 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43357 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43358 + p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43359 + }
43360 +
43361 +
43362 + ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip);
43363 +
43364 + FmPcdLockUnlockAll(p_FmPcd);
43365 +
43366 + /* unlock shadow */
43367 + RELEASE_LOCK(p_FmPcd->shadowLock);
43368 +
43369 + return E_OK;
43370 +}
43371 +
43372 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)
43373 +{
43374 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43375 +
43376 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43377 +
43378 + if (p_Manip->owner)
43379 + RETURN_ERROR(
43380 + MAJOR,
43381 + E_INVALID_STATE,
43382 + ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
43383 +
43384 + if (p_Manip->h_NextManip)
43385 + {
43386 + MANIP_SET_PREV(p_Manip->h_NextManip, NULL);
43387 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE);
43388 + }
43389 +
43390 + if (p_Manip->p_Hmct
43391 + && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip)))
43392 + FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram,
43393 + p_Manip->p_Hmct);
43394 +
43395 + if (p_Manip->h_Spinlock)
43396 + {
43397 + XX_FreeSpinlock(p_Manip->h_Spinlock);
43398 + p_Manip->h_Spinlock = NULL;
43399 + }
43400 +
43401 + ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd);
43402 +
43403 + XX_Free(h_ManipNode);
43404 +
43405 + return E_OK;
43406 +}
43407 +
43408 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,
43409 + t_FmPcdManipStats *p_FmPcdManipStats)
43410 +{
43411 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43412 +
43413 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43414 + SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER);
43415 +
43416 + switch (p_Manip->opcode)
43417 + {
43418 + case (HMAN_OC_IP_REASSEMBLY):
43419 + return IpReassemblyStats(p_Manip,
43420 + &p_FmPcdManipStats->u.reassem.u.ipReassem);
43421 + case (HMAN_OC_IP_FRAGMENTATION):
43422 + return IpFragmentationStats(p_Manip,
43423 + &p_FmPcdManipStats->u.frag.u.ipFrag);
43424 +#if (DPAA_VERSION >= 11)
43425 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43426 + return CapwapReassemblyStats(
43427 + p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem);
43428 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43429 + return CapwapFragmentationStats(
43430 + p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag);
43431 +#endif /* (DPAA_VERSION >= 11) */
43432 + default:
43433 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
43434 + ("no statistics to this type of manip"));
43435 + }
43436 +
43437 + return E_OK;
43438 +}
43439 +
43440 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43441 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
43442 +{
43443 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
43444 + t_FmPcdManip *p_Manip;
43445 + t_Error err;
43446 +
43447 + SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
43448 + SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
43449 +
43450 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
43451 + if (!p_Manip)
43452 + return NULL;
43453 +
43454 + switch (p_Manip->opcode)
43455 + {
43456 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
43457 + /* Indexed statistics */
43458 + err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
43459 + break;
43460 + default:
43461 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
43462 + ReleaseManipHandler(p_Manip, p_FmPcd);
43463 + XX_Free(p_Manip);
43464 + return NULL;
43465 + }
43466 +
43467 + if (err)
43468 + {
43469 + REPORT_ERROR(MAJOR, err, NO_MSG);
43470 + ReleaseManipHandler(p_Manip, p_FmPcd);
43471 + XX_Free(p_Manip);
43472 + return NULL;
43473 + }
43474 +
43475 + return p_Manip;
43476 +}
43477 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43478 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
43479 new file mode 100644
43480 index 00000000..853bb834
43481 --- /dev/null
43482 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
43483 @@ -0,0 +1,555 @@
43484 +/*
43485 + * Copyright 2008-2012 Freescale Semiconductor Inc.
43486 + *
43487 + * Redistribution and use in source and binary forms, with or without
43488 + * modification, are permitted provided that the following conditions are met:
43489 + * * Redistributions of source code must retain the above copyright
43490 + * notice, this list of conditions and the following disclaimer.
43491 + * * Redistributions in binary form must reproduce the above copyright
43492 + * notice, this list of conditions and the following disclaimer in the
43493 + * documentation and/or other materials provided with the distribution.
43494 + * * Neither the name of Freescale Semiconductor nor the
43495 + * names of its contributors may be used to endorse or promote products
43496 + * derived from this software without specific prior written permission.
43497 + *
43498 + *
43499 + * ALTERNATIVELY, this software may be distributed under the terms of the
43500 + * GNU General Public License ("GPL") as published by the Free Software
43501 + * Foundation, either version 2 of that License or (at your option) any
43502 + * later version.
43503 + *
43504 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
43505 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43506 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43507 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
43508 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43509 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43510 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43511 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43512 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43513 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43514 + */
43515 +
43516 +
43517 +/******************************************************************************
43518 + @File fm_manip.h
43519 +
43520 + @Description FM PCD manip...
43521 +*//***************************************************************************/
43522 +#ifndef __FM_MANIP_H
43523 +#define __FM_MANIP_H
43524 +
43525 +#include "std_ext.h"
43526 +#include "error_ext.h"
43527 +#include "list_ext.h"
43528 +
43529 +#include "fm_cc.h"
43530 +
43531 +
43532 +/***********************************************************************/
43533 +/* Header manipulations defines */
43534 +/***********************************************************************/
43535 +
43536 +#define NUM_OF_SCRATCH_POOL_BUFFERS 1000 /*TODO - Change it!!*/
43537 +
43538 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43539 +#define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e
43540 +#define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31
43541 +#define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f
43542 +#define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30
43543 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */
43544 +#define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */
43545 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43546 +#else
43547 +#define HMAN_OC_CAPWAP_MANIP 0x2F
43548 +#define HMAN_OC_CAPWAP_FRAG_CHECK 0x2E
43549 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43550 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x30
43551 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43552 +#define HMAN_OC_IP_MANIP 0x34
43553 +#define HMAN_OC_IP_FRAGMENTATION 0x74
43554 +#define HMAN_OC_IP_REASSEMBLY 0xB4
43555 +#define HMAN_OC_IPSEC_MANIP 0xF4
43556 +#define HMAN_OC 0x35
43557 +
43558 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43559 +#define HMAN_RMV_HDR 0x80000000
43560 +#define HMAN_INSRT_INT_FRM_HDR 0x40000000
43561 +
43562 +#define UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP 6
43563 +#define UDP_CHECKSUM_FIELD_SIZE 2
43564 +#define UDP_LENGTH_FIELD_OFFSET_FROM_UDP 4
43565 +
43566 +#define IPv4_DSCECN_FIELD_OFFSET_FROM_IP 1
43567 +#define IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2
43568 +#define IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10
43569 +#define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12
43570 +#define IPv4_ID_FIELD_OFFSET_FROM_IP 4
43571 +
43572 +#define IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP 4
43573 +#define IPv6_NEXT_HEADER_OFFSET_FROM_IP 6
43574 +
43575 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 0x80
43576 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8
43577 +#define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32
43578 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4
43579 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE 8
43580 +
43581 +
43582 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES 0x40000000
43583 +#define FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG 0x10000000
43584 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS 0x08000000
43585 +#define FM_PCD_MANIP_CAPWAP_REASM_PR_COPY 0x00800000
43586 +
43587 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN 0x80000000
43588 +
43589 +#define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4
43590 +#define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000
43591 +#define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000
43592 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43593 +
43594 +#if (DPAA_VERSION >= 11)
43595 +#define FM_PCD_MANIP_CAPWAP_DTLS 0x00040000
43596 +#define FM_PCD_MANIP_CAPWAP_NADEN 0x20000000
43597 +
43598 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT 16
43599 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_NO_FRAGMENTATION 0xFFFF0000
43600 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA 0x20000000
43601 +
43602 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN 0x04000000
43603 +#define FM_PCD_MANIP_CAPWAP_FRAG_SCRATCH_BPID 24
43604 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN 0x08000000
43605 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK 0xFF000000
43606 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT 24
43607 +#endif /* (DPAA_VERSION >= 11) */
43608 +
43609 +#define FM_PCD_MANIP_REASM_TABLE_SIZE 0x40
43610 +#define FM_PCD_MANIP_REASM_TABLE_ALIGN 8
43611 +
43612 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE 64
43613 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN 8
43614 +#define FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000
43615 +#define FM_PCD_MANIP_REASM_COUPLING_ENABLE 0x40000000
43616 +#define FM_PCD_MANIP_REASM_COUPLING_MASK 0xFF000000
43617 +#define FM_PCD_MANIP_REASM_COUPLING_SHIFT 24
43618 +#define FM_PCD_MANIP_REASM_LIODN_MASK 0x0000003F
43619 +#define FM_PCD_MANIP_REASM_LIODN_SHIFT 56
43620 +#define FM_PCD_MANIP_REASM_ELIODN_MASK 0x000003c0
43621 +#define FM_PCD_MANIP_REASM_ELIODN_SHIFT 38
43622 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF
43623 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24
43624 +#define FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH 1024
43625 +
43626 +#define FM_PCD_MANIP_IP_MTU_SHIFT 16
43627 +#define FM_PCD_MANIP_IP_NO_FRAGMENTATION 0xFFFF0000
43628 +#define FM_PCD_MANIP_IP_CNIA 0x20000000
43629 +
43630 +#define FM_PCD_MANIP_IP_FRAG_DF_SHIFT 28
43631 +#define FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID 24
43632 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_EN 0x08000000
43633 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK 0xFF000000
43634 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT 24
43635 +
43636 +#define FM_PCD_MANIP_IPSEC_DEC 0x10000000
43637 +#define FM_PCD_MANIP_IPSEC_VIPV_EN 0x08000000
43638 +#define FM_PCD_MANIP_IPSEC_ECN_EN 0x04000000
43639 +#define FM_PCD_MANIP_IPSEC_DSCP_EN 0x02000000
43640 +#define FM_PCD_MANIP_IPSEC_VIPL_EN 0x01000000
43641 +#define FM_PCD_MANIP_IPSEC_NADEN 0x20000000
43642 +
43643 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_MASK 0x00FF0000
43644 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT 16
43645 +
43646 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_MASK 0xFFFF0000
43647 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT 16
43648 +
43649 +#define e_FM_MANIP_IP_INDX 1
43650 +
43651 +#define HMCD_OPCODE_GENERIC_RMV 0x01
43652 +#define HMCD_OPCODE_GENERIC_INSRT 0x02
43653 +#define HMCD_OPCODE_GENERIC_REPLACE 0x05
43654 +#define HMCD_OPCODE_L2_RMV 0x08
43655 +#define HMCD_OPCODE_L2_INSRT 0x09
43656 +#define HMCD_OPCODE_VLAN_PRI_UPDATE 0x0B
43657 +#define HMCD_OPCODE_IPV4_UPDATE 0x0C
43658 +#define HMCD_OPCODE_IPV6_UPDATE 0x10
43659 +#define HMCD_OPCODE_TCP_UDP_UPDATE 0x0E
43660 +#define HMCD_OPCODE_TCP_UDP_CHECKSUM 0x14
43661 +#define HMCD_OPCODE_REPLACE_IP 0x12
43662 +#define HMCD_OPCODE_RMV_TILL 0x15
43663 +#define HMCD_OPCODE_UDP_INSRT 0x16
43664 +#define HMCD_OPCODE_IP_INSRT 0x17
43665 +#define HMCD_OPCODE_CAPWAP_RMV 0x18
43666 +#define HMCD_OPCODE_CAPWAP_INSRT 0x18
43667 +#define HMCD_OPCODE_GEN_FIELD_REPLACE 0x19
43668 +
43669 +#define HMCD_LAST 0x00800000
43670 +
43671 +#define HMCD_DSCP_VALUES 64
43672 +
43673 +#define HMCD_BASIC_SIZE 4
43674 +#define HMCD_PTR_SIZE 4
43675 +#define HMCD_PARAM_SIZE 4
43676 +#define HMCD_IPV4_ADDR_SIZE 4
43677 +#define HMCD_IPV6_ADDR_SIZE 0x10
43678 +#define HMCD_L4_HDR_SIZE 8
43679 +
43680 +#define HMCD_CAPWAP_INSRT 0x00010000
43681 +#define HMCD_INSRT_UDP_LITE 0x00010000
43682 +#define HMCD_IP_ID_MASK 0x0000FFFF
43683 +#define HMCD_IP_SIZE_MASK 0x0000FF00
43684 +#define HMCD_IP_SIZE_SHIFT 8
43685 +#define HMCD_IP_LAST_PID_MASK 0x000000FF
43686 +#define HMCD_IP_OR_QOS 0x00010000
43687 +#define HMCD_IP_L4_CS_CALC 0x00040000
43688 +#define HMCD_IP_DF_MODE 0x00400000
43689 +
43690 +
43691 +#define HMCD_OC_SHIFT 24
43692 +
43693 +#define HMCD_RMV_OFFSET_SHIFT 0
43694 +#define HMCD_RMV_SIZE_SHIFT 8
43695 +
43696 +#define HMCD_INSRT_OFFSET_SHIFT 0
43697 +#define HMCD_INSRT_SIZE_SHIFT 8
43698 +
43699 +#define HMTD_CFG_TYPE 0x4000
43700 +#define HMTD_CFG_EXT_HMCT 0x0080
43701 +#define HMTD_CFG_PRS_AFTER_HM 0x0040
43702 +#define HMTD_CFG_NEXT_AD_EN 0x0020
43703 +
43704 +#define HMCD_RMV_L2_ETHERNET 0
43705 +#define HMCD_RMV_L2_STACKED_QTAGS 1
43706 +#define HMCD_RMV_L2_ETHERNET_AND_MPLS 2
43707 +#define HMCD_RMV_L2_MPLS 3
43708 +#define HMCD_RMV_L2_PPPOE 4
43709 +
43710 +#define HMCD_INSRT_L2_MPLS 0
43711 +#define HMCD_INSRT_N_UPDATE_L2_MPLS 1
43712 +#define HMCD_INSRT_L2_PPPOE 2
43713 +#define HMCD_INSRT_L2_SIZE_SHIFT 24
43714 +
43715 +#define HMCD_L2_MODE_SHIFT 16
43716 +
43717 +#define HMCD_VLAN_PRI_REP_MODE_SHIFT 16
43718 +#define HMCD_VLAN_PRI_UPDATE 0
43719 +#define HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI 1
43720 +
43721 +#define HMCD_IPV4_UPDATE_TTL 0x00000001
43722 +#define HMCD_IPV4_UPDATE_TOS 0x00000002
43723 +#define HMCD_IPV4_UPDATE_DST 0x00000020
43724 +#define HMCD_IPV4_UPDATE_SRC 0x00000040
43725 +#define HMCD_IPV4_UPDATE_ID 0x00000080
43726 +#define HMCD_IPV4_UPDATE_TOS_SHIFT 8
43727 +
43728 +#define HMCD_IPV6_UPDATE_HL 0x00000001
43729 +#define HMCD_IPV6_UPDATE_TC 0x00000002
43730 +#define HMCD_IPV6_UPDATE_DST 0x00000040
43731 +#define HMCD_IPV6_UPDATE_SRC 0x00000080
43732 +#define HMCD_IPV6_UPDATE_TC_SHIFT 8
43733 +
43734 +#define HMCD_TCP_UDP_UPDATE_DST 0x00004000
43735 +#define HMCD_TCP_UDP_UPDATE_SRC 0x00008000
43736 +#define HMCD_TCP_UDP_UPDATE_SRC_SHIFT 16
43737 +
43738 +#define HMCD_IP_REPLACE_REPLACE_IPV4 0x00000000
43739 +#define HMCD_IP_REPLACE_REPLACE_IPV6 0x00010000
43740 +#define HMCD_IP_REPLACE_TTL_HL 0x00200000
43741 +#define HMCD_IP_REPLACE_ID 0x00400000
43742 +
43743 +#define HMCD_IP_REPLACE_L3HDRSIZE_SHIFT 24
43744 +
43745 +#define HMCD_GEN_FIELD_SIZE_SHIFT 16
43746 +#define HMCD_GEN_FIELD_SRC_OFF_SHIFT 8
43747 +#define HMCD_GEN_FIELD_DST_OFF_SHIFT 0
43748 +#define HMCD_GEN_FIELD_MASK_EN 0x00400000
43749 +
43750 +#define HMCD_GEN_FIELD_MASK_OFF_SHIFT 16
43751 +#define HMCD_GEN_FIELD_MASK_SHIFT 24
43752 +
43753 +#define DSCP_TO_VLAN_TABLE_SIZE 32
43754 +
43755 +#define MANIP_GET_HMCT_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->tableSize)
43756 +#define MANIP_GET_DATA_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->dataSize)
43757 +
43758 +#define MANIP_GET_HMCT_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Hmct)
43759 +#define MANIP_GET_DATA_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Data)
43760 +
43761 +#define MANIP_SET_HMCT_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Hmct = h_NewPtr)
43762 +#define MANIP_SET_DATA_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Data = h_NewPtr)
43763 +
43764 +#define MANIP_GET_HMTD_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->h_Ad)
43765 +#define MANIP_DONT_REPARSE(h_Manip) (((t_FmPcdManip *)h_Manip)->dontParseAfterManip)
43766 +#define MANIP_SET_PREV(h_Manip, h_Prev) (((t_FmPcdManip *)h_Manip)->h_PrevManip = h_Prev)
43767 +#define MANIP_GET_OWNERS(h_Manip) (((t_FmPcdManip *)h_Manip)->owner)
43768 +#define MANIP_GET_TYPE(h_Manip) (((t_FmPcdManip *)h_Manip)->type)
43769 +#define MANIP_SET_UNIFIED_TBL_PTR_INDICATION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedTablePtr = TRUE)
43770 +#define MANIP_GET_MURAM(h_Manip) (((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram)
43771 +#define MANIP_FREE_HMTD(h_Manip) \
43772 + {if (((t_FmPcdManip *)h_Manip)->muramAllocate) \
43773 + FM_MURAM_FreeMem(((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram, ((t_FmPcdManip *)h_Manip)->h_Ad);\
43774 + else \
43775 + XX_Free(((t_FmPcdManip *)h_Manip)->h_Ad); \
43776 + ((t_FmPcdManip *)h_Manip)->h_Ad = NULL; \
43777 + }
43778 +/* position regarding Manip SW structure */
43779 +#define MANIP_IS_FIRST(h_Manip) (!(((t_FmPcdManip *)h_Manip)->h_PrevManip))
43780 +#define MANIP_IS_CASCADED(h_Manip) (((t_FmPcdManip *)h_Manip)->cascaded)
43781 +#define MANIP_IS_UNIFIED(h_Manip) (!(((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE))
43782 +#define MANIP_IS_UNIFIED_NON_FIRST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID) || \
43783 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST))
43784 +#define MANIP_IS_UNIFIED_NON_LAST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) ||\
43785 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID))
43786 +#define MANIP_IS_UNIFIED_FIRST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST)
43787 +#define MANIP_IS_UNIFIED_LAST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST)
43788 +
43789 +#define MANIP_UPDATE_UNIFIED_POSITION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition = \
43790 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)? \
43791 + e_MANIP_UNIFIED_LAST : e_MANIP_UNIFIED_MID)
43792 +
43793 +typedef enum e_ManipUnifiedPosition {
43794 + e_MANIP_UNIFIED_NONE = 0,
43795 + e_MANIP_UNIFIED_FIRST,
43796 + e_MANIP_UNIFIED_MID,
43797 + e_MANIP_UNIFIED_LAST
43798 +} e_ManipUnifiedPosition;
43799 +
43800 +typedef enum e_ManipInfo {
43801 + e_MANIP_HMTD,
43802 + e_MANIP_HMCT,
43803 + e_MANIP_HANDLER_TABLE_OWNER
43804 +}e_ManipInfo;
43805 +/***********************************************************************/
43806 +/* Memory map */
43807 +/***********************************************************************/
43808 +#if defined(__MWERKS__) && !defined(__GNUC__)
43809 +#pragma pack(push,1)
43810 +#endif /* defined(__MWERKS__) && ... */
43811 +
43812 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43813 +typedef struct t_CapwapReasmPram {
43814 + volatile uint32_t mode;
43815 + volatile uint32_t autoLearnHashTblPtr;
43816 + volatile uint32_t intStatsTblPtr;
43817 + volatile uint32_t reasmFrmDescPoolTblPtr;
43818 + volatile uint32_t reasmFrmDescIndexPoolTblPtr;
43819 + volatile uint32_t timeOutTblPtr;
43820 + volatile uint32_t bufferPoolIdAndRisc1SetIndexes;
43821 + volatile uint32_t risc23SetIndexes;
43822 + volatile uint32_t risc4SetIndexesAndExtendedStatsTblPtr;
43823 + volatile uint32_t extendedStatsTblPtr;
43824 + volatile uint32_t expirationDelay;
43825 + volatile uint32_t totalProcessedFragCounter;
43826 + volatile uint32_t totalUnsuccessfulReasmFramesCounter;
43827 + volatile uint32_t totalDuplicatedFragCounter;
43828 + volatile uint32_t totalMalformdFragCounter;
43829 + volatile uint32_t totalTimeOutCounter;
43830 + volatile uint32_t totalSetBusyCounter;
43831 + volatile uint32_t totalRfdPoolBusyCounter;
43832 + volatile uint32_t totalDiscardedFragsCounter;
43833 + volatile uint32_t totalMoreThan16FramesCounter;
43834 + volatile uint32_t internalBufferBusy;
43835 + volatile uint32_t externalBufferBusy;
43836 + volatile uint32_t reserved1[4];
43837 +} t_CapwapReasmPram;
43838 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43839 +
43840 +typedef _Packed struct t_ReassTbl {
43841 + volatile uint16_t waysNumAndSetSize;
43842 + volatile uint16_t autoLearnHashKeyMask;
43843 + volatile uint32_t reassCommonPrmTblPtr;
43844 + volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi;
43845 + volatile uint32_t autoLearnHashTblPtrLow;
43846 + volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi;
43847 + volatile uint32_t autoLearnSetLockTblPtrLow;
43848 + volatile uint16_t minFragSize; /* Not relevant for CAPWAP*/
43849 + volatile uint16_t maxReassemblySize; /* Only relevant for CAPWAP*/
43850 + volatile uint32_t totalSuccessfullyReasmFramesCounter;
43851 + volatile uint32_t totalValidFragmentCounter;
43852 + volatile uint32_t totalProcessedFragCounter;
43853 + volatile uint32_t totalMalformdFragCounter;
43854 + volatile uint32_t totalSetBusyCounter;
43855 + volatile uint32_t totalDiscardedFragsCounter;
43856 + volatile uint32_t totalMoreThan16FramesCounter;
43857 + volatile uint32_t reserved2[2];
43858 +} _PackedType t_ReassTbl;
43859 +
43860 +typedef struct t_ReassCommonTbl {
43861 + volatile uint32_t timeoutModeAndFqid;
43862 + volatile uint32_t reassFrmDescIndexPoolTblPtr;
43863 + volatile uint32_t liodnAndReassFrmDescPoolPtrHi;
43864 + volatile uint32_t reassFrmDescPoolPtrLow;
43865 + volatile uint32_t timeOutTblPtr;
43866 + volatile uint32_t expirationDelay;
43867 + volatile uint32_t internalBufferManagement;
43868 + volatile uint32_t reserved2;
43869 + volatile uint32_t totalTimeOutCounter;
43870 + volatile uint32_t totalRfdPoolBusyCounter;
43871 + volatile uint32_t totalInternalBufferBusy;
43872 + volatile uint32_t totalExternalBufferBusy;
43873 + volatile uint32_t totalSgFragmentCounter;
43874 + volatile uint32_t totalDmaSemaphoreDepletionCounter;
43875 + volatile uint32_t totalNCSPCounter;
43876 + volatile uint32_t discardMask;
43877 +} t_ReassCommonTbl;
43878 +
43879 +typedef _Packed struct t_Hmtd {
43880 + volatile uint16_t cfg;
43881 + volatile uint8_t eliodnOffset;
43882 + volatile uint8_t extHmcdBasePtrHi;
43883 + volatile uint32_t hmcdBasePtr;
43884 + volatile uint16_t nextAdIdx;
43885 + volatile uint8_t res1;
43886 + volatile uint8_t opCode;
43887 + volatile uint32_t res2;
43888 +} _PackedType t_Hmtd;
43889 +
43890 +#if defined(__MWERKS__) && !defined(__GNUC__)
43891 +#pragma pack(pop)
43892 +#endif /* defined(__MWERKS__) && ... */
43893 +
43894 +
43895 +/***********************************************************************/
43896 +/* Driver's internal structures */
43897 +/***********************************************************************/
43898 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43899 +typedef struct
43900 +{
43901 + t_Handle p_AutoLearnHashTbl;
43902 + t_Handle p_ReassmFrmDescrPoolTbl;
43903 + t_Handle p_ReassmFrmDescrIndxPoolTbl;
43904 + t_Handle p_TimeOutTbl;
43905 + uint16_t maxNumFramesInProcess;
43906 + uint8_t numOfTasks;
43907 + //uint8_t poolId;
43908 + uint8_t prOffset;
43909 + uint16_t dataOffset;
43910 + uint8_t sgBpid;
43911 + uint8_t hwPortId;
43912 + uint32_t fqidForTimeOutFrames;
43913 + uint32_t timeoutRoutineRequestTime;
43914 + uint32_t bitFor1Micro;
43915 +} t_CapwapFragParams;
43916 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43917 +
43918 +typedef struct
43919 +{
43920 + t_AdOfTypeContLookup *p_Frag;
43921 +#if (DPAA_VERSION == 10)
43922 + uint8_t scratchBpid;
43923 +#endif /* (DPAA_VERSION == 10) */
43924 +} t_FragParams;
43925 +
43926 +typedef struct t_ReassmParams
43927 +{
43928 + e_NetHeaderType hdr; /* Header selection */
43929 + t_ReassCommonTbl *p_ReassCommonTbl;
43930 + uintptr_t reassFrmDescrIndxPoolTblAddr;
43931 + uintptr_t reassFrmDescrPoolTblAddr;
43932 + uintptr_t timeOutTblAddr;
43933 + uintptr_t internalBufferPoolManagementIndexAddr;
43934 + uintptr_t internalBufferPoolAddr;
43935 + uint32_t maxNumFramesInProcess;
43936 + uint8_t sgBpid;
43937 + uint8_t dataMemId;
43938 + uint16_t dataLiodnOffset;
43939 + uint32_t fqidForTimeOutFrames;
43940 + e_FmPcdManipReassemTimeOutMode timeOutMode;
43941 + uint32_t timeoutThresholdForReassmProcess;
43942 + union {
43943 + struct {
43944 + t_Handle h_Ipv4Ad;
43945 + t_Handle h_Ipv6Ad;
43946 + bool ipv6Assigned;
43947 + t_ReassTbl *p_Ipv4ReassTbl;
43948 + t_ReassTbl *p_Ipv6ReassTbl;
43949 + uintptr_t ipv4AutoLearnHashTblAddr;
43950 + uintptr_t ipv6AutoLearnHashTblAddr;
43951 + uintptr_t ipv4AutoLearnSetLockTblAddr;
43952 + uintptr_t ipv6AutoLearnSetLockTblAddr;
43953 + uint16_t minFragSize[2];
43954 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
43955 + uint8_t relativeSchemeId[2];
43956 + t_Handle h_Ipv4Scheme;
43957 + t_Handle h_Ipv6Scheme;
43958 + uint32_t nonConsistentSpFqid;
43959 + } ip;
43960 + struct {
43961 + t_Handle h_Ad;
43962 + t_ReassTbl *p_ReassTbl;
43963 + uintptr_t autoLearnHashTblAddr;
43964 + uintptr_t autoLearnSetLockTblAddr;
43965 + uint16_t maxRessembledsSize;
43966 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
43967 + uint8_t relativeSchemeId;
43968 + t_Handle h_Scheme;
43969 + } capwap;
43970 + };
43971 +} t_ReassmParams;
43972 +
43973 +typedef struct{
43974 + e_FmPcdManipType type;
43975 + t_FmPcdManipParams manipParams;
43976 + bool muramAllocate;
43977 + t_Handle h_Ad;
43978 + uint32_t opcode;
43979 + bool rmv;
43980 + bool insrt;
43981 + t_Handle h_NextManip;
43982 + t_Handle h_PrevManip;
43983 + e_FmPcdManipType nextManipType;
43984 + /* HdrManip parameters*/
43985 + uint8_t *p_Hmct;
43986 + uint8_t *p_Data;
43987 + bool dontParseAfterManip;
43988 + bool fieldUpdate;
43989 + bool custom;
43990 + uint16_t tableSize;
43991 + uint8_t dataSize;
43992 + bool cascaded;
43993 + e_ManipUnifiedPosition unifiedPosition;
43994 + /* end HdrManip */
43995 + uint8_t *p_Template;
43996 + uint16_t owner;
43997 + uint32_t updateParams;
43998 + uint32_t shadowUpdateParams;
43999 + bool frag;
44000 + bool reassm;
44001 + uint16_t sizeForFragmentation;
44002 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44003 + t_Handle h_Frag;
44004 + t_CapwapFragParams capwapFragParams;
44005 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44006 + union {
44007 + t_ReassmParams reassmParams;
44008 + t_FragParams fragParams;
44009 + };
44010 + uint8_t icOffset;
44011 + uint16_t ownerTmp;
44012 + bool cnia;
44013 + t_Handle p_StatsTbl;
44014 + t_Handle h_FmPcd;
44015 + t_List nodesLst;
44016 + t_Handle h_Spinlock;
44017 +} t_FmPcdManip;
44018 +
44019 +typedef struct t_FmPcdCcSavedManipParams
44020 +{
44021 + union
44022 + {
44023 + struct
44024 + {
44025 + uint16_t dataOffset;
44026 + //uint8_t poolId;
44027 + }capwapParams;
44028 + struct
44029 + {
44030 + uint16_t dataOffset;
44031 + uint8_t poolId;
44032 + }ipParams;
44033 + };
44034 +
44035 +} t_FmPcdCcSavedManipParams;
44036 +
44037 +
44038 +#endif /* __FM_MANIP_H */
44039 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
44040 new file mode 100644
44041 index 00000000..91f70a1a
44042 --- /dev/null
44043 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
44044 @@ -0,0 +1,2095 @@
44045 +/*
44046 + * Copyright 2008-2012 Freescale Semiconductor Inc.
44047 + *
44048 + * Redistribution and use in source and binary forms, with or without
44049 + * modification, are permitted provided that the following conditions are met:
44050 + * * Redistributions of source code must retain the above copyright
44051 + * notice, this list of conditions and the following disclaimer.
44052 + * * Redistributions in binary form must reproduce the above copyright
44053 + * notice, this list of conditions and the following disclaimer in the
44054 + * documentation and/or other materials provided with the distribution.
44055 + * * Neither the name of Freescale Semiconductor nor the
44056 + * names of its contributors may be used to endorse or promote products
44057 + * derived from this software without specific prior written permission.
44058 + *
44059 + *
44060 + * ALTERNATIVELY, this software may be distributed under the terms of the
44061 + * GNU General Public License ("GPL") as published by the Free Software
44062 + * Foundation, either version 2 of that License or (at your option) any
44063 + * later version.
44064 + *
44065 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
44066 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44067 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44068 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
44069 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44070 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44071 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44072 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44073 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44074 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44075 + */
44076 +
44077 +
44078 +/******************************************************************************
44079 + @File fm_pcd.c
44080 +
44081 + @Description FM PCD ...
44082 +*//***************************************************************************/
44083 +#include "std_ext.h"
44084 +#include "error_ext.h"
44085 +#include "string_ext.h"
44086 +#include "xx_ext.h"
44087 +#include "sprint_ext.h"
44088 +#include "debug_ext.h"
44089 +#include "net_ext.h"
44090 +#include "fm_ext.h"
44091 +#include "fm_pcd_ext.h"
44092 +
44093 +#include "fm_common.h"
44094 +#include "fm_pcd.h"
44095 +#include "fm_pcd_ipc.h"
44096 +#include "fm_hc.h"
44097 +#include "fm_muram_ext.h"
44098 +
44099 +
44100 +/****************************************/
44101 +/* static functions */
44102 +/****************************************/
44103 +
44104 +static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
44105 +{
44106 + if (!p_FmPcd->h_Fm)
44107 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
44108 +
44109 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
44110 + {
44111 + if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
44112 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
44113 +
44114 + if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
44115 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
44116 +
44117 + if (!p_FmPcd->f_Exception)
44118 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
44119 +
44120 + if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
44121 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
44122 +
44123 + if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
44124 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
44125 + }
44126 +
44127 + return E_OK;
44128 +}
44129 +
44130 +static volatile bool blockingFlag = FALSE;
44131 +static void IpcMsgCompletionCB(t_Handle h_FmPcd,
44132 + uint8_t *p_Msg,
44133 + uint8_t *p_Reply,
44134 + uint32_t replyLength,
44135 + t_Error status)
44136 +{
44137 + UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
44138 + blockingFlag = FALSE;
44139 +}
44140 +
44141 +static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd,
44142 + uint8_t *p_Msg,
44143 + uint32_t msgLength,
44144 + uint8_t *p_Reply,
44145 + uint32_t *p_ReplyLength)
44146 +{
44147 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44148 + t_Error err = E_OK;
44149 + t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg;
44150 + t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
44151 +
44152 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44153 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
44154 +
44155 +#ifdef DISABLE_SANITY_CHECKS
44156 + UNUSED(msgLength);
44157 +#endif /* DISABLE_SANITY_CHECKS */
44158 +
44159 + ASSERT_COND(p_Msg);
44160 +
44161 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
44162 + *p_ReplyLength = 0;
44163 +
44164 + switch (p_IpcMsg->msgId)
44165 + {
44166 + case (FM_PCD_MASTER_IS_ALIVE):
44167 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
44168 + p_IpcReply->error = E_OK;
44169 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44170 + break;
44171 + case (FM_PCD_MASTER_IS_ENABLED):
44172 + /* count partitions registrations */
44173 + if (p_FmPcd->enabled)
44174 + p_FmPcd->numOfEnabledGuestPartitionsPcds++;
44175 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled;
44176 + p_IpcReply->error = E_OK;
44177 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44178 + break;
44179 + case (FM_PCD_GUEST_DISABLE):
44180 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds)
44181 + {
44182 + p_FmPcd->numOfEnabledGuestPartitionsPcds--;
44183 + p_IpcReply->error = E_OK;
44184 + }
44185 + else
44186 + {
44187 + REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
44188 + p_IpcReply->error = E_INVALID_STATE;
44189 + }
44190 + *p_ReplyLength = sizeof(uint32_t);
44191 + break;
44192 + case (FM_PCD_GET_COUNTER):
44193 + {
44194 + e_FmPcdCounters inCounter;
44195 + uint32_t outCounter;
44196 +
44197 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
44198 + outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
44199 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
44200 + p_IpcReply->error = E_OK;
44201 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
44202 + break;
44203 + }
44204 + case (FM_PCD_ALLOC_KG_SCHEMES):
44205 + {
44206 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
44207 +
44208 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
44209 + err = FmPcdKgAllocSchemes(h_FmPcd,
44210 + ipcSchemesParams.numOfSchemes,
44211 + ipcSchemesParams.guestId,
44212 + p_IpcReply->replyBody);
44213 + p_IpcReply->error = err;
44214 + *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
44215 + break;
44216 + }
44217 + case (FM_PCD_FREE_KG_SCHEMES):
44218 + {
44219 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
44220 +
44221 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
44222 + err = FmPcdKgFreeSchemes(h_FmPcd,
44223 + ipcSchemesParams.numOfSchemes,
44224 + ipcSchemesParams.guestId,
44225 + ipcSchemesParams.schemesIds);
44226 + p_IpcReply->error = err;
44227 + *p_ReplyLength = sizeof(uint32_t);
44228 + break;
44229 + }
44230 + case (FM_PCD_ALLOC_KG_CLSPLAN):
44231 + {
44232 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
44233 +
44234 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
44235 + err = KgAllocClsPlanEntries(h_FmPcd,
44236 + ipcKgClsPlanParams.numOfClsPlanEntries,
44237 + ipcKgClsPlanParams.guestId,
44238 + p_IpcReply->replyBody);
44239 + p_IpcReply->error = err;
44240 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44241 + break;
44242 + }
44243 + case (FM_PCD_FREE_KG_CLSPLAN):
44244 + {
44245 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
44246 +
44247 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
44248 + KgFreeClsPlanEntries(h_FmPcd,
44249 + ipcKgClsPlanParams.numOfClsPlanEntries,
44250 + ipcKgClsPlanParams.guestId,
44251 + ipcKgClsPlanParams.clsPlanBase);
44252 + *p_ReplyLength = sizeof(uint32_t);
44253 + break;
44254 + }
44255 + case (FM_PCD_ALLOC_PROFILES):
44256 + {
44257 + t_FmIpcResourceAllocParams ipcAllocParams;
44258 + uint16_t base;
44259 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44260 + base = PlcrAllocProfilesForPartition(h_FmPcd,
44261 + ipcAllocParams.base,
44262 + ipcAllocParams.num,
44263 + ipcAllocParams.guestId);
44264 + memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t));
44265 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
44266 + break;
44267 + }
44268 + case (FM_PCD_FREE_PROFILES):
44269 + {
44270 + t_FmIpcResourceAllocParams ipcAllocParams;
44271 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44272 + PlcrFreeProfilesForPartition(h_FmPcd,
44273 + ipcAllocParams.base,
44274 + ipcAllocParams.num,
44275 + ipcAllocParams.guestId);
44276 + break;
44277 + }
44278 + case (FM_PCD_SET_PORT_PROFILES):
44279 + {
44280 + t_FmIpcResourceAllocParams ipcAllocParams;
44281 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44282 + PlcrSetPortProfiles(h_FmPcd,
44283 + ipcAllocParams.guestId,
44284 + ipcAllocParams.num,
44285 + ipcAllocParams.base);
44286 + break;
44287 + }
44288 + case (FM_PCD_CLEAR_PORT_PROFILES):
44289 + {
44290 + t_FmIpcResourceAllocParams ipcAllocParams;
44291 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44292 + PlcrClearPortProfiles(h_FmPcd,
44293 + ipcAllocParams.guestId);
44294 + break;
44295 + }
44296 + case (FM_PCD_GET_SW_PRS_OFFSET):
44297 + {
44298 + t_FmPcdIpcSwPrsLable ipcSwPrsLable;
44299 + uint32_t swPrsOffset;
44300 +
44301 + memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
44302 + swPrsOffset =
44303 + FmPcdGetSwPrsOffset(h_FmPcd,
44304 + (e_NetHeaderType)ipcSwPrsLable.enumHdr,
44305 + ipcSwPrsLable.indexPerHdr);
44306 + memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
44307 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
44308 + break;
44309 + }
44310 + case (FM_PCD_PRS_INC_PORT_STATS):
44311 + {
44312 + t_FmPcdIpcPrsIncludePort ipcPrsIncludePort;
44313 +
44314 + memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
44315 + PrsIncludePortInStatistics(h_FmPcd,
44316 + ipcPrsIncludePort.hardwarePortId,
44317 + ipcPrsIncludePort.include);
44318 + break;
44319 + }
44320 + default:
44321 + *p_ReplyLength = 0;
44322 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
44323 + }
44324 + return E_OK;
44325 +}
44326 +
44327 +static uint32_t NetEnvLock(t_Handle h_NetEnv)
44328 +{
44329 + ASSERT_COND(h_NetEnv);
44330 + return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock);
44331 +}
44332 +
44333 +static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags)
44334 +{
44335 + ASSERT_COND(h_NetEnv);
44336 + XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags);
44337 +}
44338 +
44339 +static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44340 +{
44341 + uint32_t intFlags;
44342 +
44343 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44344 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst);
44345 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44346 +}
44347 +
44348 +static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd)
44349 +{
44350 + t_FmPcdLock *p_Lock = NULL;
44351 + uint32_t intFlags;
44352 +
44353 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44354 + if (!LIST_IsEmpty(&p_FmPcd->freeLocksLst))
44355 + {
44356 + p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next);
44357 + LIST_DelAndInit(&p_Lock->node);
44358 + }
44359 + if (p_FmPcd->h_Spinlock)
44360 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44361 +
44362 + return p_Lock;
44363 +}
44364 +
44365 +static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44366 +{
44367 + uint32_t intFlags;
44368 +
44369 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44370 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst);
44371 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44372 +}
44373 +
44374 +static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd)
44375 +{
44376 + t_FmPcdLock *p_Lock;
44377 + int i;
44378 +
44379 + for (i=0; i<10; i++)
44380 + {
44381 + p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock));
44382 + if (!p_Lock)
44383 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!"));
44384 + memset(p_Lock, 0, sizeof(t_FmPcdLock));
44385 + INIT_LIST(&p_Lock->node);
44386 + p_Lock->h_Spinlock = XX_InitSpinlock();
44387 + if (!p_Lock->h_Spinlock)
44388 + {
44389 + XX_Free(p_Lock);
44390 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!"));
44391 + }
44392 + EnqueueLockToFreeLst(p_FmPcd, p_Lock);
44393 + }
44394 +
44395 + return E_OK;
44396 +}
44397 +
44398 +static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd)
44399 +{
44400 + t_FmPcdLock *p_Lock;
44401 +
44402 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44403 + while (p_Lock)
44404 + {
44405 + XX_FreeSpinlock(p_Lock->h_Spinlock);
44406 + XX_Free(p_Lock);
44407 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44408 + }
44409 +}
44410 +
44411 +
44412 +
44413 +/*****************************************************************************/
44414 +/* Inter-module API routines */
44415 +/*****************************************************************************/
44416 +
44417 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
44418 +{
44419 + ASSERT_COND(p_FmPcd);
44420 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
44421 +}
44422 +
44423 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
44424 +{
44425 + uint8_t netEnvId = p_GrpParams->netEnvId;
44426 + int i, k, j;
44427 +
44428 + ASSERT_COND(p_FmPcd);
44429 + if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
44430 + {
44431 + p_GrpParams->grpExists = TRUE;
44432 + p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
44433 + return E_OK;
44434 + }
44435 +
44436 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44437 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44438 + {
44439 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44440 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44441 + {
44442 + /* if an option exists, add it to the opts list */
44443 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44444 + {
44445 + /* check if this option already exists, add if it doesn't */
44446 + for (j = 0;j<p_GrpParams->numOfOptions;j++)
44447 + {
44448 + if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44449 + break;
44450 + }
44451 + p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
44452 + if (j == p_GrpParams->numOfOptions)
44453 + {
44454 + p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
44455 + p_GrpParams->numOfOptions++;
44456 + }
44457 + }
44458 + }
44459 + }
44460 +
44461 + if (p_GrpParams->numOfOptions == 0)
44462 + {
44463 + if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
44464 + {
44465 + p_GrpParams->grpExists = TRUE;
44466 + p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
44467 + }
44468 + }
44469 +
44470 + return E_OK;
44471 +
44472 +}
44473 +
44474 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
44475 +{
44476 + uint8_t j,k;
44477 +
44478 + *p_Vector = 0;
44479 +
44480 + ASSERT_COND(p_FmPcd);
44481 + for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44482 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
44483 + {
44484 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44485 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44486 + {
44487 + if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
44488 + *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
44489 + }
44490 + }
44491 +
44492 + if (!*p_Vector)
44493 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
44494 + else
44495 + return E_OK;
44496 +}
44497 +
44498 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
44499 +{
44500 + int i;
44501 +
44502 + ASSERT_COND(p_FmPcd);
44503 + ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS);
44504 +
44505 + p_Params->vector = 0;
44506 + for (i=0; i<p_Params->numOfDistinctionUnits ;i++)
44507 + {
44508 + if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
44509 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
44510 + ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
44511 + p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
44512 + }
44513 +
44514 + return E_OK;
44515 +}
44516 +
44517 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
44518 +{
44519 + int i=0, k;
44520 +
44521 + ASSERT_COND(p_FmPcd);
44522 + /* check whether a given unit may be used by non-clsPlan users. */
44523 + /* first, recognize the unit by its vector */
44524 + while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
44525 + {
44526 + if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
44527 + {
44528 + for (k=0;
44529 + ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44530 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
44531 + k++)
44532 + /* check that no option exists */
44533 + if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44534 + return FALSE;
44535 + break;
44536 + }
44537 + i++;
44538 + }
44539 + /* assert that a unit was found to mach the vector */
44540 + ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
44541 +
44542 + return TRUE;
44543 +}
44544 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44545 +{
44546 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44547 + int i, k;
44548 +
44549 + ASSERT_COND(p_FmPcd);
44550 +
44551 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44552 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44553 + {
44554 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44555 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44556 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
44557 + return TRUE;
44558 + }
44559 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44560 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
44561 + {
44562 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44563 + return TRUE;
44564 + }
44565 +
44566 + return FALSE;
44567 +}
44568 +
44569 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt)
44570 +{
44571 + uint8_t i, k;
44572 +
44573 + ASSERT_COND(p_FmPcd);
44574 +
44575 + if (interchangeable)
44576 + {
44577 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44578 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44579 + {
44580 + for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44581 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
44582 + {
44583 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) &&
44584 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt))
44585 +
44586 + return i;
44587 + }
44588 + }
44589 + }
44590 + else
44591 + {
44592 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44593 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44594 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) &&
44595 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) &&
44596 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE))
44597 + return i;
44598 +
44599 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44600 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44601 + if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) &&
44602 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt))
44603 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44604 + }
44605 +
44606 + return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS;
44607 +}
44608 +
44609 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
44610 +{
44611 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44612 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0};
44613 + uint8_t result;
44614 + t_Error err = E_OK;
44615 +
44616 + ASSERT_COND(p_FmPcd);
44617 + ASSERT_COND(h_ReasmCommonPramTbl);
44618 +
44619 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
44620 + ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/
44621 +
44622 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK)
44623 + RETURN_ERROR(MAJOR, err, NO_MSG);
44624 +
44625 + switch (result)
44626 + {
44627 + case (0):
44628 + return E_OK;
44629 + case (1):
44630 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44631 + case (2):
44632 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44633 + case (3):
44634 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT"));
44635 + default:
44636 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
44637 + }
44638 +
44639 + return E_OK;
44640 +}
44641 +
44642 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44643 +{
44644 + int i;
44645 +
44646 + ASSERT_COND(p_FmPcd);
44647 + ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS);
44648 +
44649 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS)
44650 + && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44651 + {
44652 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44653 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44654 + }
44655 +
44656 + return HEADER_TYPE_NONE;
44657 +}
44658 +
44659 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
44660 +{
44661 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44662 + uint16_t swPortIndex = 0;
44663 +
44664 + ASSERT_COND(h_FmPcd);
44665 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
44666 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
44667 +}
44668 +
44669 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
44670 +{
44671 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44672 +
44673 + ASSERT_COND(h_FmPcd);
44674 + return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
44675 +}
44676 +
44677 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
44678 +{
44679 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44680 +
44681 + ASSERT_COND(h_FmPcd);
44682 + return p_FmPcd->netEnvs[netEnvId].macsecVector;
44683 +}
44684 +
44685 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv)
44686 +{
44687 + return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId;
44688 +}
44689 +
44690 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44691 +{
44692 + uint32_t intFlags;
44693 +
44694 + ASSERT_COND(h_FmPcd);
44695 +
44696 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44697 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
44698 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44699 +}
44700 +
44701 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44702 +{
44703 + uint32_t intFlags;
44704 +
44705 + ASSERT_COND(h_FmPcd);
44706 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
44707 +
44708 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44709 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
44710 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44711 +}
44712 +
44713 +uint32_t FmPcdLock(t_Handle h_FmPcd)
44714 +{
44715 + ASSERT_COND(h_FmPcd);
44716 + return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
44717 +}
44718 +
44719 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
44720 +{
44721 + ASSERT_COND(h_FmPcd);
44722 + XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
44723 +}
44724 +
44725 +t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd)
44726 +{
44727 + t_FmPcdLock *p_Lock;
44728 + ASSERT_COND(h_FmPcd);
44729 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44730 + if (!p_Lock)
44731 + {
44732 + FillFreeLocksLst(h_FmPcd);
44733 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44734 + }
44735 +
44736 + if (p_Lock)
44737 + EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock);
44738 + return p_Lock;
44739 +}
44740 +
44741 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock)
44742 +{
44743 + uint32_t intFlags;
44744 + ASSERT_COND(h_FmPcd);
44745 + intFlags = FmPcdLock(h_FmPcd);
44746 + LIST_DelAndInit(&p_Lock->node);
44747 + FmPcdUnlock(h_FmPcd, intFlags);
44748 + EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock);
44749 +}
44750 +
44751 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd)
44752 +{
44753 + uint32_t intFlags;
44754 + t_List *p_Pos, *p_SavedPos=NULL;
44755 +
44756 + ASSERT_COND(h_FmPcd);
44757 + intFlags = FmPcdLock(h_FmPcd);
44758 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44759 + {
44760 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44761 + if (!FmPcdLockTryLock(p_Lock))
44762 + {
44763 + p_SavedPos = p_Pos;
44764 + break;
44765 + }
44766 + }
44767 + if (p_SavedPos)
44768 + {
44769 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44770 + {
44771 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44772 + if (p_Pos == p_SavedPos)
44773 + break;
44774 + FmPcdLockUnlock(p_Lock);
44775 + }
44776 + }
44777 + FmPcdUnlock(h_FmPcd, intFlags);
44778 +
44779 + CORE_MemoryBarrier();
44780 +
44781 + if (p_SavedPos)
44782 + return FALSE;
44783 +
44784 + return TRUE;
44785 +}
44786 +
44787 +void FmPcdLockUnlockAll(t_Handle h_FmPcd)
44788 +{
44789 + uint32_t intFlags;
44790 + t_List *p_Pos;
44791 +
44792 + ASSERT_COND(h_FmPcd);
44793 + intFlags = FmPcdLock(h_FmPcd);
44794 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44795 + {
44796 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44797 + p_Lock->flag = FALSE;
44798 + }
44799 + FmPcdUnlock(h_FmPcd, intFlags);
44800 +
44801 + CORE_MemoryBarrier();
44802 +}
44803 +
44804 +t_Error FmPcdHcSync(t_Handle h_FmPcd)
44805 +{
44806 + ASSERT_COND(h_FmPcd);
44807 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc);
44808 +
44809 + return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc);
44810 +}
44811 +
44812 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
44813 +{
44814 + ASSERT_COND(h_FmPcd);
44815 + return ((t_FmPcd*)h_FmPcd)->h_Hc;
44816 +}
44817 +
44818 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd)
44819 +{
44820 + ASSERT_COND(h_FmPcd);
44821 + return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport;
44822 +}
44823 +/*********************** End of inter-module routines ************************/
44824 +
44825 +
44826 +/****************************************/
44827 +/* API Init unit functions */
44828 +/****************************************/
44829 +
44830 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
44831 +{
44832 + t_FmPcd *p_FmPcd = NULL;
44833 + t_FmPhysAddr physicalMuramBase;
44834 + uint8_t i;
44835 +
44836 + SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
44837 +
44838 + p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
44839 + if (!p_FmPcd)
44840 + {
44841 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD"));
44842 + return NULL;
44843 + }
44844 + memset(p_FmPcd, 0, sizeof(t_FmPcd));
44845 +
44846 + p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
44847 + if (!p_FmPcd->p_FmPcdDriverParam)
44848 + {
44849 + XX_Free(p_FmPcd);
44850 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param"));
44851 + return NULL;
44852 + }
44853 + memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
44854 +
44855 + p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
44856 + p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
44857 + p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
44858 + if (p_FmPcd->h_FmMuram)
44859 + {
44860 + FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
44861 + p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
44862 + }
44863 +
44864 + for (i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
44865 + p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
44866 +
44867 + if (p_FmPcdParams->useHostCommand)
44868 + {
44869 + t_FmHcParams hcParams;
44870 +
44871 + memset(&hcParams, 0, sizeof(hcParams));
44872 + hcParams.h_Fm = p_FmPcd->h_Fm;
44873 + hcParams.h_FmPcd = (t_Handle)p_FmPcd;
44874 + memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
44875 + p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
44876 + if (!p_FmPcd->h_Hc)
44877 + {
44878 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC"));
44879 + FM_PCD_Free(p_FmPcd);
44880 + return NULL;
44881 + }
44882 + }
44883 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
44884 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
44885 +
44886 + if (p_FmPcdParams->kgSupport)
44887 + {
44888 + p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
44889 + if (!p_FmPcd->p_FmPcdKg)
44890 + {
44891 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen"));
44892 + FM_PCD_Free(p_FmPcd);
44893 + return NULL;
44894 + }
44895 + }
44896 +
44897 + if (p_FmPcdParams->plcrSupport)
44898 + {
44899 + p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
44900 + if (!p_FmPcd->p_FmPcdPlcr)
44901 + {
44902 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer"));
44903 + FM_PCD_Free(p_FmPcd);
44904 + return NULL;
44905 + }
44906 + }
44907 +
44908 + if (p_FmPcdParams->prsSupport)
44909 + {
44910 + p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
44911 + if (!p_FmPcd->p_FmPcdPrs)
44912 + {
44913 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser"));
44914 + FM_PCD_Free(p_FmPcd);
44915 + return NULL;
44916 + }
44917 + }
44918 +
44919 + p_FmPcd->h_Spinlock = XX_InitSpinlock();
44920 + if (!p_FmPcd->h_Spinlock)
44921 + {
44922 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock"));
44923 + FM_PCD_Free(p_FmPcd);
44924 + return NULL;
44925 + }
44926 + INIT_LIST(&p_FmPcd->freeLocksLst);
44927 + INIT_LIST(&p_FmPcd->acquiredLocksLst);
44928 +
44929 + p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
44930 +
44931 + p_FmPcd->f_Exception = p_FmPcdParams->f_Exception;
44932 + p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId;
44933 + p_FmPcd->h_App = p_FmPcdParams->h_App;
44934 +
44935 + p_FmPcd->p_CcShadow = NULL;
44936 + p_FmPcd->ccShadowSize = 0;
44937 + p_FmPcd->ccShadowAlign = 0;
44938 +
44939 + p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock();
44940 + if (!p_FmPcd->h_ShadowSpinlock)
44941 + {
44942 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock"));
44943 + FM_PCD_Free(p_FmPcd);
44944 + return NULL;
44945 + }
44946 +
44947 + return p_FmPcd;
44948 +}
44949 +
44950 +t_Error FM_PCD_Init(t_Handle h_FmPcd)
44951 +{
44952 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44953 + t_Error err = E_OK;
44954 + t_FmPcdIpcMsg msg;
44955 +
44956 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44957 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
44958 +
44959 + FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo);
44960 +
44961 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
44962 + {
44963 + memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44964 + if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
44965 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44966 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44967 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
44968 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44969 +
44970 + p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
44971 + if (p_FmPcd->h_IpcSession)
44972 + {
44973 + t_FmPcdIpcReply reply;
44974 + uint32_t replyLength;
44975 + uint8_t isMasterAlive = 0;
44976 +
44977 + memset(&msg, 0, sizeof(msg));
44978 + memset(&reply, 0, sizeof(reply));
44979 + msg.msgId = FM_PCD_MASTER_IS_ALIVE;
44980 + msg.msgBody[0] = p_FmPcd->guestId;
44981 + blockingFlag = TRUE;
44982 +
44983 + do
44984 + {
44985 + replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
44986 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
44987 + (uint8_t*)&msg,
44988 + sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
44989 + (uint8_t*)&reply,
44990 + &replyLength,
44991 + IpcMsgCompletionCB,
44992 + h_FmPcd)) != E_OK)
44993 + REPORT_ERROR(MAJOR, err, NO_MSG);
44994 + while (blockingFlag) ;
44995 + if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
44996 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
44997 + isMasterAlive = *(uint8_t*)(reply.replyBody);
44998 + } while (!isMasterAlive);
44999 + }
45000 + }
45001 +
45002 + CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
45003 +
45004 + if (p_FmPcd->p_FmPcdKg)
45005 + {
45006 + err = KgInit(p_FmPcd);
45007 + if (err)
45008 + RETURN_ERROR(MAJOR, err, NO_MSG);
45009 + }
45010 +
45011 + if (p_FmPcd->p_FmPcdPlcr)
45012 + {
45013 + err = PlcrInit(p_FmPcd);
45014 + if (err)
45015 + RETURN_ERROR(MAJOR, err, NO_MSG);
45016 + }
45017 +
45018 + if (p_FmPcd->p_FmPcdPrs)
45019 + {
45020 + err = PrsInit(p_FmPcd);
45021 + if (err)
45022 + RETURN_ERROR(MAJOR, err, NO_MSG);
45023 + }
45024 +
45025 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
45026 + {
45027 + /* register to inter-core messaging mechanism */
45028 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
45029 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
45030 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
45031 + err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
45032 + if (err)
45033 + RETURN_ERROR(MAJOR, err, NO_MSG);
45034 + }
45035 +
45036 + /* IPv6 Frame-Id used for fragmentation */
45037 + p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4));
45038 + if (!p_FmPcd->ipv6FrameIdAddr)
45039 + {
45040 + FM_PCD_Free(p_FmPcd);
45041 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id"));
45042 + }
45043 + IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4);
45044 +
45045 + /* CAPWAP Frame-Id used for fragmentation */
45046 + p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4));
45047 + if (!p_FmPcd->capwapFrameIdAddr)
45048 + {
45049 + FM_PCD_Free(p_FmPcd);
45050 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id"));
45051 + }
45052 + IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2);
45053 +
45054 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
45055 + p_FmPcd->p_FmPcdDriverParam = NULL;
45056 +
45057 + FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
45058 +
45059 + return E_OK;
45060 +}
45061 +
45062 +t_Error FM_PCD_Free(t_Handle h_FmPcd)
45063 +{
45064 + t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd;
45065 + t_Error err = E_OK;
45066 +
45067 + if (p_FmPcd->ipv6FrameIdAddr)
45068 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr));
45069 +
45070 + if (p_FmPcd->capwapFrameIdAddr)
45071 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr));
45072 +
45073 + if (p_FmPcd->enabled)
45074 + FM_PCD_Disable(p_FmPcd);
45075 +
45076 + if (p_FmPcd->p_FmPcdDriverParam)
45077 + {
45078 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
45079 + p_FmPcd->p_FmPcdDriverParam = NULL;
45080 + }
45081 +
45082 + if (p_FmPcd->p_FmPcdKg)
45083 + {
45084 + if ((err = KgFree(p_FmPcd)) != E_OK)
45085 + RETURN_ERROR(MINOR, err, NO_MSG);
45086 + XX_Free(p_FmPcd->p_FmPcdKg);
45087 + p_FmPcd->p_FmPcdKg = NULL;
45088 + }
45089 +
45090 + if (p_FmPcd->p_FmPcdPlcr)
45091 + {
45092 + PlcrFree(p_FmPcd);
45093 + XX_Free(p_FmPcd->p_FmPcdPlcr);
45094 + p_FmPcd->p_FmPcdPlcr = NULL;
45095 + }
45096 +
45097 + if (p_FmPcd->p_FmPcdPrs)
45098 + {
45099 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
45100 + PrsFree(p_FmPcd);
45101 + XX_Free(p_FmPcd->p_FmPcdPrs);
45102 + p_FmPcd->p_FmPcdPrs = NULL;
45103 + }
45104 +
45105 + if (p_FmPcd->h_Hc)
45106 + {
45107 + FmHcFree(p_FmPcd->h_Hc);
45108 + p_FmPcd->h_Hc = NULL;
45109 + }
45110 +
45111 + XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
45112 +
45113 + FmUnregisterPcd(p_FmPcd->h_Fm);
45114 +
45115 + ReleaseFreeLocksLst(p_FmPcd);
45116 +
45117 + if (p_FmPcd->h_Spinlock)
45118 + XX_FreeSpinlock(p_FmPcd->h_Spinlock);
45119 +
45120 + if (p_FmPcd->h_ShadowSpinlock)
45121 + XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock);
45122 +
45123 + XX_Free(p_FmPcd);
45124 +
45125 + return E_OK;
45126 +}
45127 +
45128 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
45129 +{
45130 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45131 + uint32_t bitMask = 0;
45132 +
45133 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45134 +
45135 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45136 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
45137 +
45138 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
45139 + if (bitMask)
45140 + {
45141 + if (enable)
45142 + p_FmPcd->exceptions |= bitMask;
45143 + else
45144 + p_FmPcd->exceptions &= ~bitMask;
45145 + }
45146 + else
45147 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
45148 +
45149 + return E_OK;
45150 +}
45151 +
45152 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId)
45153 +{
45154 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45155 +
45156 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45157 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
45158 +
45159 + return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId);
45160 +}
45161 +
45162 +t_Error FM_PCD_Enable(t_Handle h_FmPcd)
45163 +{
45164 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45165 + t_Error err = E_OK;
45166 +
45167 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45168 +
45169 + if (p_FmPcd->enabled)
45170 + return E_OK;
45171 +
45172 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45173 + p_FmPcd->h_IpcSession)
45174 + {
45175 + uint8_t enabled;
45176 + t_FmPcdIpcMsg msg;
45177 + t_FmPcdIpcReply reply;
45178 + uint32_t replyLength;
45179 +
45180 + memset(&reply, 0, sizeof(reply));
45181 + memset(&msg, 0, sizeof(msg));
45182 + msg.msgId = FM_PCD_MASTER_IS_ENABLED;
45183 + replyLength = sizeof(uint32_t) + sizeof(enabled);
45184 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45185 + (uint8_t*)&msg,
45186 + sizeof(msg.msgId),
45187 + (uint8_t*)&reply,
45188 + &replyLength,
45189 + NULL,
45190 + NULL)) != E_OK)
45191 + RETURN_ERROR(MAJOR, err, NO_MSG);
45192 + if (replyLength != sizeof(uint32_t) + sizeof(enabled))
45193 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45194 + p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
45195 + if (!p_FmPcd->enabled)
45196 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
45197 +
45198 + return E_OK;
45199 + }
45200 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
45201 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
45202 + ("running in guest-mode without IPC!"));
45203 +
45204 + if (p_FmPcd->p_FmPcdKg)
45205 + KgEnable(p_FmPcd);
45206 +
45207 + if (p_FmPcd->p_FmPcdPlcr)
45208 + PlcrEnable(p_FmPcd);
45209 +
45210 + if (p_FmPcd->p_FmPcdPrs)
45211 + PrsEnable(p_FmPcd);
45212 +
45213 + p_FmPcd->enabled = TRUE;
45214 +
45215 + return E_OK;
45216 +}
45217 +
45218 +t_Error FM_PCD_Disable(t_Handle h_FmPcd)
45219 +{
45220 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45221 + t_Error err = E_OK;
45222 +
45223 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45224 +
45225 + if (!p_FmPcd->enabled)
45226 + return E_OK;
45227 +
45228 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45229 + p_FmPcd->h_IpcSession)
45230 + {
45231 + t_FmPcdIpcMsg msg;
45232 + t_FmPcdIpcReply reply;
45233 + uint32_t replyLength;
45234 +
45235 + memset(&reply, 0, sizeof(reply));
45236 + memset(&msg, 0, sizeof(msg));
45237 + msg.msgId = FM_PCD_GUEST_DISABLE;
45238 + replyLength = sizeof(uint32_t);
45239 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45240 + (uint8_t*)&msg,
45241 + sizeof(msg.msgId),
45242 + (uint8_t*)&reply,
45243 + &replyLength,
45244 + NULL,
45245 + NULL)) != E_OK)
45246 + RETURN_ERROR(MAJOR, err, NO_MSG);
45247 + if (replyLength != sizeof(uint32_t))
45248 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45249 + if (reply.error == E_OK)
45250 + p_FmPcd->enabled = FALSE;
45251 +
45252 + return (t_Error)(reply.error);
45253 + }
45254 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
45255 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
45256 + ("running in guest-mode without IPC!"));
45257 +
45258 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
45259 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
45260 + ("Trying to disable a master partition PCD while"
45261 + "guest partitions are still enabled!"));
45262 +
45263 + if (p_FmPcd->p_FmPcdKg)
45264 + KgDisable(p_FmPcd);
45265 +
45266 + if (p_FmPcd->p_FmPcdPlcr)
45267 + PlcrDisable(p_FmPcd);
45268 +
45269 + if (p_FmPcd->p_FmPcdPrs)
45270 + PrsDisable(p_FmPcd);
45271 +
45272 + p_FmPcd->enabled = FALSE;
45273 +
45274 + return E_OK;
45275 +}
45276 +
45277 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams)
45278 +{
45279 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45280 + uint32_t intFlags, specialUnits = 0;
45281 + uint8_t bitId = 0;
45282 + uint8_t i, j, k;
45283 + uint8_t netEnvCurrId;
45284 + uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0;
45285 + bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
45286 + uint8_t hdrNum;
45287 + t_FmPcdNetEnvParams *p_ModifiedNetEnvParams;
45288 +
45289 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
45290 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
45291 + SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL);
45292 +
45293 + intFlags = FmPcdLock(p_FmPcd);
45294 +
45295 + /* find a new netEnv */
45296 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
45297 + if (!p_FmPcd->netEnvs[i].used)
45298 + break;
45299 +
45300 + if (i== FM_MAX_NUM_OF_PORTS)
45301 + {
45302 + REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
45303 + FmPcdUnlock(p_FmPcd, intFlags);
45304 + return NULL;
45305 + }
45306 +
45307 + p_FmPcd->netEnvs[i].used = TRUE;
45308 + FmPcdUnlock(p_FmPcd, intFlags);
45309 +
45310 + /* As anyone doesn't have handle of this netEnv yet, no need
45311 + to protect it with spinlocks */
45312 +
45313 + p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams));
45314 + if (!p_ModifiedNetEnvParams)
45315 + {
45316 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams"));
45317 + return NULL;
45318 + }
45319 +
45320 + memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams));
45321 + p_NetEnvParams = p_ModifiedNetEnvParams;
45322 +
45323 + netEnvCurrId = (uint8_t)i;
45324 +
45325 + /* clear from previous use */
45326 + memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
45327 + memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases));
45328 + memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
45329 +
45330 + p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId;
45331 + p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd;
45332 +
45333 + p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45334 +
45335 + /* check that header with opt is not interchanged with the same header */
45336 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45337 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45338 + {
45339 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45340 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45341 + {
45342 + /* if an option exists, check that other headers are not the same header
45343 + without option */
45344 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
45345 + {
45346 + for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45347 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
45348 + {
45349 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
45350 + !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
45351 + {
45352 + REPORT_ERROR(MINOR, E_FULL,
45353 + ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
45354 + XX_Free(p_ModifiedNetEnvParams);
45355 + return NULL;
45356 + }
45357 + }
45358 + }
45359 + }
45360 + }
45361 +
45362 + /* Specific headers checking */
45363 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45364 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45365 + {
45366 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45367 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45368 + {
45369 + /* Some headers pairs may not be defined on different units as the parser
45370 + doesn't distinguish */
45371 + /* IPSEC_AH and IPSEC_SPI can't be 2 units, */
45372 + /* check that header with opt is not interchanged with the same header */
45373 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
45374 + {
45375 + if (ipsecEspExists && (ipsecEspUnit != i))
45376 + {
45377 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45378 + XX_Free(p_ModifiedNetEnvParams);
45379 + return NULL;
45380 + }
45381 + else
45382 + {
45383 + ipsecAhUnit = i;
45384 + ipsecAhExists = TRUE;
45385 + }
45386 + }
45387 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
45388 + {
45389 + if (ipsecAhExists && (ipsecAhUnit != i))
45390 + {
45391 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45392 + XX_Free(p_ModifiedNetEnvParams);
45393 + return NULL;
45394 + }
45395 + else
45396 + {
45397 + ipsecEspUnit = i;
45398 + ipsecEspExists = TRUE;
45399 + }
45400 + }
45401 + /* ENCAP_ESP */
45402 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
45403 + {
45404 + /* IPSec UDP encapsulation is currently set to use SHIM1 */
45405 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
45406 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45407 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45408 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45409 + }
45410 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
45411 + /* UDP_LITE */
45412 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE)
45413 + {
45414 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE;
45415 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP;
45416 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP;
45417 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45418 + }
45419 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
45420 +
45421 + /* IP FRAG */
45422 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) &&
45423 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1))
45424 + {
45425 + /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if
45426 + * IPv4 exists. If so we don't need to set an extra unit
45427 + * We consider as "having IPv4" any IPv4 without interchangable headers
45428 + * but including any options. */
45429 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4;
45430 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1;
45431 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45432 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45433 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45434 +
45435 + /* check if IPv4 header exists by itself */
45436 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45437 + {
45438 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4;
45439 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45440 + }
45441 + }
45442 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) &&
45443 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1))
45444 + {
45445 + /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if
45446 + * IPv4 exists. If so we don't need to set an extra unit
45447 + * We consider as "having IPv6" any IPv6 without interchangable headers
45448 + * but including any options. */
45449 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6;
45450 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1;
45451 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45452 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45453 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45454 +
45455 + /* check if IPv6 header exists by itself */
45456 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45457 + {
45458 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6;
45459 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45460 + }
45461 + }
45462 +#if (DPAA_VERSION >= 11)
45463 + /* CAPWAP FRAG */
45464 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) &&
45465 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1))
45466 + {
45467 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP;
45468 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1;
45469 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45470 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45471 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45472 + }
45473 +#endif /* (DPAA_VERSION >= 11) */
45474 + }
45475 + }
45476 +
45477 + /* if private header (shim), check that no other headers specified */
45478 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45479 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45480 + {
45481 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45482 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
45483 + {
45484 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
45485 + XX_Free(p_ModifiedNetEnvParams);
45486 + return NULL;
45487 + }
45488 + }
45489 +
45490 + for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++)
45491 + {
45492 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45493 + switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
45494 + {
45495 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
45496 + if (shim1Selected)
45497 + {
45498 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
45499 + XX_Free(p_ModifiedNetEnvParams);
45500 + return NULL;
45501 + }
45502 + shim1Selected = TRUE;
45503 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
45504 + break;
45505 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
45506 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
45507 + break;
45508 + default:
45509 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
45510 + }
45511 + else
45512 + {
45513 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
45514 +
45515 + if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45516 + p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45517 + }
45518 + }
45519 +
45520 + /* define a set of hardware parser LCV's according to the defined netenv */
45521 +
45522 + /* set an array of LCV's for each header in the netEnv */
45523 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45524 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45525 + {
45526 + /* private headers have no LCV in the hard parser */
45527 + if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45528 + {
45529 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45530 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45531 + {
45532 + hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
45533 + if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
45534 + {
45535 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
45536 + XX_Free(p_ModifiedNetEnvParams);
45537 + return NULL;
45538 + }
45539 + p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45540 + }
45541 + }
45542 + }
45543 + XX_Free(p_ModifiedNetEnvParams);
45544 +
45545 + p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock();
45546 + if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock)
45547 + {
45548 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock"));
45549 + return NULL;
45550 + }
45551 + return &p_FmPcd->netEnvs[netEnvCurrId];
45552 +}
45553 +
45554 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv)
45555 +{
45556 + t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv;
45557 + t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd;
45558 + uint32_t intFlags;
45559 + uint8_t netEnvId = p_NetEnv->netEnvId;
45560 +
45561 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE);
45562 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45563 +
45564 + /* check that no port is bound to this netEnv */
45565 + if (p_FmPcd->netEnvs[netEnvId].owners)
45566 + {
45567 + RETURN_ERROR(MINOR, E_INVALID_STATE,
45568 + ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
45569 + }
45570 +
45571 + intFlags = FmPcdLock(p_FmPcd);
45572 +
45573 + p_FmPcd->netEnvs[netEnvId].used = FALSE;
45574 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45575 +
45576 + memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45577 + memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45578 + memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
45579 +
45580 + if (p_FmPcd->netEnvs[netEnvId].h_Spinlock)
45581 + XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock);
45582 +
45583 + FmPcdUnlock(p_FmPcd, intFlags);
45584 + return E_OK;
45585 +}
45586 +
45587 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
45588 +{
45589 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45590 +
45591 + SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
45592 +
45593 + FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
45594 +}
45595 +
45596 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd)
45597 +{
45598 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45599 + t_FmCtrlCodeRevisionInfo revInfo;
45600 + t_Error err;
45601 +
45602 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45603 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45604 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE);
45605 +
45606 + if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK)
45607 + {
45608 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
45609 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
45610 + }
45611 + if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
45612 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
45613 +
45614 + if (!p_FmPcd->h_Hc)
45615 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode"));
45616 +
45617 + p_FmPcd->advancedOffloadSupport = TRUE;
45618 +
45619 + return E_OK;
45620 +}
45621 +
45622 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
45623 +{
45624 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45625 + uint32_t outCounter = 0;
45626 + t_Error err;
45627 +
45628 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
45629 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
45630 +
45631 + switch (counter)
45632 + {
45633 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45634 + if (!p_FmPcd->p_FmPcdKg)
45635 + {
45636 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated"));
45637 + return 0;
45638 + }
45639 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45640 + !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs &&
45641 + !p_FmPcd->h_IpcSession)
45642 + {
45643 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45644 + ("running in guest-mode without neither IPC nor mapped register!"));
45645 + return 0;
45646 + }
45647 + break;
45648 +
45649 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45650 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45651 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45652 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45653 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45654 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45655 + if (!p_FmPcd->p_FmPcdPlcr)
45656 + {
45657 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated"));
45658 + return 0;
45659 + }
45660 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45661 + !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45662 + !p_FmPcd->h_IpcSession)
45663 + {
45664 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45665 + ("running in \"guest-mode\" without neither IPC nor mapped register!"));
45666 + return 0;
45667 + }
45668 +
45669 + /* check that counters are enabled */
45670 + if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45671 + !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
45672 + {
45673 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
45674 + return 0;
45675 + }
45676 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs ||
45677 + ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession));
45678 + break;
45679 +
45680 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45681 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45682 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45683 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45684 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45685 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45686 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45687 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45688 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45689 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45690 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45691 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45692 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45693 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45694 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45695 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45696 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45697 + if (!p_FmPcd->p_FmPcdPrs)
45698 + {
45699 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated"));
45700 + return 0;
45701 + }
45702 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45703 + !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs &&
45704 + !p_FmPcd->h_IpcSession)
45705 + {
45706 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45707 + ("running in guest-mode without neither IPC nor mapped register!"));
45708 + return 0;
45709 + }
45710 + break;
45711 + default:
45712 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
45713 + return 0;
45714 + }
45715 +
45716 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45717 + p_FmPcd->h_IpcSession)
45718 + {
45719 + t_FmPcdIpcMsg msg;
45720 + t_FmPcdIpcReply reply;
45721 + uint32_t replyLength;
45722 +
45723 + memset(&msg, 0, sizeof(msg));
45724 + memset(&reply, 0, sizeof(reply));
45725 + msg.msgId = FM_PCD_GET_COUNTER;
45726 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
45727 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
45728 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45729 + (uint8_t*)&msg,
45730 + sizeof(msg.msgId) +sizeof(uint32_t),
45731 + (uint8_t*)&reply,
45732 + &replyLength,
45733 + NULL,
45734 + NULL)) != E_OK)
45735 + RETURN_ERROR(MAJOR, err, NO_MSG);
45736 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
45737 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45738 +
45739 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
45740 + return outCounter;
45741 + }
45742 +
45743 + switch (counter)
45744 + {
45745 + /* Parser statistics */
45746 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45747 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds);
45748 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45749 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs);
45750 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45751 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs);
45752 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45753 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs);
45754 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45755 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs);
45756 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45757 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres);
45758 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45759 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres);
45760 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45761 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres);
45762 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45763 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres);
45764 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45765 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs);
45766 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45767 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs);
45768 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45769 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs);
45770 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45771 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs);
45772 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45773 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs);
45774 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45775 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs);
45776 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45777 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs);
45778 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45779 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs);
45780 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45781 + return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc);
45782 +
45783 + /* Policer statistics */
45784 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45785 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
45786 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45787 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
45788 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45789 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
45790 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45791 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
45792 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45793 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
45794 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45795 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
45796 + }
45797 + return 0;
45798 +}
45799 +
45800 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
45801 +{
45802 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45803 + uint32_t bitMask = 0, tmpReg;
45804 +
45805 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45806 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45807 +
45808 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45809 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
45810 +
45811 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
45812 +
45813 + if (bitMask)
45814 + {
45815 + if (enable)
45816 + p_FmPcd->exceptions |= bitMask;
45817 + else
45818 + p_FmPcd->exceptions &= ~bitMask;
45819 +
45820 + switch (exception)
45821 + {
45822 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45823 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45824 + if (!p_FmPcd->p_FmPcdKg)
45825 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45826 + break;
45827 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45828 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45829 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45830 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45831 + if (!p_FmPcd->p_FmPcdPlcr)
45832 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45833 + break;
45834 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45835 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45836 + if (!p_FmPcd->p_FmPcdPrs)
45837 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
45838 + break;
45839 + }
45840 +
45841 + switch (exception)
45842 + {
45843 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45844 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45845 + if (enable)
45846 + tmpReg |= FM_EX_KG_DOUBLE_ECC;
45847 + else
45848 + tmpReg &= ~FM_EX_KG_DOUBLE_ECC;
45849 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45850 + break;
45851 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45852 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45853 + if (enable)
45854 + tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW;
45855 + else
45856 + tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW;
45857 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45858 + break;
45859 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45860 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer);
45861 + if (enable)
45862 + tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
45863 + else
45864 + tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
45865 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg);
45866 + break;
45867 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45868 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever);
45869 + if (enable)
45870 + tmpReg |= FM_PCD_PRS_SINGLE_ECC;
45871 + else
45872 + tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
45873 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg);
45874 + break;
45875 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45876 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45877 + if (enable)
45878 + tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
45879 + else
45880 + tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
45881 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45882 + break;
45883 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45884 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45885 + if (enable)
45886 + tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
45887 + else
45888 + tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
45889 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45890 + break;
45891 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45892 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45893 + if (enable)
45894 + tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45895 + else
45896 + tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45897 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45898 + break;
45899 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45900 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45901 + if (enable)
45902 + tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45903 + else
45904 + tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45905 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45906 + break;
45907 + }
45908 + /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
45909 + Driver may disable them automatically, depending on driver's status */
45910 + if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45911 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45912 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45913 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45914 + FmEnableRamsEcc(p_FmPcd->h_Fm);
45915 + if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45916 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45917 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45918 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45919 + FmDisableRamsEcc(p_FmPcd->h_Fm);
45920 + }
45921 +
45922 + return E_OK;
45923 +}
45924 +
45925 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
45926 +{
45927 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45928 +
45929 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45930 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45931 +
45932 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45933 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
45934 +
45935 + switch (exception)
45936 + {
45937 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45938 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45939 + if (!p_FmPcd->p_FmPcdKg)
45940 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45941 + break;
45942 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45943 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45944 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45945 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45946 + if (!p_FmPcd->p_FmPcdPlcr)
45947 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45948 + break;
45949 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45950 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45951 + if (!p_FmPcd->p_FmPcdPrs)
45952 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
45953 + break;
45954 + default:
45955 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested"));
45956 + }
45957 + switch (exception)
45958 + {
45959 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
45960 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
45961 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45962 + break;
45963 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
45964 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
45965 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45966 + break;
45967 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
45968 + if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC))
45969 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45970 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC);
45971 + break;
45972 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
45973 + if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW))
45974 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45975 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW);
45976 + break;
45977 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
45978 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
45979 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45980 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
45981 + break;
45982 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
45983 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
45984 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45985 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
45986 + break;
45987 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
45988 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
45989 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45990 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
45991 + break;
45992 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
45993 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
45994 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45995 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
45996 + break;
45997 + }
45998 +
45999 + return E_OK;
46000 +}
46001 +
46002 +
46003 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
46004 +{
46005 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46006 +
46007 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
46008 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
46009 +
46010 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
46011 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
46012 +
46013 + switch (counter)
46014 + {
46015 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
46016 + if (!p_FmPcd->p_FmPcdKg)
46017 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working"));
46018 + break;
46019 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
46020 + case (e_FM_PCD_PLCR_COUNTERS_RED):
46021 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
46022 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
46023 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
46024 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
46025 + if (!p_FmPcd->p_FmPcdPlcr)
46026 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working"));
46027 + if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
46028 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
46029 + break;
46030 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
46031 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
46032 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
46033 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
46034 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
46035 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
46036 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
46037 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
46038 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
46039 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
46040 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
46041 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
46042 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
46043 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
46044 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
46045 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
46046 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
46047 + if (!p_FmPcd->p_FmPcdPrs)
46048 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
46049 + break;
46050 + default:
46051 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
46052 + }
46053 + switch (counter)
46054 + {
46055 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
46056 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value);
46057 + break;
46058 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
46059 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value);
46060 + break;
46061 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
46062 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value);
46063 + break;
46064 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
46065 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value);
46066 + break;
46067 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
46068 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value);
46069 + break;
46070 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
46071 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value);
46072 + break;
46073 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
46074 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value);
46075 + break;
46076 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
46077 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value);
46078 + break;
46079 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
46080 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value);
46081 + break;
46082 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
46083 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value);
46084 + break;
46085 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
46086 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value);
46087 + break;
46088 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
46089 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value);
46090 + break;
46091 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
46092 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value);
46093 + break;
46094 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
46095 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value);
46096 + break;
46097 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
46098 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value);
46099 + break;
46100 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
46101 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value);
46102 + break;
46103 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
46104 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value);
46105 + break;
46106 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
46107 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value);
46108 + break;
46109 +
46110 + /*Policer counters*/
46111 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
46112 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
46113 + break;
46114 + case (e_FM_PCD_PLCR_COUNTERS_RED):
46115 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
46116 + break;
46117 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
46118 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
46119 + break;
46120 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
46121 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
46122 + break;
46123 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
46124 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
46125 + break;
46126 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
46127 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
46128 + break;
46129 + }
46130 +
46131 + return E_OK;
46132 +}
46133 +
46134 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd)
46135 +{
46136 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46137 + return FmHcGetPort(p_FmPcd->h_Hc);
46138 +}
46139 +
46140 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
46141 new file mode 100644
46142 index 00000000..27ec9c5b
46143 --- /dev/null
46144 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
46145 @@ -0,0 +1,543 @@
46146 +/*
46147 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46148 + *
46149 + * Redistribution and use in source and binary forms, with or without
46150 + * modification, are permitted provided that the following conditions are met:
46151 + * * Redistributions of source code must retain the above copyright
46152 + * notice, this list of conditions and the following disclaimer.
46153 + * * Redistributions in binary form must reproduce the above copyright
46154 + * notice, this list of conditions and the following disclaimer in the
46155 + * documentation and/or other materials provided with the distribution.
46156 + * * Neither the name of Freescale Semiconductor nor the
46157 + * names of its contributors may be used to endorse or promote products
46158 + * derived from this software without specific prior written permission.
46159 + *
46160 + *
46161 + * ALTERNATIVELY, this software may be distributed under the terms of the
46162 + * GNU General Public License ("GPL") as published by the Free Software
46163 + * Foundation, either version 2 of that License or (at your option) any
46164 + * later version.
46165 + *
46166 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46167 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46168 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46169 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46170 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46171 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46172 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46173 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46174 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46175 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46176 + */
46177 +
46178 +
46179 +/******************************************************************************
46180 + @File fm_pcd.h
46181 +
46182 + @Description FM PCD ...
46183 +*//***************************************************************************/
46184 +#ifndef __FM_PCD_H
46185 +#define __FM_PCD_H
46186 +
46187 +#include "std_ext.h"
46188 +#include "error_ext.h"
46189 +#include "list_ext.h"
46190 +#include "fm_pcd_ext.h"
46191 +#include "fm_common.h"
46192 +#include "fsl_fman_prs.h"
46193 +#include "fsl_fman_kg.h"
46194 +
46195 +#define __ERR_MODULE__ MODULE_FM_PCD
46196 +
46197 +
46198 +/****************************/
46199 +/* Defaults */
46200 +/****************************/
46201 +#define DEFAULT_plcrAutoRefresh FALSE
46202 +#define DEFAULT_fmPcdKgErrorExceptions (FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW)
46203 +#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
46204 +#define DEFAULT_fmPcdPlcrExceptions 0
46205 +#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC)
46206 +
46207 +#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC
46208 +#define DEFAULT_numOfUsedProfilesPerWindow 16
46209 +#define DEFAULT_numOfSharedPlcrProfiles 4
46210 +
46211 +/****************************/
46212 +/* Network defines */
46213 +/****************************/
46214 +#define UDP_HEADER_SIZE 8
46215 +
46216 +#define ESP_SPI_OFFSET 0
46217 +#define ESP_SPI_SIZE 4
46218 +#define ESP_SEQ_NUM_OFFSET ESP_SPI_SIZE
46219 +#define ESP_SEQ_NUM_SIZE 4
46220 +
46221 +/****************************/
46222 +/* General defines */
46223 +/****************************/
46224 +#define ILLEGAL_CLS_PLAN 0xff
46225 +#define ILLEGAL_NETENV 0xff
46226 +
46227 +#define FM_PCD_MAX_NUM_OF_ALIAS_HDRS 3
46228 +
46229 +/****************************/
46230 +/* Error defines */
46231 +/****************************/
46232 +
46233 +#define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000
46234 +#define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000
46235 +#define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000
46236 +#define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000
46237 +
46238 +#define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \
46239 +switch (exception){ \
46240 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \
46241 + bitMask = FM_EX_KG_DOUBLE_ECC; break; \
46242 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \
46243 + bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \
46244 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \
46245 + bitMask = FM_EX_KG_KEYSIZE_OVERFLOW; break; \
46246 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \
46247 + bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \
46248 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \
46249 + bitMask = FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE; break; \
46250 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: \
46251 + bitMask = FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE; break; \
46252 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: \
46253 + bitMask = FM_PCD_EX_PRS_DOUBLE_ECC; break; \
46254 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: \
46255 + bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \
46256 + default: bitMask = 0;break;}
46257 +
46258 +/***********************************************************************/
46259 +/* Policer defines */
46260 +/***********************************************************************/
46261 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
46262 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
46263 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
46264 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
46265 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
46266 +
46267 +/***********************************************************************/
46268 +/* Memory map */
46269 +/***********************************************************************/
46270 +#if defined(__MWERKS__) && !defined(__GNUC__)
46271 +#pragma pack(push,1)
46272 +#endif /* defined(__MWERKS__) && ... */
46273 +
46274 +
46275 +typedef struct {
46276 +/* General Configuration and Status Registers */
46277 + volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */
46278 + volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */
46279 + volatile uint32_t fmpl_evr; /* 0x008 FMPL_EVR - FM Policer Event Register */
46280 + volatile uint32_t fmpl_ier; /* 0x00C FMPL_IER - FM Policer Interrupt Enable Register */
46281 + volatile uint32_t fmpl_ifr; /* 0x010 FMPL_IFR - FM Policer Interrupt Force Register */
46282 + volatile uint32_t fmpl_eevr; /* 0x014 FMPL_EEVR - FM Policer Error Event Register */
46283 + volatile uint32_t fmpl_eier; /* 0x018 FMPL_EIER - FM Policer Error Interrupt Enable Register */
46284 + volatile uint32_t fmpl_eifr; /* 0x01C FMPL_EIFR - FM Policer Error Interrupt Force Register */
46285 +/* Global Statistic Counters */
46286 + volatile uint32_t fmpl_rpcnt; /* 0x020 FMPL_RPC - FM Policer RED Packets Counter */
46287 + volatile uint32_t fmpl_ypcnt; /* 0x024 FMPL_YPC - FM Policer YELLOW Packets Counter */
46288 + volatile uint32_t fmpl_rrpcnt; /* 0x028 FMPL_RRPC - FM Policer Recolored RED Packet Counter */
46289 + volatile uint32_t fmpl_rypcnt; /* 0x02C FMPL_RYPC - FM Policer Recolored YELLOW Packet Counter */
46290 + volatile uint32_t fmpl_tpcnt; /* 0x030 FMPL_TPC - FM Policer Total Packet Counter */
46291 + volatile uint32_t fmpl_flmcnt; /* 0x034 FMPL_FLMC - FM Policer Frame Length Mismatch Counter */
46292 + volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */
46293 +/* Profile RAM Access Registers */
46294 + volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/
46295 + t_FmPcdPlcrProfileRegs profileRegs;
46296 +/* Error Capture Registers */
46297 + volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */
46298 + volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */
46299 + volatile uint32_t fmpl_res2; /* 0x108 Reserved */
46300 +/* Debug Registers */
46301 + volatile uint32_t fmpl_res3[61]; /* 0x10C-0x200 Reserved Debug*/
46302 +/* Profile Selection Mapping Registers Per Port-ID (n=1-11, 16) */
46303 + volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */
46304 + volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers.
46305 + (for port-ID 1-11, only for supported Port-ID registers) */
46306 +} t_FmPcdPlcrRegs;
46307 +
46308 +#if defined(__MWERKS__) && !defined(__GNUC__)
46309 +#pragma pack(pop)
46310 +#endif /* defined(__MWERKS__) && ... */
46311 +
46312 +
46313 +/***********************************************************************/
46314 +/* Driver's internal structures */
46315 +/***********************************************************************/
46316 +
46317 +typedef struct {
46318 + bool known;
46319 + uint8_t id;
46320 +} t_FmPcdKgSchemesExtractsEntry;
46321 +
46322 +typedef struct {
46323 + t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
46324 +} t_FmPcdKgSchemesExtracts;
46325 +
46326 +typedef struct {
46327 + t_Handle h_Manip;
46328 + bool keepRes;
46329 + e_FmPcdEngine nextEngine;
46330 + uint8_t parseCode;
46331 +} t_FmPcdInfoForManip;
46332 +
46333 +/**************************************************************************//**
46334 + @Description A structure of parameters to communicate
46335 + between the port and PCD regarding the KG scheme.
46336 +*//***************************************************************************/
46337 +typedef struct {
46338 + uint8_t netEnvId; /* in */
46339 + uint8_t numOfDistinctionUnits; /* in */
46340 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */
46341 + uint32_t vector; /* out */
46342 +} t_NetEnvParams;
46343 +
46344 +typedef struct {
46345 + bool allocated;
46346 + uint8_t ownerId; /* guestId for KG in multi-partition only.
46347 + portId for PLCR in any environment */
46348 +} t_FmPcdAllocMng;
46349 +
46350 +typedef struct {
46351 + volatile bool lock;
46352 + bool used;
46353 + uint8_t owners;
46354 + uint8_t netEnvId;
46355 + uint8_t guestId;
46356 + uint8_t baseEntry;
46357 + uint16_t sizeOfGrp;
46358 + protocolOpt_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
46359 +} t_FmPcdKgClsPlanGrp;
46360 +
46361 +typedef struct {
46362 + t_Handle h_FmPcd;
46363 + uint8_t schemeId;
46364 + t_FmPcdLock *p_Lock;
46365 + bool valid;
46366 + uint8_t netEnvId;
46367 + uint8_t owners;
46368 + uint32_t matchVector;
46369 + uint32_t ccUnits;
46370 + bool nextRelativePlcrProfile;
46371 + uint16_t relativeProfileId;
46372 + uint16_t numOfProfiles;
46373 + t_FmPcdKgKeyOrder orderedArray;
46374 + e_FmPcdEngine nextEngine;
46375 + e_FmPcdDoneAction doneAction;
46376 + bool requiredActionFlag;
46377 + uint32_t requiredAction;
46378 + bool extractedOrs;
46379 + uint8_t bitOffsetInPlcrProfile;
46380 + bool directPlcr;
46381 +#if (DPAA_VERSION >= 11)
46382 + bool vspe;
46383 +#endif
46384 +} t_FmPcdKgScheme;
46385 +
46386 +typedef union {
46387 + struct fman_kg_scheme_regs schemeRegs;
46388 + struct fman_kg_pe_regs portRegs;
46389 + struct fman_kg_cp_regs clsPlanRegs;
46390 +} u_FmPcdKgIndirectAccessRegs;
46391 +
46392 +typedef struct {
46393 + struct fman_kg_regs *p_FmPcdKgRegs;
46394 + uint32_t schemeExceptionsBitMask;
46395 + uint8_t numOfSchemes;
46396 + t_Handle h_HwSpinlock;
46397 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46398 + t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES];
46399 + t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS];
46400 + uint8_t emptyClsPlanGrpId;
46401 + t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */
46402 + t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP];
46403 + u_FmPcdKgIndirectAccessRegs *p_IndirectAccessRegs;
46404 +} t_FmPcdKg;
46405 +
46406 +typedef struct {
46407 + uint16_t profilesBase;
46408 + uint16_t numOfProfiles;
46409 + t_Handle h_FmPort;
46410 +} t_FmPcdPlcrMapParam;
46411 +
46412 +typedef struct {
46413 + uint16_t absoluteProfileId;
46414 + t_Handle h_FmPcd;
46415 + bool valid;
46416 + t_FmPcdLock *p_Lock;
46417 + t_FmPcdAllocMng profilesMng;
46418 + bool requiredActionFlag;
46419 + uint32_t requiredAction;
46420 + e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */
46421 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */
46422 +
46423 + e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */
46424 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */
46425 +
46426 + e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */
46427 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */
46428 +} t_FmPcdPlcrProfile;
46429 +
46430 +typedef struct {
46431 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
46432 + uint16_t partPlcrProfilesBase;
46433 + uint16_t partNumOfPlcrProfiles;
46434 + t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES];
46435 + uint16_t numOfSharedProfiles;
46436 + uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES];
46437 + t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
46438 + t_Handle h_HwSpinlock;
46439 + t_Handle h_SwSpinlock;
46440 +} t_FmPcdPlcr;
46441 +
46442 +typedef struct {
46443 + uint32_t *p_SwPrsCode;
46444 + uint32_t *p_CurrSwPrs;
46445 + uint8_t currLabel;
46446 + struct fman_prs_regs *p_FmPcdPrsRegs;
46447 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
46448 + uint32_t fmPcdPrsPortIdStatistics;
46449 +} t_FmPcdPrs;
46450 +
46451 +typedef struct {
46452 + struct {
46453 + e_NetHeaderType hdr;
46454 + protocolOpt_t opt; /* only one option !! */
46455 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
46456 +} t_FmPcdIntDistinctionUnit;
46457 +
46458 +typedef struct {
46459 + e_NetHeaderType hdr;
46460 + protocolOpt_t opt; /* only one option !! */
46461 + e_NetHeaderType aliasHdr;
46462 +} t_FmPcdNetEnvAliases;
46463 +
46464 +typedef struct {
46465 + uint8_t netEnvId;
46466 + t_Handle h_FmPcd;
46467 + t_Handle h_Spinlock;
46468 + bool used;
46469 + uint8_t owners;
46470 + uint8_t clsPlanGrpId;
46471 + t_FmPcdIntDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46472 + uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46473 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
46474 + uint32_t macsecVector;
46475 + t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_ALIAS_HDRS];
46476 +} t_FmPcdNetEnv;
46477 +
46478 +typedef struct {
46479 + struct fman_prs_cfg dfltCfg;
46480 + bool plcrAutoRefresh;
46481 + uint16_t prsMaxParseCycleLimit;
46482 +} t_FmPcdDriverParam;
46483 +
46484 +typedef struct {
46485 + t_Handle h_Fm;
46486 + t_Handle h_FmMuram;
46487 + t_FmRevisionInfo fmRevInfo;
46488 +
46489 + uint64_t physicalMuramBase;
46490 +
46491 + t_Handle h_Spinlock;
46492 + t_List freeLocksLst;
46493 + t_List acquiredLocksLst;
46494 +
46495 + t_Handle h_IpcSession; /* relevant for guest only */
46496 + bool enabled;
46497 + uint8_t guestId; /**< Guest Partition Id */
46498 + uint8_t numOfEnabledGuestPartitionsPcds;
46499 + char fmPcdModuleName[MODULE_NAME_SIZE];
46500 + char fmPcdIpcHandlerModuleName[MODULE_NAME_SIZE]; /* relevant for guest only - this is the master's name */
46501 + t_FmPcdNetEnv netEnvs[FM_MAX_NUM_OF_PORTS];
46502 + t_FmPcdKg *p_FmPcdKg;
46503 + t_FmPcdPlcr *p_FmPcdPlcr;
46504 + t_FmPcdPrs *p_FmPcdPrs;
46505 +
46506 + void *p_CcShadow; /**< CC MURAM shadow */
46507 + uint32_t ccShadowSize;
46508 + uint32_t ccShadowAlign;
46509 + volatile bool shadowLock;
46510 + t_Handle h_ShadowSpinlock;
46511 +
46512 + t_Handle h_Hc;
46513 +
46514 + uint32_t exceptions;
46515 + t_FmPcdExceptionCallback *f_Exception;
46516 + t_FmPcdIdExceptionCallback *f_FmPcdIndexedException;
46517 + t_Handle h_App;
46518 + uintptr_t ipv6FrameIdAddr;
46519 + uintptr_t capwapFrameIdAddr;
46520 + bool advancedOffloadSupport;
46521 +
46522 + t_FmPcdDriverParam *p_FmPcdDriverParam;
46523 +} t_FmPcd;
46524 +
46525 +#if (DPAA_VERSION >= 11)
46526 +typedef uint8_t t_FmPcdFrmReplicUpdateType;
46527 +#define FRM_REPLIC_UPDATE_COUNTER 0x01
46528 +#define FRM_REPLIC_UPDATE_INFO 0x02
46529 +#endif /* (DPAA_VERSION >= 11) */
46530 +/***********************************************************************/
46531 +/* PCD internal routines */
46532 +/***********************************************************************/
46533 +
46534 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector);
46535 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params);
46536 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector);
46537 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams);
46538 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId);
46539 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46540 +uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46541 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt);
46542 +
46543 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, bool isIpv4, uint8_t groupId);
46544 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip);
46545 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, uint8_t groupId);
46546 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip);
46547 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip);
46548 +
46549 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46550 +t_Error KgInit(t_FmPcd *p_FmPcd);
46551 +t_Error KgFree(t_FmPcd *p_FmPcd);
46552 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set);
46553 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId);
46554 +void KgEnable(t_FmPcd *p_FmPcd);
46555 +void KgDisable(t_FmPcd *p_FmPcd);
46556 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First);
46557 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base);
46558 +
46559 +/* only for MULTI partittion */
46560 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46561 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46562 +/* only for SINGLE partittion */
46563 +t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg);
46564 +
46565 +t_FmPcdLock *FmPcdAcquireLock(t_Handle h_FmPcd);
46566 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock);
46567 +
46568 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46569 +t_Error PlcrInit(t_FmPcd *p_FmPcd);
46570 +t_Error PlcrFree(t_FmPcd *p_FmPcd);
46571 +void PlcrEnable(t_FmPcd *p_FmPcd);
46572 +void PlcrDisable(t_FmPcd *p_FmPcd);
46573 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46574 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46575 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
46576 + uint8_t hardwarePortId,
46577 + uint16_t numOfProfiles,
46578 + uint16_t base);
46579 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId);
46580 +
46581 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams);
46582 +t_Error PrsInit(t_FmPcd *p_FmPcd);
46583 +void PrsEnable(t_FmPcd *p_FmPcd);
46584 +void PrsDisable(t_FmPcd *p_FmPcd);
46585 +void PrsFree(t_FmPcd *p_FmPcd );
46586 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include);
46587 +
46588 +t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase);
46589 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
46590 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
46591 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode);
46592 +t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, e_FmPcdCcStatsMode supportedStatsMode);
46593 +
46594 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46595 +t_Error FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction);
46596 +void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip,
46597 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
46598 + t_Handle p_Ad,
46599 + t_Handle *p_AdNewPtr);
46600 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset);
46601 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46602 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode);
46603 +#ifdef FM_CAPWAP_SUPPORT
46604 +t_Handle FmPcdManipApplSpecificBuild(void);
46605 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip);
46606 +#endif /* FM_CAPWAP_SUPPORT */
46607 +#if (DPAA_VERSION >= 11)
46608 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup);
46609 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, bool add);
46610 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, void *p_Ad, t_Handle *h_AdNew);
46611 +
46612 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
46613 + t_Handle h_ReplicGroup,
46614 + t_List *p_AdTables,
46615 + uint32_t *p_NumOfAdTables);
46616 +#endif /* (DPAA_VERSION >= 11) */
46617 +
46618 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, t_Handle h_Spinlock);
46619 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46620 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46621 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip);
46622 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip);
46623 +
46624 +typedef struct
46625 +{
46626 + t_Handle h_StatsAd;
46627 + t_Handle h_StatsCounters;
46628 +#if (DPAA_VERSION >= 11)
46629 + t_Handle h_StatsFLRs;
46630 +#endif /* (DPAA_VERSION >= 11) */
46631 +} t_FmPcdCcStatsParams;
46632 +
46633 +void NextStepAd(t_Handle h_Ad,
46634 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
46635 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
46636 + t_FmPcd *p_FmPcd);
46637 +void ReleaseLst(t_List *p_List);
46638 +
46639 +static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd)
46640 +{
46641 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46642 + ASSERT_COND(p_FmPcd);
46643 + return p_FmPcd->h_FmMuram;
46644 +}
46645 +
46646 +static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd)
46647 +{
46648 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46649 + ASSERT_COND(p_FmPcd);
46650 + return p_FmPcd->physicalMuramBase;
46651 +}
46652 +
46653 +static __inline__ uint32_t FmPcdLockSpinlock(t_FmPcdLock *p_Lock)
46654 +{
46655 + ASSERT_COND(p_Lock);
46656 + return XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46657 +}
46658 +
46659 +static __inline__ void FmPcdUnlockSpinlock(t_FmPcdLock *p_Lock, uint32_t flags)
46660 +{
46661 + ASSERT_COND(p_Lock);
46662 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, flags);
46663 +}
46664 +
46665 +static __inline__ bool FmPcdLockTryLock(t_FmPcdLock *p_Lock)
46666 +{
46667 + uint32_t intFlags;
46668 +
46669 + ASSERT_COND(p_Lock);
46670 + intFlags = XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46671 + if (p_Lock->flag)
46672 + {
46673 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46674 + return FALSE;
46675 + }
46676 + p_Lock->flag = TRUE;
46677 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46678 + return TRUE;
46679 +}
46680 +
46681 +static __inline__ void FmPcdLockUnlock(t_FmPcdLock *p_Lock)
46682 +{
46683 + ASSERT_COND(p_Lock);
46684 + p_Lock->flag = FALSE;
46685 +}
46686 +
46687 +
46688 +#endif /* __FM_PCD_H */
46689 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
46690 new file mode 100644
46691 index 00000000..325d3e33
46692 --- /dev/null
46693 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
46694 @@ -0,0 +1,280 @@
46695 +/*
46696 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46697 + *
46698 + * Redistribution and use in source and binary forms, with or without
46699 + * modification, are permitted provided that the following conditions are met:
46700 + * * Redistributions of source code must retain the above copyright
46701 + * notice, this list of conditions and the following disclaimer.
46702 + * * Redistributions in binary form must reproduce the above copyright
46703 + * notice, this list of conditions and the following disclaimer in the
46704 + * documentation and/or other materials provided with the distribution.
46705 + * * Neither the name of Freescale Semiconductor nor the
46706 + * names of its contributors may be used to endorse or promote products
46707 + * derived from this software without specific prior written permission.
46708 + *
46709 + *
46710 + * ALTERNATIVELY, this software may be distributed under the terms of the
46711 + * GNU General Public License ("GPL") as published by the Free Software
46712 + * Foundation, either version 2 of that License or (at your option) any
46713 + * later version.
46714 + *
46715 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46716 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46717 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46718 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46719 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46720 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46721 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46722 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46723 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46724 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46725 + */
46726 +
46727 +
46728 +/**************************************************************************//**
46729 + @File fm_pcd_ipc.h
46730 +
46731 + @Description FM PCD Inter-Partition prototypes, structures and definitions.
46732 +*//***************************************************************************/
46733 +#ifndef __FM_PCD_IPC_H
46734 +#define __FM_PCD_IPC_H
46735 +
46736 +#include "std_ext.h"
46737 +
46738 +
46739 +/**************************************************************************//**
46740 + @Group FM_grp Frame Manager API
46741 +
46742 + @Description FM API functions, definitions and enums
46743 +
46744 + @{
46745 +*//***************************************************************************/
46746 +
46747 +
46748 +#if defined(__MWERKS__) && !defined(__GNUC__)
46749 +#pragma pack(push,1)
46750 +#endif /* defined(__MWERKS__) && ... */
46751 +
46752 +/**************************************************************************//**
46753 + @Description Structure for getting a sw parser address according to a label
46754 + Fields commented 'IN' are passed by the port module to be used
46755 + by the FM module.
46756 + Fields commented 'OUT' will be filled by FM before returning to port.
46757 +*//***************************************************************************/
46758 +typedef _Packed struct t_FmPcdIpcSwPrsLable
46759 +{
46760 + uint32_t enumHdr; /**< IN. The existence of this header will invoke
46761 + the sw parser code. */
46762 + uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser
46763 + attachments for the same header, use this
46764 +
46765 + index to distinguish between them. */
46766 +} _PackedType t_FmPcdIpcSwPrsLable;
46767 +
46768 +/**************************************************************************//**
46769 + @Description Structure for port-PCD communication.
46770 + Fields commented 'IN' are passed by the port module to be used
46771 + by the FM module.
46772 + Fields commented 'OUT' will be filled by FM before returning to port.
46773 + Some fields are optional (depending on configuration) and
46774 + will be analized by the port and FM modules accordingly.
46775 +*//***************************************************************************/
46776 +
46777 +typedef struct t_FmPcdIpcKgSchemesParams
46778 +{
46779 + uint8_t guestId;
46780 + uint8_t numOfSchemes;
46781 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46782 +} _PackedType t_FmPcdIpcKgSchemesParams;
46783 +
46784 +typedef struct t_FmPcdIpcKgClsPlanParams
46785 +{
46786 + uint8_t guestId;
46787 + uint16_t numOfClsPlanEntries;
46788 + uint8_t clsPlanBase;
46789 +} _PackedType t_FmPcdIpcKgClsPlanParams;
46790 +
46791 +typedef _Packed struct t_FmPcdIpcPrsIncludePort
46792 +{
46793 + uint8_t hardwarePortId;
46794 + bool include;
46795 +} _PackedType t_FmPcdIpcPrsIncludePort;
46796 +
46797 +
46798 +#define FM_PCD_MAX_REPLY_SIZE 16
46799 +#define FM_PCD_MAX_MSG_SIZE 36
46800 +#define FM_PCD_MAX_REPLY_BODY_SIZE 36
46801 +
46802 +typedef _Packed struct {
46803 + uint32_t msgId;
46804 + uint8_t msgBody[FM_PCD_MAX_MSG_SIZE];
46805 +} _PackedType t_FmPcdIpcMsg;
46806 +
46807 +typedef _Packed struct t_FmPcdIpcReply {
46808 + uint32_t error;
46809 + uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE];
46810 +} _PackedType t_FmPcdIpcReply;
46811 +
46812 +typedef _Packed struct t_FmIpcResourceAllocParams {
46813 + uint8_t guestId;
46814 + uint16_t base;
46815 + uint16_t num;
46816 +}_PackedType t_FmIpcResourceAllocParams;
46817 +
46818 +#if defined(__MWERKS__) && !defined(__GNUC__)
46819 +#pragma pack(pop)
46820 +#endif /* defined(__MWERKS__) && ... */
46821 +
46822 +
46823 +
46824 +/**************************************************************************//**
46825 + @Function FM_PCD_ALLOC_KG_SCHEMES
46826 +
46827 + @Description Used by FM PCD front-end in order to allocate KG resources
46828 +
46829 + @Param[in/out] t_FmPcdIpcKgAllocParams Pointer
46830 +*//***************************************************************************/
46831 +#define FM_PCD_ALLOC_KG_SCHEMES 3
46832 +
46833 +/**************************************************************************//**
46834 + @Function FM_PCD_FREE_KG_SCHEMES
46835 +
46836 + @Description Used by FM PCD front-end in order to Free KG resources
46837 +
46838 + @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer
46839 +*//***************************************************************************/
46840 +#define FM_PCD_FREE_KG_SCHEMES 4
46841 +
46842 +/**************************************************************************//**
46843 + @Function FM_PCD_ALLOC_PROFILES
46844 +
46845 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46846 +
46847 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46848 +*//***************************************************************************/
46849 +#define FM_PCD_ALLOC_PROFILES 5
46850 +
46851 +/**************************************************************************//**
46852 + @Function FM_PCD_FREE_PROFILES
46853 +
46854 + @Description Used by FM PCD front-end in order to Free Policer profiles
46855 +
46856 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46857 +*//***************************************************************************/
46858 +#define FM_PCD_FREE_PROFILES 6
46859 +
46860 +/**************************************************************************//**
46861 + @Function FM_PCD_SET_PORT_PROFILES
46862 +
46863 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46864 + for specific port
46865 +
46866 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46867 +*//***************************************************************************/
46868 +#define FM_PCD_SET_PORT_PROFILES 7
46869 +
46870 +/**************************************************************************//**
46871 + @Function FM_PCD_CLEAR_PORT_PROFILES
46872 +
46873 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46874 + for specific port
46875 +
46876 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46877 +*//***************************************************************************/
46878 +#define FM_PCD_CLEAR_PORT_PROFILES 8
46879 +
46880 +/**************************************************************************//**
46881 + @Function FM_PCD_GET_PHYS_MURAM_BASE
46882 +
46883 + @Description Used by FM PCD front-end in order to get MURAM base address
46884 +
46885 + @Param[in/out] t_FmPcdIcPhysAddr Pointer
46886 +*//***************************************************************************/
46887 +#define FM_PCD_GET_PHYS_MURAM_BASE 9
46888 +
46889 +/**************************************************************************//**
46890 + @Function FM_PCD_GET_SW_PRS_OFFSET
46891 +
46892 + @Description Used by FM front-end to get the SW parser offset of the start of
46893 + code relevant to a given label.
46894 +
46895 + @Param[in/out] t_FmPcdIpcSwPrsLable Pointer
46896 +*//***************************************************************************/
46897 +#define FM_PCD_GET_SW_PRS_OFFSET 10
46898 +
46899 +/**************************************************************************//**
46900 + @Function FM_PCD_MASTER_IS_ENABLED
46901 +
46902 + @Description Used by FM front-end in order to verify
46903 + PCD enablement.
46904 +
46905 + @Param[in] bool Pointer
46906 +*//***************************************************************************/
46907 +#define FM_PCD_MASTER_IS_ENABLED 15
46908 +
46909 +/**************************************************************************//**
46910 + @Function FM_PCD_GUEST_DISABLE
46911 +
46912 + @Description Used by FM front-end to inform back-end when
46913 + front-end PCD is disabled
46914 +
46915 + @Param[in] None
46916 +*//***************************************************************************/
46917 +#define FM_PCD_GUEST_DISABLE 16
46918 +
46919 +/**************************************************************************//**
46920 + @Function FM_PCD_FREE_KG_CLSPLAN
46921 +
46922 + @Description Used by FM PCD front-end in order to Free KG classification plan entries
46923 +
46924 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46925 +*//***************************************************************************/
46926 +#define FM_PCD_FREE_KG_CLSPLAN 22
46927 +
46928 +/**************************************************************************//**
46929 + @Function FM_PCD_ALLOC_KG_CLSPLAN
46930 +
46931 + @Description Used by FM PCD front-end in order to allocate KG classification plan entries
46932 +
46933 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46934 +*//***************************************************************************/
46935 +#define FM_PCD_ALLOC_KG_CLSPLAN 23
46936 +
46937 +/**************************************************************************//**
46938 + @Function FM_PCD_MASTER_IS_ALIVE
46939 +
46940 + @Description Used by FM front-end to check that back-end exists
46941 +
46942 + @Param[in] None
46943 +*//***************************************************************************/
46944 +#define FM_PCD_MASTER_IS_ALIVE 24
46945 +
46946 +/**************************************************************************//**
46947 + @Function FM_PCD_GET_COUNTER
46948 +
46949 + @Description Used by FM front-end to read PCD counters
46950 +
46951 + @Param[in/out] t_FmPcdIpcGetCounter Pointer
46952 +*//***************************************************************************/
46953 +#define FM_PCD_GET_COUNTER 25
46954 +
46955 +/**************************************************************************//**
46956 + @Function FM_PCD_PRS_INC_PORT_STATS
46957 +
46958 + @Description Used by FM front-end to set/clear statistics for port
46959 +
46960 + @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer
46961 +*//***************************************************************************/
46962 +#define FM_PCD_PRS_INC_PORT_STATS 26
46963 +
46964 +#if (DPAA_VERSION >= 11)
46965 +/* TODO - doc */
46966 +#define FM_PCD_ALLOC_SP 27
46967 +#endif /* (DPAA_VERSION >= 11) */
46968 +
46969 +
46970 +/** @} */ /* end of FM_PCD_IPC_grp group */
46971 +/** @} */ /* end of FM_grp group */
46972 +
46973 +
46974 +#endif /* __FM_PCD_IPC_H */
46975 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
46976 new file mode 100644
46977 index 00000000..e3753305
46978 --- /dev/null
46979 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
46980 @@ -0,0 +1,1847 @@
46981 +/*
46982 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46983 + *
46984 + * Redistribution and use in source and binary forms, with or without
46985 + * modification, are permitted provided that the following conditions are met:
46986 + * * Redistributions of source code must retain the above copyright
46987 + * notice, this list of conditions and the following disclaimer.
46988 + * * Redistributions in binary form must reproduce the above copyright
46989 + * notice, this list of conditions and the following disclaimer in the
46990 + * documentation and/or other materials provided with the distribution.
46991 + * * Neither the name of Freescale Semiconductor nor the
46992 + * names of its contributors may be used to endorse or promote products
46993 + * derived from this software without specific prior written permission.
46994 + *
46995 + *
46996 + * ALTERNATIVELY, this software may be distributed under the terms of the
46997 + * GNU General Public License ("GPL") as published by the Free Software
46998 + * Foundation, either version 2 of that License or (at your option) any
46999 + * later version.
47000 + *
47001 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
47002 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47003 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47004 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
47005 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47006 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47007 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47008 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47009 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47010 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47011 + */
47012 +
47013 +
47014 +/******************************************************************************
47015 + @File fm_plcr.c
47016 +
47017 + @Description FM PCD POLICER...
47018 +*//***************************************************************************/
47019 +#include <linux/math64.h>
47020 +#include "std_ext.h"
47021 +#include "error_ext.h"
47022 +#include "string_ext.h"
47023 +#include "debug_ext.h"
47024 +#include "net_ext.h"
47025 +#include "fm_ext.h"
47026 +
47027 +#include "fm_common.h"
47028 +#include "fm_pcd.h"
47029 +#include "fm_hc.h"
47030 +#include "fm_pcd_ipc.h"
47031 +#include "fm_plcr.h"
47032 +
47033 +
47034 +/****************************************/
47035 +/* static functions */
47036 +/****************************************/
47037 +
47038 +static uint32_t PlcrProfileLock(t_Handle h_Profile)
47039 +{
47040 + ASSERT_COND(h_Profile);
47041 + return FmPcdLockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
47042 +}
47043 +
47044 +static void PlcrProfileUnlock(t_Handle h_Profile, uint32_t intFlags)
47045 +{
47046 + ASSERT_COND(h_Profile);
47047 + FmPcdUnlockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock, intFlags);
47048 +}
47049 +
47050 +static bool PlcrProfileFlagTryLock(t_Handle h_Profile)
47051 +{
47052 + ASSERT_COND(h_Profile);
47053 + return FmPcdLockTryLock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
47054 +}
47055 +
47056 +static void PlcrProfileFlagUnlock(t_Handle h_Profile)
47057 +{
47058 + ASSERT_COND(h_Profile);
47059 + FmPcdLockUnlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
47060 +}
47061 +
47062 +static uint32_t PlcrHwLock(t_Handle h_FmPcdPlcr)
47063 +{
47064 + ASSERT_COND(h_FmPcdPlcr);
47065 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock);
47066 +}
47067 +
47068 +static void PlcrHwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
47069 +{
47070 + ASSERT_COND(h_FmPcdPlcr);
47071 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock, intFlags);
47072 +}
47073 +
47074 +static uint32_t PlcrSwLock(t_Handle h_FmPcdPlcr)
47075 +{
47076 + ASSERT_COND(h_FmPcdPlcr);
47077 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock);
47078 +}
47079 +
47080 +static void PlcrSwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
47081 +{
47082 + ASSERT_COND(h_FmPcdPlcr);
47083 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock, intFlags);
47084 +}
47085 +
47086 +static bool IsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId)
47087 +{
47088 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47089 + uint16_t i;
47090 +
47091 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE);
47092 +
47093 + for (i=0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++)
47094 + if (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId)
47095 + return TRUE;
47096 + return FALSE;
47097 +}
47098 +
47099 +static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction)
47100 +{
47101 + uint32_t nia;
47102 + uint16_t absoluteProfileId;
47103 + uint8_t relativeSchemeId, physicalSchemeId;
47104 +
47105 + nia = FM_PCD_PLCR_NIA_VALID;
47106 +
47107 + switch (nextEngine)
47108 + {
47109 + case e_FM_PCD_DONE :
47110 + switch (p_NextEngineParams->action)
47111 + {
47112 + case e_FM_PCD_DROP_FRAME :
47113 + nia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
47114 + break;
47115 + case e_FM_PCD_ENQ_FRAME:
47116 + nia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
47117 + break;
47118 + default:
47119 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47120 + }
47121 + break;
47122 + case e_FM_PCD_KG:
47123 + physicalSchemeId = FmPcdKgGetSchemeId(p_NextEngineParams->h_DirectScheme);
47124 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
47125 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
47126 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
47127 + if (!FmPcdKgIsSchemeValidSw(p_NextEngineParams->h_DirectScheme))
47128 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
47129 + if (!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId))
47130 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct."));
47131 + nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicalSchemeId;
47132 + break;
47133 + case e_FM_PCD_PLCR:
47134 + absoluteProfileId = ((t_FmPcdPlcrProfile *)p_NextEngineParams->h_Profile)->absoluteProfileId;
47135 + if (!IsProfileShared(p_FmPcd, absoluteProfileId))
47136 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile"));
47137 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
47138 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile "));
47139 + nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId;
47140 + break;
47141 + default:
47142 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47143 + }
47144 +
47145 + *nextAction = nia;
47146 +
47147 + return E_OK;
47148 +}
47149 +
47150 +static uint32_t CalcFPP(uint32_t fpp)
47151 +{
47152 + if (fpp > 15)
47153 + return 15 - (0x1f - fpp);
47154 + else
47155 + return 16 + fpp;
47156 +}
47157 +
47158 +static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode,
47159 + uint32_t rate,
47160 + uint64_t tsuInTenthNano,
47161 + uint32_t fppShift,
47162 + uint64_t *p_Integer,
47163 + uint64_t *p_Fraction)
47164 +{
47165 + uint64_t tmp, div;
47166 +
47167 + if (rateMode == e_FM_PCD_PLCR_BYTE_MODE)
47168 + {
47169 + /* now we calculate the initial integer for the bigger rate */
47170 + /* from Kbps to Bytes/TSU */
47171 + tmp = (uint64_t)rate;
47172 + tmp *= 1000; /* kb --> b */
47173 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
47174 +
47175 + div = 1000000000; /* nano */
47176 + div *= 10; /* 10 nano */
47177 + div *= 8; /* bit to byte */
47178 + }
47179 + else
47180 + {
47181 + /* now we calculate the initial integer for the bigger rate */
47182 + /* from Kbps to Bytes/TSU */
47183 + tmp = (uint64_t)rate;
47184 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
47185 +
47186 + div = 1000000000; /* nano */
47187 + div *= 10; /* 10 nano */
47188 + }
47189 + *p_Integer = div64_u64(tmp<<fppShift, div);
47190 +
47191 + /* for calculating the fraction, we will recalculate cir and deduct the integer.
47192 + * For precision, we will multiply by 2^16. we do not divid back, since we write
47193 + * this value as fraction - see spec.
47194 + */
47195 + *p_Fraction = div64_u64(((tmp<<fppShift)<<16) - ((*p_Integer<<16)*div), div);
47196 +}
47197 +
47198 +/* .......... */
47199 +
47200 +static void CalcRates(uint32_t bitFor1Micro,
47201 + t_FmPcdPlcrNonPassthroughAlgParams *p_NonPassthroughAlgParam,
47202 + uint32_t *cir,
47203 + uint32_t *cbs,
47204 + uint32_t *pir_eir,
47205 + uint32_t *pbs_ebs,
47206 + uint32_t *fpp)
47207 +{
47208 + uint64_t integer, fraction;
47209 + uint32_t temp, tsuInTenthNanos;
47210 + uint8_t fppShift=0;
47211 +
47212 + /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */
47213 + tsuInTenthNanos = (uint32_t)(1000*10/(1 << bitFor1Micro));
47214 +
47215 + /* we choose the faster rate to calibrate fpp */
47216 + /* The meaning of this step:
47217 + * when fppShift is 0 it means all TS bits are treated as integer and TSU is the TS LSB count.
47218 + * In this configuration we calculate the integer and fraction that represent the higher infoRate
47219 + * When this is done, we can tell where we have "spare" unused bits and optimize the division of TS
47220 + * into "integer" and "fraction" where the logic is - as many bits as possible for integer at
47221 + * high rate, as many bits as possible for fraction at low rate.
47222 + */
47223 + if (p_NonPassthroughAlgParam->committedInfoRate > p_NonPassthroughAlgParam->peakOrExcessInfoRate)
47224 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
47225 + else
47226 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
47227 +
47228 + /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and
47229 + * the LSB bits are for the fraction */
47230 + temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF);
47231 + /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll
47232 + * take max FP = 31.
47233 + * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is
47234 + * limited by the 10G physical port.
47235 + */
47236 + if (temp != 0)
47237 + {
47238 + /* In this case, the largest rate integer is non 0, if it does not occupy all (high) 16
47239 + * bits of the PIR_EIR we can use this fact and enlarge it to occupy all 16 bits.
47240 + * The logic is to have as many bits for integer in the higher rates, but if we have "0"s
47241 + * in the integer part of the cir/pir register, than these bits are wasted. So we want
47242 + * to use these bits for the fraction. in this way we will have for fraction - the number
47243 + * of "0" bits and the rest - for integer.
47244 + * In other words: For each bit we shift it in PIR_EIR, we move the FP in the TS
47245 + * one bit to the left - preserving the relationship and achieving more bits
47246 + * for integer in the TS.
47247 + */
47248 +
47249 + /* count zeroes left of the higher used bit (in order to shift the value such that
47250 + * unused bits may be used for fraction).
47251 + */
47252 + while ((temp & 0x80000000) == 0)
47253 + {
47254 + temp = temp << 1;
47255 + fppShift++;
47256 + }
47257 + if (fppShift > 15)
47258 + {
47259 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small"));
47260 + return;
47261 + }
47262 + }
47263 + else
47264 + {
47265 + temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */
47266 + if (!temp)
47267 + /* integer and fraction are 0, we set FP to its max val */
47268 + fppShift = 31;
47269 + else
47270 + {
47271 + /* integer was 0 but fraction is not. FP is 16 for the fraction,
47272 + * + all left zeroes of the fraction. */
47273 + fppShift=16;
47274 + /* count zeroes left of the higher used bit (in order to shift the value such that
47275 + * unused bits may be used for fraction).
47276 + */
47277 + while ((temp & 0x8000) == 0)
47278 + {
47279 + temp = temp << 1;
47280 + fppShift++;
47281 + }
47282 + }
47283 + }
47284 +
47285 + /*
47286 + * This means that the FM TS register will now be used so that 'fppShift' bits are for
47287 + * fraction and the rest for integer */
47288 + /* now we re-calculate cir and pir_eir with the calculated FP */
47289 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
47290 + *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
47291 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
47292 + *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
47293 +
47294 + *cbs = p_NonPassthroughAlgParam->committedBurstSize;
47295 + *pbs_ebs = p_NonPassthroughAlgParam->peakOrExcessBurstSize;
47296 +
47297 + /* convert FP as it should be written to reg.
47298 + * 0-15 --> 16-31
47299 + * 16-31 --> 0-15
47300 + */
47301 + *fpp = CalcFPP(fppShift);
47302 +}
47303 +
47304 +static void WritePar(t_FmPcd *p_FmPcd, uint32_t par)
47305 +{
47306 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47307 +
47308 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47309 + WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par);
47310 +
47311 + while (GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ;
47312 +}
47313 +
47314 +static t_Error BuildProfileRegs(t_FmPcd *p_FmPcd,
47315 + t_FmPcdPlcrProfileParams *p_ProfileParams,
47316 + t_FmPcdPlcrProfileRegs *p_PlcrRegs)
47317 +{
47318 + t_Error err = E_OK;
47319 + uint32_t pemode, gnia, ynia, rnia, bitFor1Micro;
47320 +
47321 + ASSERT_COND(p_FmPcd);
47322 +
47323 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
47324 + if (bitFor1Micro == 0)
47325 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
47326 +
47327 +/* Set G, Y, R Nia */
47328 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnGreen, &(p_ProfileParams->paramsOnGreen), &gnia);
47329 + if (err)
47330 + RETURN_ERROR(MAJOR, err, NO_MSG);
47331 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnYellow, &(p_ProfileParams->paramsOnYellow), &ynia);
47332 + if (err)
47333 + RETURN_ERROR(MAJOR, err, NO_MSG);
47334 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnRed, &(p_ProfileParams->paramsOnRed), &rnia);
47335 + if (err)
47336 + RETURN_ERROR(MAJOR, err, NO_MSG);
47337 +
47338 +/* Mode fmpl_pemode */
47339 + pemode = FM_PCD_PLCR_PEMODE_PI;
47340 +
47341 + switch (p_ProfileParams->algSelection)
47342 + {
47343 + case e_FM_PCD_PLCR_PASS_THROUGH:
47344 + p_PlcrRegs->fmpl_pecir = 0;
47345 + p_PlcrRegs->fmpl_pecbs = 0;
47346 + p_PlcrRegs->fmpl_pepepir_eir = 0;
47347 + p_PlcrRegs->fmpl_pepbs_ebs = 0;
47348 + p_PlcrRegs->fmpl_pelts = 0;
47349 + p_PlcrRegs->fmpl_pects = 0;
47350 + p_PlcrRegs->fmpl_pepts_ets = 0;
47351 + pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK;
47352 + switch (p_ProfileParams->colorMode)
47353 + {
47354 + case e_FM_PCD_PLCR_COLOR_BLIND:
47355 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47356 + switch (p_ProfileParams->color.dfltColor)
47357 + {
47358 + case e_FM_PCD_PLCR_GREEN:
47359 + pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK;
47360 + break;
47361 + case e_FM_PCD_PLCR_YELLOW:
47362 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y;
47363 + break;
47364 + case e_FM_PCD_PLCR_RED:
47365 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_R;
47366 + break;
47367 + case e_FM_PCD_PLCR_OVERRIDE:
47368 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE;
47369 + break;
47370 + default:
47371 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47372 + }
47373 +
47374 + break;
47375 + case e_FM_PCD_PLCR_COLOR_AWARE:
47376 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47377 + break;
47378 + default:
47379 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47380 + }
47381 + break;
47382 +
47383 + case e_FM_PCD_PLCR_RFC_2698:
47384 + /* Select algorithm MODE[ALG] = "01" */
47385 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698;
47386 + if (p_ProfileParams->nonPassthroughAlgParams.committedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrExcessInfoRate)
47387 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than committedInfoRate."));
47388 + goto cont_rfc;
47389 + case e_FM_PCD_PLCR_RFC_4115:
47390 + /* Select algorithm MODE[ALG] = "10" */
47391 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115;
47392 +cont_rfc:
47393 + /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */
47394 + switch (p_ProfileParams->colorMode)
47395 + {
47396 + case e_FM_PCD_PLCR_COLOR_BLIND:
47397 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47398 + break;
47399 + case e_FM_PCD_PLCR_COLOR_AWARE:
47400 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47401 + /*In color aware more select override color interpretation (MODE[OVCLR]) */
47402 + switch (p_ProfileParams->color.override)
47403 + {
47404 + case e_FM_PCD_PLCR_GREEN:
47405 + pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK;
47406 + break;
47407 + case e_FM_PCD_PLCR_YELLOW:
47408 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y;
47409 + break;
47410 + case e_FM_PCD_PLCR_RED:
47411 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R;
47412 + break;
47413 + case e_FM_PCD_PLCR_OVERRIDE:
47414 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC;
47415 + break;
47416 + default:
47417 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47418 + }
47419 + break;
47420 + default:
47421 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47422 + }
47423 + /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */
47424 + switch (p_ProfileParams->nonPassthroughAlgParams.rateMode)
47425 + {
47426 + case e_FM_PCD_PLCR_BYTE_MODE :
47427 + pemode &= ~FM_PCD_PLCR_PEMODE_PKT;
47428 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.frameLengthSelection)
47429 + {
47430 + case e_FM_PCD_PLCR_L2_FRM_LEN:
47431 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L2;
47432 + break;
47433 + case e_FM_PCD_PLCR_L3_FRM_LEN:
47434 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L3;
47435 + break;
47436 + case e_FM_PCD_PLCR_L4_FRM_LEN:
47437 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L4;
47438 + break;
47439 + case e_FM_PCD_PLCR_FULL_FRM_LEN:
47440 + pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL;
47441 + break;
47442 + default:
47443 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47444 + }
47445 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection)
47446 + {
47447 + case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN:
47448 + pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS;
47449 + break;
47450 + case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN:
47451 + pemode |= FM_PCD_PLCR_PEMODE_RBFLS;
47452 + break;
47453 + default:
47454 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47455 + }
47456 + break;
47457 + case e_FM_PCD_PLCR_PACKET_MODE :
47458 + pemode |= FM_PCD_PLCR_PEMODE_PKT;
47459 + break;
47460 + default:
47461 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47462 + }
47463 + /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET
47464 + mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE
47465 + mode with high traffic rates move the fixed point to the right to increase integer accuracy. */
47466 +
47467 + /* Configure Traffic Parameters*/
47468 + {
47469 + uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0;
47470 +
47471 + CalcRates(bitFor1Micro, &p_ProfileParams->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp);
47472 +
47473 + /* Set Committed Information Rate (CIR) */
47474 + p_PlcrRegs->fmpl_pecir = cir;
47475 + /* Set Committed Burst Size (CBS). */
47476 + p_PlcrRegs->fmpl_pecbs = cbs;
47477 + /* Set Peak Information Rate (PIR_EIR used as PIR) */
47478 + p_PlcrRegs->fmpl_pepepir_eir = pir_eir;
47479 + /* Set Peak Burst Size (PBS_EBS used as PBS) */
47480 + p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs;
47481 +
47482 + /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */
47483 + /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */
47484 + p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF;
47485 + /* Committed Rate Token Bucket Size (CTS) */
47486 + p_PlcrRegs->fmpl_pects = 0xFFFFFFFF;
47487 +
47488 + /* Set the FPP based on calculation */
47489 + pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT);
47490 + }
47491 + break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */
47492 + default:
47493 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47494 + }
47495 +
47496 + p_PlcrRegs->fmpl_pemode = pemode;
47497 +
47498 + p_PlcrRegs->fmpl_pegnia = gnia;
47499 + p_PlcrRegs->fmpl_peynia = ynia;
47500 + p_PlcrRegs->fmpl_pernia = rnia;
47501 +
47502 + /* Zero Counters */
47503 + p_PlcrRegs->fmpl_pegpc = 0;
47504 + p_PlcrRegs->fmpl_peypc = 0;
47505 + p_PlcrRegs->fmpl_perpc = 0;
47506 + p_PlcrRegs->fmpl_perypc = 0;
47507 + p_PlcrRegs->fmpl_perrpc = 0;
47508 +
47509 + return E_OK;
47510 +}
47511 +
47512 +static t_Error AllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47513 +{
47514 + uint32_t profilesFound;
47515 + uint16_t i, k=0;
47516 + uint32_t intFlags;
47517 +
47518 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47519 +
47520 + if (!numOfProfiles)
47521 + return E_OK;
47522 +
47523 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
47524 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
47525 +
47526 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47527 + /* Find numOfProfiles free profiles (may be spread) */
47528 + profilesFound = 0;
47529 + for (i=0;i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47530 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
47531 + {
47532 + profilesFound++;
47533 + profilesIds[k] = i;
47534 + k++;
47535 + if (profilesFound == numOfProfiles)
47536 + break;
47537 + }
47538 +
47539 + if (profilesFound != numOfProfiles)
47540 + {
47541 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47542 + RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG);
47543 + }
47544 +
47545 + for (i = 0;i<k;i++)
47546 + {
47547 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE;
47548 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0;
47549 + }
47550 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47551 +
47552 + return E_OK;
47553 +}
47554 +
47555 +static void FreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47556 +{
47557 + uint16_t i;
47558 +
47559 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
47560 +
47561 + ASSERT_COND(numOfProfiles);
47562 +
47563 + for (i=0; i < numOfProfiles; i++)
47564 + {
47565 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated);
47566 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE;
47567 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = p_FmPcd->guestId;
47568 + }
47569 +}
47570 +
47571 +static void UpdateRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool set)
47572 +{
47573 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47574 +
47575 + /* this routine is protected by calling routine */
47576 +
47577 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
47578 +
47579 + if (set)
47580 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = TRUE;
47581 + else
47582 + {
47583 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = 0;
47584 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = FALSE;
47585 + }
47586 +}
47587 +
47588 +/*********************************************/
47589 +/*............Policer Exception..............*/
47590 +/*********************************************/
47591 +static void EventsCB(t_Handle h_FmPcd)
47592 +{
47593 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47594 + uint32_t event, mask, force;
47595 +
47596 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47597 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr);
47598 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
47599 +
47600 + event &= mask;
47601 +
47602 + /* clear the forced events */
47603 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr);
47604 + if (force & event)
47605 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event);
47606 +
47607 +
47608 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event);
47609 +
47610 + if (event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE)
47611 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE);
47612 + if (event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)
47613 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE);
47614 +}
47615 +
47616 +/* ..... */
47617 +
47618 +static void ErrorExceptionsCB(t_Handle h_FmPcd)
47619 +{
47620 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47621 + uint32_t event, force, captureReg, mask;
47622 +
47623 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47624 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr);
47625 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
47626 +
47627 + event &= mask;
47628 +
47629 + /* clear the forced events */
47630 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr);
47631 + if (force & event)
47632 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event);
47633 +
47634 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event);
47635 +
47636 + if (event & FM_PCD_PLCR_DOUBLE_ECC)
47637 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC);
47638 + if (event & FM_PCD_PLCR_INIT_ENTRY_ERROR)
47639 + {
47640 + captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr);
47641 + /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP);
47642 + p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK);
47643 + p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ;
47644 + p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/
47645 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK));
47646 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP);
47647 + }
47648 +}
47649 +
47650 +
47651 +/*****************************************************************************/
47652 +/* Inter-module API routines */
47653 +/*****************************************************************************/
47654 +
47655 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
47656 +{
47657 + t_FmPcdPlcr *p_FmPcdPlcr;
47658 + uint16_t i=0;
47659 +
47660 + UNUSED(p_FmPcd);
47661 + UNUSED(p_FmPcdParams);
47662 +
47663 + p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr));
47664 + if (!p_FmPcdPlcr)
47665 + {
47666 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED"));
47667 + return NULL;
47668 + }
47669 + memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr));
47670 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
47671 + {
47672 + p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm));
47673 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh;
47674 + p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions);
47675 + }
47676 +
47677 + p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles;
47678 +
47679 + p_FmPcdPlcr->partPlcrProfilesBase = p_FmPcdParams->partPlcrProfilesBase;
47680 + p_FmPcdPlcr->partNumOfPlcrProfiles = p_FmPcdParams->partNumOfPlcrProfiles;
47681 + /* for backward compatabilty. if no policer profile, will set automatically to the max */
47682 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) &&
47683 + (p_FmPcdPlcr->partNumOfPlcrProfiles == 0))
47684 + p_FmPcdPlcr->partNumOfPlcrProfiles = FM_PCD_PLCR_NUM_ENTRIES;
47685 +
47686 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47687 + p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47688 +
47689 + return p_FmPcdPlcr;
47690 +}
47691 +
47692 +t_Error PlcrInit(t_FmPcd *p_FmPcd)
47693 +{
47694 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
47695 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47696 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47697 + t_Error err = E_OK;
47698 + uint32_t tmpReg32 = 0;
47699 + uint16_t base;
47700 +
47701 + if ((p_FmPcdPlcr->partPlcrProfilesBase + p_FmPcdPlcr->partNumOfPlcrProfiles) > FM_PCD_PLCR_NUM_ENTRIES)
47702 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partPlcrProfilesBase+partNumOfPlcrProfiles out of range!!!"));
47703 +
47704 + p_FmPcdPlcr->h_HwSpinlock = XX_InitSpinlock();
47705 + if (!p_FmPcdPlcr->h_HwSpinlock)
47706 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer HW spinlock"));
47707 +
47708 + p_FmPcdPlcr->h_SwSpinlock = XX_InitSpinlock();
47709 + if (!p_FmPcdPlcr->h_SwSpinlock)
47710 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer SW spinlock"));
47711 +
47712 + base = PlcrAllocProfilesForPartition(p_FmPcd,
47713 + p_FmPcdPlcr->partPlcrProfilesBase,
47714 + p_FmPcdPlcr->partNumOfPlcrProfiles,
47715 + p_FmPcd->guestId);
47716 + if (base == (uint16_t)ILLEGAL_BASE)
47717 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
47718 +
47719 + if (p_FmPcdPlcr->numOfSharedProfiles)
47720 + {
47721 + err = AllocSharedProfiles(p_FmPcd,
47722 + p_FmPcdPlcr->numOfSharedProfiles,
47723 + p_FmPcdPlcr->sharedProfilesIds);
47724 + if (err)
47725 + RETURN_ERROR(MAJOR, err,NO_MSG);
47726 + }
47727 +
47728 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47729 + return E_OK;
47730 +
47731 + /**********************FMPL_GCR******************/
47732 + tmpReg32 = 0;
47733 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
47734 + if (p_Param->plcrAutoRefresh)
47735 + tmpReg32 |= FM_PCD_PLCR_GCR_DAR;
47736 + tmpReg32 |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
47737 +
47738 + WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32);
47739 + /**********************FMPL_GCR******************/
47740 +
47741 + /**********************FMPL_EEVR******************/
47742 + WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR));
47743 + /**********************FMPL_EEVR******************/
47744 + /**********************FMPL_EIER******************/
47745 + tmpReg32 = 0;
47746 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)
47747 + {
47748 + FmEnableRamsEcc(p_FmPcd->h_Fm);
47749 + tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC;
47750 + }
47751 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
47752 + tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
47753 + WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32);
47754 + /**********************FMPL_EIER******************/
47755 +
47756 + /**********************FMPL_EVR******************/
47757 + WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE));
47758 + /**********************FMPL_EVR******************/
47759 + /**********************FMPL_IER******************/
47760 + tmpReg32 = 0;
47761 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)
47762 + tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
47763 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE)
47764 + tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
47765 + WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32);
47766 + /**********************FMPL_IER******************/
47767 +
47768 + /* register even if no interrupts enabled, to allow future enablement */
47769 + FmRegisterIntr(p_FmPcd->h_Fm,
47770 + e_FM_MOD_PLCR,
47771 + 0,
47772 + e_FM_INTR_TYPE_ERR,
47773 + ErrorExceptionsCB,
47774 + p_FmPcd);
47775 + FmRegisterIntr(p_FmPcd->h_Fm,
47776 + e_FM_MOD_PLCR,
47777 + 0,
47778 + e_FM_INTR_TYPE_NORMAL,
47779 + EventsCB,
47780 + p_FmPcd);
47781 +
47782 + /* driver initializes one DFLT profile at the last entry*/
47783 + /**********************FMPL_DPMR******************/
47784 + tmpReg32 = 0;
47785 + WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32);
47786 + p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE;
47787 +
47788 + return E_OK;
47789 +}
47790 +
47791 +t_Error PlcrFree(t_FmPcd *p_FmPcd)
47792 +{
47793 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR);
47794 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL);
47795 +
47796 + if (p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles)
47797 + FreeSharedProfiles(p_FmPcd,
47798 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles,
47799 + p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);
47800 +
47801 + if (p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles)
47802 + PlcrFreeProfilesForPartition(p_FmPcd,
47803 + p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase,
47804 + p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles,
47805 + p_FmPcd->guestId);
47806 +
47807 + if (p_FmPcd->p_FmPcdPlcr->h_SwSpinlock)
47808 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_SwSpinlock);
47809 +
47810 + if (p_FmPcd->p_FmPcdPlcr->h_HwSpinlock)
47811 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_HwSpinlock);
47812 +
47813 + return E_OK;
47814 +}
47815 +
47816 +void PlcrEnable(t_FmPcd *p_FmPcd)
47817 +{
47818 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47819 +
47820 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN);
47821 +}
47822 +
47823 +void PlcrDisable(t_FmPcd *p_FmPcd)
47824 +{
47825 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47826 +
47827 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN);
47828 +}
47829 +
47830 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47831 +{
47832 + uint32_t intFlags;
47833 + uint16_t profilesFound = 0;
47834 + int i = 0;
47835 +
47836 + ASSERT_COND(p_FmPcd);
47837 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47838 +
47839 + if (!numOfProfiles)
47840 + return 0;
47841 +
47842 + if ((numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES) ||
47843 + (base + numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES))
47844 + return (uint16_t)ILLEGAL_BASE;
47845 +
47846 + if (p_FmPcd->h_IpcSession)
47847 + {
47848 + t_FmIpcResourceAllocParams ipcAllocParams;
47849 + t_FmPcdIpcMsg msg;
47850 + t_FmPcdIpcReply reply;
47851 + t_Error err;
47852 + uint32_t replyLength;
47853 +
47854 + memset(&msg, 0, sizeof(msg));
47855 + memset(&reply, 0, sizeof(reply));
47856 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47857 + ipcAllocParams.guestId = p_FmPcd->guestId;
47858 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47859 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47860 + msg.msgId = FM_PCD_ALLOC_PROFILES;
47861 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47862 + replyLength = sizeof(uint32_t) + sizeof(uint16_t);
47863 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47864 + (uint8_t*)&msg,
47865 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47866 + (uint8_t*)&reply,
47867 + &replyLength,
47868 + NULL,
47869 + NULL);
47870 + if ((err != E_OK) ||
47871 + (replyLength != (sizeof(uint32_t) + sizeof(uint16_t))))
47872 + {
47873 + REPORT_ERROR(MAJOR, err, NO_MSG);
47874 + return (uint16_t)ILLEGAL_BASE;
47875 + }
47876 + else
47877 + memcpy((uint8_t*)&p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, reply.replyBody, sizeof(uint16_t));
47878 + if (p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase == (uint16_t)ILLEGAL_BASE)
47879 + {
47880 + REPORT_ERROR(MAJOR, err, NO_MSG);
47881 + return (uint16_t)ILLEGAL_BASE;
47882 + }
47883 + }
47884 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47885 + {
47886 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47887 + return (uint16_t)ILLEGAL_BASE;
47888 + }
47889 +
47890 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
47891 + for (i=base; i<(base+numOfProfiles); i++)
47892 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
47893 + profilesFound++;
47894 + else
47895 + break;
47896 +
47897 + if (profilesFound == numOfProfiles)
47898 + for (i=base; i<(base+numOfProfiles); i++)
47899 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = guestId;
47900 + else
47901 + {
47902 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47903 + return (uint16_t)ILLEGAL_BASE;
47904 + }
47905 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47906 +
47907 + return base;
47908 +}
47909 +
47910 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47911 +{
47912 + int i = 0;
47913 +
47914 + ASSERT_COND(p_FmPcd);
47915 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47916 +
47917 + if (p_FmPcd->h_IpcSession)
47918 + {
47919 + t_FmIpcResourceAllocParams ipcAllocParams;
47920 + t_FmPcdIpcMsg msg;
47921 + t_Error err;
47922 +
47923 + memset(&msg, 0, sizeof(msg));
47924 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47925 + ipcAllocParams.guestId = p_FmPcd->guestId;
47926 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47927 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47928 + msg.msgId = FM_PCD_FREE_PROFILES;
47929 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47930 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47931 + (uint8_t*)&msg,
47932 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47933 + NULL,
47934 + NULL,
47935 + NULL,
47936 + NULL);
47937 + if (err != E_OK)
47938 + REPORT_ERROR(MAJOR, err, NO_MSG);
47939 + return;
47940 + }
47941 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47942 + {
47943 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47944 + return;
47945 + }
47946 +
47947 + for (i=base; i<(base+numOfProfiles); i++)
47948 + {
47949 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == guestId)
47950 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47951 + else
47952 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
47953 + }
47954 +}
47955 +
47956 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
47957 + uint8_t hardwarePortId,
47958 + uint16_t numOfProfiles,
47959 + uint16_t base)
47960 +{
47961 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47962 + uint32_t log2Num, tmpReg32;
47963 +
47964 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47965 + !p_Regs &&
47966 + p_FmPcd->h_IpcSession)
47967 + {
47968 + t_FmIpcResourceAllocParams ipcAllocParams;
47969 + t_FmPcdIpcMsg msg;
47970 + t_Error err;
47971 +
47972 + memset(&msg, 0, sizeof(msg));
47973 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47974 + ipcAllocParams.guestId = hardwarePortId;
47975 + ipcAllocParams.num = numOfProfiles;
47976 + ipcAllocParams.base = base;
47977 + msg.msgId = FM_PCD_SET_PORT_PROFILES;
47978 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47979 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47980 + (uint8_t*)&msg,
47981 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47982 + NULL,
47983 + NULL,
47984 + NULL,
47985 + NULL);
47986 + if (err != E_OK)
47987 + RETURN_ERROR(MAJOR, err, NO_MSG);
47988 + return E_OK;
47989 + }
47990 + else if (!p_Regs)
47991 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
47992 + ("Either IPC or 'baseAddress' is required!"));
47993 +
47994 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47995 +
47996 + if (GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V)
47997 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
47998 + ("The requesting port has already an allocated profiles window."));
47999 +
48000 + /**********************FMPL_PMRx******************/
48001 + LOG2((uint64_t)numOfProfiles, log2Num);
48002 + tmpReg32 = base;
48003 + tmpReg32 |= log2Num << 16;
48004 + tmpReg32 |= FM_PCD_PLCR_PMR_V;
48005 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32);
48006 +
48007 + return E_OK;
48008 +}
48009 +
48010 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
48011 +{
48012 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48013 +
48014 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
48015 + !p_Regs &&
48016 + p_FmPcd->h_IpcSession)
48017 + {
48018 + t_FmIpcResourceAllocParams ipcAllocParams;
48019 + t_FmPcdIpcMsg msg;
48020 + t_Error err;
48021 +
48022 + memset(&msg, 0, sizeof(msg));
48023 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
48024 + ipcAllocParams.guestId = hardwarePortId;
48025 + msg.msgId = FM_PCD_CLEAR_PORT_PROFILES;
48026 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
48027 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
48028 + (uint8_t*)&msg,
48029 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
48030 + NULL,
48031 + NULL,
48032 + NULL,
48033 + NULL);
48034 + if (err != E_OK)
48035 + RETURN_ERROR(MAJOR, err, NO_MSG);
48036 + return E_OK;
48037 + }
48038 + else if (!p_Regs)
48039 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
48040 + ("Either IPC or 'baseAddress' is required!"));
48041 +
48042 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
48043 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0);
48044 +
48045 + return E_OK;
48046 +}
48047 +
48048 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles)
48049 +{
48050 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48051 + t_Error err = E_OK;
48052 + uint32_t profilesFound;
48053 + uint32_t intFlags;
48054 + uint16_t i, first, swPortIndex = 0;
48055 +
48056 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48057 +
48058 + if (!numOfProfiles)
48059 + return E_OK;
48060 +
48061 + ASSERT_COND(hardwarePortId);
48062 +
48063 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
48064 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
48065 +
48066 + if (!POWER_OF_2(numOfProfiles))
48067 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
48068 +
48069 + first = 0;
48070 + profilesFound = 0;
48071 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
48072 +
48073 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; )
48074 + {
48075 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
48076 + {
48077 + profilesFound++;
48078 + i++;
48079 + if (profilesFound == numOfProfiles)
48080 + break;
48081 + }
48082 + else
48083 + {
48084 + profilesFound = 0;
48085 + /* advance i to the next aligned address */
48086 + i = first = (uint16_t)(first + numOfProfiles);
48087 + }
48088 + }
48089 +
48090 + if (profilesFound == numOfProfiles)
48091 + {
48092 + for (i=first; i<first + numOfProfiles; i++)
48093 + {
48094 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE;
48095 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId;
48096 + }
48097 + }
48098 + else
48099 + {
48100 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48101 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
48102 + }
48103 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48104 +
48105 + err = PlcrSetPortProfiles(p_FmPcd, hardwarePortId, numOfProfiles, first);
48106 + if (err)
48107 + {
48108 + RETURN_ERROR(MAJOR, err, NO_MSG);
48109 + }
48110 +
48111 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48112 +
48113 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles;
48114 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = first;
48115 +
48116 + return E_OK;
48117 +}
48118 +
48119 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
48120 +{
48121 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48122 + t_Error err = E_OK;
48123 + uint32_t intFlags;
48124 + uint16_t i, swPortIndex = 0;
48125 +
48126 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
48127 +
48128 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48129 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48130 +
48131 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48132 +
48133 + err = PlcrClearPortProfiles(p_FmPcd, hardwarePortId);
48134 + if (err)
48135 + RETURN_ERROR(MAJOR, err,NO_MSG);
48136 +
48137 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
48138 + for (i=p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
48139 + i<(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase +
48140 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles);
48141 + i++)
48142 + {
48143 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId);
48144 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated);
48145 +
48146 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE;
48147 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = p_FmPcd->guestId;
48148 + }
48149 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48150 +
48151 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0;
48152 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0;
48153 +
48154 + return E_OK;
48155 +}
48156 +
48157 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction)
48158 +{
48159 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48160 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48161 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs;
48162 + uint32_t tmpReg32, intFlags;
48163 + t_Error err;
48164 +
48165 + /* Calling function locked all PCD modules, so no need to lock here */
48166 +
48167 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
48168 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range"));
48169 +
48170 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileIndx))
48171 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid"));
48172 +
48173 + /*intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx]);*/
48174 +
48175 + if (p_FmPcd->h_Hc)
48176 + {
48177 + err = FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction);
48178 +
48179 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
48180 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
48181 +
48182 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48183 + return err;
48184 + }
48185 +
48186 + /* lock the HW because once we read the registers we don't want them to be changed
48187 + * by another access. (We can copy to a tmp location and release the lock!) */
48188 +
48189 + intFlags = PlcrHwLock(p_FmPcdPlcr);
48190 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
48191 +
48192 + if (!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredActionFlag ||
48193 + !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction))
48194 + {
48195 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
48196 + {
48197 + if ((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) ||
48198 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) ||
48199 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE))
48200 + {
48201 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48202 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48203 + RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE"));
48204 + }
48205 +
48206 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME)
48207 + {
48208 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia);
48209 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48210 + {
48211 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48212 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48213 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48214 + }
48215 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48216 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32);
48217 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48218 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48219 + WritePar(p_FmPcd, tmpReg32);
48220 + }
48221 +
48222 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME)
48223 + {
48224 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia);
48225 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48226 + {
48227 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48228 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48229 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48230 + }
48231 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48232 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32);
48233 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48234 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48235 + WritePar(p_FmPcd, tmpReg32);
48236 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48237 + }
48238 +
48239 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME)
48240 + {
48241 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia);
48242 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48243 + {
48244 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48245 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48246 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48247 + }
48248 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48249 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32);
48250 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48251 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48252 + WritePar(p_FmPcd, tmpReg32);
48253 +
48254 + }
48255 + }
48256 + }
48257 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48258 +
48259 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
48260 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
48261 +
48262 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48263 +
48264 + return E_OK;
48265 +}
48266 +
48267 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48268 +{
48269 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48270 +
48271 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48272 +
48273 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag;
48274 +}
48275 +
48276 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48277 +{
48278 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48279 +
48280 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48281 +
48282 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction;
48283 +}
48284 +
48285 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48286 +{
48287 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48288 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48289 +
48290 + ASSERT_COND(absoluteProfileId < FM_PCD_PLCR_NUM_ENTRIES);
48291 +
48292 + return p_FmPcdPlcr->profiles[absoluteProfileId].valid;
48293 +}
48294 +
48295 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48296 +{
48297 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48298 + uint32_t intFlags;
48299 +
48300 + ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48301 +
48302 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
48303 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE;
48304 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
48305 +}
48306 +
48307 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48308 +{
48309 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48310 + uint32_t intFlags;
48311 +
48312 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48313 +
48314 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
48315 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE;
48316 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
48317 +}
48318 +
48319 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile)
48320 +{
48321 + return ((t_FmPcdPlcrProfile*)h_Profile)->absoluteProfileId;
48322 +}
48323 +
48324 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
48325 + e_FmPcdProfileTypeSelection profileType,
48326 + t_Handle h_FmPort,
48327 + uint16_t relativeProfile,
48328 + uint16_t *p_AbsoluteId)
48329 +{
48330 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48331 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48332 + uint8_t i;
48333 +
48334 + switch (profileType)
48335 + {
48336 + case e_FM_PCD_PLCR_PORT_PRIVATE:
48337 + /* get port PCD id from port handle */
48338 + for (i=0;i<FM_MAX_NUM_OF_PORTS;i++)
48339 + if (p_FmPcd->p_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort)
48340 + break;
48341 + if (i == FM_MAX_NUM_OF_PORTS)
48342 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle."));
48343 +
48344 + if (!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48345 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles"));
48346 + if (relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48347 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48348 + *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile);
48349 + break;
48350 + case e_FM_PCD_PLCR_SHARED:
48351 + if (relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles)
48352 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48353 + *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]);
48354 + break;
48355 + default:
48356 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type"));
48357 + }
48358 +
48359 + return E_OK;
48360 +}
48361 +
48362 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId)
48363 +{
48364 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48365 + uint16_t swPortIndex = 0;
48366 +
48367 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48368 +
48369 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
48370 +}
48371 +
48372 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
48373 +{
48374 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48375 + uint16_t swPortIndex = 0;
48376 +
48377 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48378 +
48379 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles;
48380 +
48381 +}
48382 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId)
48383 +{
48384 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48385 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT));
48386 +}
48387 +
48388 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId)
48389 +{
48390 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48391 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48392 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48393 +}
48394 +
48395 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg)
48396 +{
48397 +
48398 + if (profileModeReg & FM_PCD_PLCR_PEMODE_PI)
48399 + return TRUE;
48400 + else
48401 + return FALSE;
48402 +}
48403 +
48404 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId)
48405 +{
48406 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48407 + FM_PCD_PLCR_PAR_R |
48408 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48409 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48410 +}
48411 +
48412 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter)
48413 +{
48414 + switch (counter)
48415 + {
48416 + case (e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER):
48417 + return FM_PCD_PLCR_PAR_PWSEL_PEGPC;
48418 + case (e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER):
48419 + return FM_PCD_PLCR_PAR_PWSEL_PEYPC;
48420 + case (e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) :
48421 + return FM_PCD_PLCR_PAR_PWSEL_PERPC;
48422 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) :
48423 + return FM_PCD_PLCR_PAR_PWSEL_PERYPC;
48424 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) :
48425 + return FM_PCD_PLCR_PAR_PWSEL_PERRPC;
48426 + default:
48427 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48428 + return 0;
48429 + }
48430 +}
48431 +
48432 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red)
48433 +{
48434 +
48435 + uint32_t tmpReg32 = 0;
48436 +
48437 + if (green)
48438 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48439 + if (yellow)
48440 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48441 + if (red)
48442 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48443 +
48444 + return tmpReg32;
48445 +}
48446 +
48447 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction)
48448 +{
48449 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48450 +
48451 + /* this routine is protected by calling routine */
48452 +
48453 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48454 +
48455 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction |= requiredAction;
48456 +}
48457 +
48458 +/*********************** End of inter-module routines ************************/
48459 +
48460 +
48461 +/**************************************************/
48462 +/*............Policer API.........................*/
48463 +/**************************************************/
48464 +
48465 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable)
48466 +{
48467 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48468 +
48469 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48470 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48471 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48472 +
48473 + if (!FmIsMaster(p_FmPcd->h_Fm))
48474 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!"));
48475 +
48476 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable;
48477 +
48478 + return E_OK;
48479 +}
48480 +
48481 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles)
48482 +{
48483 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48484 +
48485 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48486 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48487 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48488 +
48489 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles;
48490 +
48491 + return E_OK;
48492 +}
48493 +
48494 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable)
48495 +{
48496 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48497 + uint32_t tmpReg32;
48498 +
48499 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48500 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48501 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48502 +
48503 + if (!FmIsMaster(p_FmPcd->h_Fm))
48504 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!"));
48505 +
48506 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr);
48507 + if (enable)
48508 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
48509 + else
48510 + tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN;
48511 +
48512 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32);
48513 + return E_OK;
48514 +}
48515 +
48516 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
48517 + t_FmPcdPlcrProfileParams *p_ProfileParams)
48518 +{
48519 + t_FmPcd *p_FmPcd;
48520 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48521 + t_FmPcdPlcrProfileRegs plcrProfileReg;
48522 + uint32_t intFlags;
48523 + uint16_t absoluteProfileId;
48524 + t_Error err = E_OK;
48525 + uint32_t tmpReg32;
48526 + t_FmPcdPlcrProfile *p_Profile;
48527 +
48528 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
48529 +
48530 + if (p_ProfileParams->modify)
48531 + {
48532 + p_Profile = (t_FmPcdPlcrProfile *)p_ProfileParams->id.h_Profile;
48533 + p_FmPcd = p_Profile->h_FmPcd;
48534 + absoluteProfileId = p_Profile->absoluteProfileId;
48535 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48536 + {
48537 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48538 + return NULL;
48539 + }
48540 +
48541 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48542 +
48543 + /* Try lock profile using flag */
48544 + if (!PlcrProfileFlagTryLock(p_Profile))
48545 + {
48546 + DBG(TRACE, ("Profile Try Lock - BUSY"));
48547 + /* Signal to caller BUSY condition */
48548 + p_ProfileParams->id.h_Profile = NULL;
48549 + return NULL;
48550 + }
48551 + }
48552 + else
48553 + {
48554 + p_FmPcd = (t_FmPcd*)h_FmPcd;
48555 +
48556 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48557 +
48558 + /* SMP: needs to be protected only if another core now changes the windows */
48559 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(h_FmPcd,
48560 + p_ProfileParams->id.newParams.profileType,
48561 + p_ProfileParams->id.newParams.h_FmPort,
48562 + p_ProfileParams->id.newParams.relativeProfileId,
48563 + &absoluteProfileId);
48564 + if (err)
48565 + {
48566 + REPORT_ERROR(MAJOR, err, NO_MSG);
48567 + return NULL;
48568 + }
48569 +
48570 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48571 + {
48572 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48573 + return NULL;
48574 + }
48575 +
48576 + if (FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
48577 + {
48578 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used"));
48579 + return NULL;
48580 + }
48581 +
48582 + /* initialize profile struct */
48583 + p_Profile = &p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId];
48584 +
48585 + p_Profile->h_FmPcd = p_FmPcd;
48586 + p_Profile->absoluteProfileId = absoluteProfileId;
48587 +
48588 + p_Profile->p_Lock = FmPcdAcquireLock(p_FmPcd);
48589 + if (!p_Profile->p_Lock)
48590 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Policer Profile lock obj!"));
48591 + }
48592 +
48593 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
48594 +
48595 + p_Profile->nextEngineOnGreen = p_ProfileParams->nextEngineOnGreen;
48596 + memcpy(&p_Profile->paramsOnGreen, &(p_ProfileParams->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams));
48597 +
48598 + p_Profile->nextEngineOnYellow = p_ProfileParams->nextEngineOnYellow;
48599 + memcpy(&p_Profile->paramsOnYellow, &(p_ProfileParams->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams));
48600 +
48601 + p_Profile->nextEngineOnRed = p_ProfileParams->nextEngineOnRed;
48602 + memcpy(&p_Profile->paramsOnRed, &(p_ProfileParams->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams));
48603 +
48604 + memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrProfileRegs));
48605 +
48606 + /* build the policer profile registers */
48607 + err = BuildProfileRegs(h_FmPcd, p_ProfileParams, &plcrProfileReg);
48608 + if (err)
48609 + {
48610 + REPORT_ERROR(MAJOR, err, NO_MSG);
48611 + if (p_ProfileParams->modify)
48612 + /* unlock */
48613 + PlcrProfileFlagUnlock(p_Profile);
48614 + if (!p_ProfileParams->modify &&
48615 + p_Profile->p_Lock)
48616 + /* release allocated Profile lock */
48617 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48618 + return NULL;
48619 + }
48620 +
48621 + if (p_FmPcd->h_Hc)
48622 + {
48623 + err = FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, (t_Handle)p_Profile, &plcrProfileReg);
48624 + if (p_ProfileParams->modify)
48625 + PlcrProfileFlagUnlock(p_Profile);
48626 + if (err)
48627 + {
48628 + /* release the allocated scheme lock */
48629 + if (!p_ProfileParams->modify &&
48630 + p_Profile->p_Lock)
48631 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48632 +
48633 + return NULL;
48634 + }
48635 + if (!p_ProfileParams->modify)
48636 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48637 + return (t_Handle)p_Profile;
48638 + }
48639 +
48640 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48641 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL);
48642 +
48643 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48644 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode);
48645 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia);
48646 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia);
48647 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia);
48648 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir);
48649 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs);
48650 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir);
48651 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs);
48652 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts);
48653 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects);
48654 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets);
48655 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc);
48656 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc);
48657 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc);
48658 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc);
48659 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc);
48660 +
48661 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId);
48662 + WritePar(p_FmPcd, tmpReg32);
48663 +
48664 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48665 +
48666 + if (!p_ProfileParams->modify)
48667 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48668 + else
48669 + PlcrProfileFlagUnlock(p_Profile);
48670 +
48671 + return (t_Handle)p_Profile;
48672 +}
48673 +
48674 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile)
48675 +{
48676 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48677 + t_FmPcd *p_FmPcd;
48678 + uint16_t profileIndx;
48679 + uint32_t tmpReg32, intFlags;
48680 + t_Error err;
48681 +
48682 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48683 + p_FmPcd = p_Profile->h_FmPcd;
48684 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48685 +
48686 + profileIndx = p_Profile->absoluteProfileId;
48687 +
48688 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, FALSE);
48689 +
48690 + FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx);
48691 +
48692 + if (p_FmPcd->h_Hc)
48693 + {
48694 + err = FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile);
48695 + if (p_Profile->p_Lock)
48696 + /* release allocated Profile lock */
48697 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48698 +
48699 + return err;
48700 + }
48701 +
48702 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48703 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI);
48704 +
48705 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
48706 + WritePar(p_FmPcd, tmpReg32);
48707 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48708 +
48709 +
48710 + if (p_Profile->p_Lock)
48711 + /* release allocated Profile lock */
48712 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48713 +
48714 + /* we do not memset profile as all its fields are being re-initialized at "set",
48715 + * plus its allocation information is still valid. */
48716 + return E_OK;
48717 +}
48718 +
48719 +/***************************************************/
48720 +/*............Policer Profile Counter..............*/
48721 +/***************************************************/
48722 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
48723 +{
48724 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48725 + t_FmPcd *p_FmPcd;
48726 + uint16_t profileIndx;
48727 + uint32_t intFlags, counterVal = 0;
48728 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48729 +
48730 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48731 + p_FmPcd = p_Profile->h_FmPcd;
48732 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48733 +
48734 + if (p_FmPcd->h_Hc)
48735 + return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter);
48736 +
48737 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48738 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0);
48739 +
48740 + profileIndx = p_Profile->absoluteProfileId;
48741 +
48742 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
48743 + {
48744 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48745 + return 0;
48746 + }
48747 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48748 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
48749 +
48750 + switch (counter)
48751 + {
48752 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48753 + counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc));
48754 + break;
48755 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48756 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc);
48757 + break;
48758 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48759 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc);
48760 + break;
48761 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48762 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc);
48763 + break;
48764 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48765 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc);
48766 + break;
48767 + default:
48768 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48769 + break;
48770 + }
48771 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48772 +
48773 + return counterVal;
48774 +}
48775 +
48776 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
48777 +{
48778 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48779 + t_FmPcd *p_FmPcd;
48780 + uint16_t profileIndx;
48781 + uint32_t tmpReg32, intFlags;
48782 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48783 +
48784 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48785 +
48786 + p_FmPcd = p_Profile->h_FmPcd;
48787 + profileIndx = p_Profile->absoluteProfileId;
48788 +
48789 + if (p_FmPcd->h_Hc)
48790 + return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value);
48791 +
48792 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48793 + SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE);
48794 +
48795 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48796 + switch (counter)
48797 + {
48798 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48799 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value);
48800 + break;
48801 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48802 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value);
48803 + break;
48804 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48805 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value);
48806 + break;
48807 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48808 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value);
48809 + break;
48810 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48811 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value);
48812 + break;
48813 + default:
48814 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48815 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48816 + }
48817 +
48818 + /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM =
48819 + * Profile Number, PWSEL=0xFFFF (select all words).
48820 + */
48821 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48822 + tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter);
48823 + WritePar(p_FmPcd, tmpReg32);
48824 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48825 +
48826 + return E_OK;
48827 +}
48828 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
48829 new file mode 100644
48830 index 00000000..2bb8b969
48831 --- /dev/null
48832 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
48833 @@ -0,0 +1,165 @@
48834 +/*
48835 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48836 + *
48837 + * Redistribution and use in source and binary forms, with or without
48838 + * modification, are permitted provided that the following conditions are met:
48839 + * * Redistributions of source code must retain the above copyright
48840 + * notice, this list of conditions and the following disclaimer.
48841 + * * Redistributions in binary form must reproduce the above copyright
48842 + * notice, this list of conditions and the following disclaimer in the
48843 + * documentation and/or other materials provided with the distribution.
48844 + * * Neither the name of Freescale Semiconductor nor the
48845 + * names of its contributors may be used to endorse or promote products
48846 + * derived from this software without specific prior written permission.
48847 + *
48848 + *
48849 + * ALTERNATIVELY, this software may be distributed under the terms of the
48850 + * GNU General Public License ("GPL") as published by the Free Software
48851 + * Foundation, either version 2 of that License or (at your option) any
48852 + * later version.
48853 + *
48854 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48855 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48856 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48857 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48858 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48859 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48860 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48861 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48862 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48863 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48864 + */
48865 +
48866 +
48867 +/******************************************************************************
48868 + @File fm_plcr.h
48869 +
48870 + @Description FM Policer private header
48871 +*//***************************************************************************/
48872 +#ifndef __FM_PLCR_H
48873 +#define __FM_PLCR_H
48874 +
48875 +#include "std_ext.h"
48876 +
48877 +
48878 +/***********************************************************************/
48879 +/* Policer defines */
48880 +/***********************************************************************/
48881 +
48882 +#define FM_PCD_PLCR_PAR_GO 0x80000000
48883 +#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF
48884 +#define FM_PCD_PLCR_PAR_R 0x40000000
48885 +
48886 +/* shifts */
48887 +#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16
48888 +
48889 +/* masks */
48890 +#define FM_PCD_PLCR_PEMODE_PI 0x80000000
48891 +#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000
48892 +#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000
48893 +#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000
48894 +#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000
48895 +#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000
48896 +#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000
48897 +#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000
48898 +#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000
48899 +#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000
48900 +#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000
48901 +#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000
48902 +#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000
48903 +#define FM_PCD_PLCR_PEMODE_PKT 0x00800000
48904 +#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000
48905 +#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16
48906 +#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000
48907 +#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000
48908 +#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000
48909 +#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000
48910 +#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000
48911 +#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800
48912 +#define FM_PCD_PLCR_PEMODE_TRA 0x00000004
48913 +#define FM_PCD_PLCR_PEMODE_TRB 0x00000002
48914 +#define FM_PCD_PLCR_PEMODE_TRC 0x00000001
48915 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
48916 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
48917 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
48918 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
48919 +
48920 +#define FM_PCD_PLCR_NIA_VALID 0x80000000
48921 +
48922 +#define FM_PCD_PLCR_GCR_EN 0x80000000
48923 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
48924 +#define FM_PCD_PLCR_GCR_DAR 0x20000000
48925 +#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF
48926 +#define FM_PCD_PLCR_NIA_ABS 0x00000100
48927 +
48928 +#define FM_PCD_PLCR_GSR_BSY 0x80000000
48929 +#define FM_PCD_PLCR_GSR_DQS 0x60000000
48930 +#define FM_PCD_PLCR_GSR_RPB 0x20000000
48931 +#define FM_PCD_PLCR_GSR_FQS 0x0C000000
48932 +#define FM_PCD_PLCR_GSR_LPALG 0x0000C000
48933 +#define FM_PCD_PLCR_GSR_LPCA 0x00003000
48934 +#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF
48935 +
48936 +#define FM_PCD_PLCR_EVR_PSIC 0x80000000
48937 +#define FM_PCD_PLCR_EVR_AAC 0x40000000
48938 +
48939 +#define FM_PCD_PLCR_PAR_PSI 0x20000000
48940 +#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000
48941 +/* PWSEL Selctive select options */
48942 +#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */
48943 +#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */
48944 +#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */
48945 +#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */
48946 +#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */
48947 +#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */
48948 +#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */
48949 +#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */
48950 +#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */
48951 +#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */
48952 +#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */
48953 +#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */
48954 +#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */
48955 +#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */
48956 +#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */
48957 +#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */
48958 +
48959 +#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1]
48960 + 1-> 2^N specific locations. */
48961 +#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}.
48962 + 2-> 2^(N-1) base locations. */
48963 +#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}.
48964 + 4-> 2^(N-2) base locations. */
48965 +#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}.
48966 + 8->2^(N-3) base locations. */
48967 +#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}.
48968 + 16-> 2^(N-4) base locations. */
48969 +#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}.
48970 + 32-> 2^(N-5) base locations. */
48971 +#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}.
48972 + 64-> 2^(N-6) base locations. */
48973 +#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}.
48974 + 128-> 2^(N-7) base locations. */
48975 +#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}.
48976 + When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */
48977 +
48978 +#define FM_PCD_PLCR_PMR_V 0x80000000
48979 +#define PLCR_ERR_ECC_CAP 0x80000000
48980 +#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000
48981 +#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0
48982 +#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F
48983 +
48984 +#define PLCR_ERR_UNINIT_CAP 0x80000000
48985 +#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF
48986 +#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000
48987 +#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000
48988 +
48989 +/* shifts */
48990 +#define PLCR_ERR_ECC_PNUM_SHIFT 4
48991 +#define PLCR_ERR_UNINIT_PID_SHIFT 16
48992 +
48993 +#define FM_PCD_PLCR_PMR_BRN_SHIFT 16
48994 +
48995 +#define PLCR_PORT_WINDOW_SIZE(hardwarePortId)
48996 +
48997 +
48998 +#endif /* __FM_PLCR_H */
48999 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
49000 new file mode 100644
49001 index 00000000..ff4f0a2f
49002 --- /dev/null
49003 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
49004 @@ -0,0 +1,423 @@
49005 +/*
49006 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49007 + *
49008 + * Redistribution and use in source and binary forms, with or without
49009 + * modification, are permitted provided that the following conditions are met:
49010 + * * Redistributions of source code must retain the above copyright
49011 + * notice, this list of conditions and the following disclaimer.
49012 + * * Redistributions in binary form must reproduce the above copyright
49013 + * notice, this list of conditions and the following disclaimer in the
49014 + * documentation and/or other materials provided with the distribution.
49015 + * * Neither the name of Freescale Semiconductor nor the
49016 + * names of its contributors may be used to endorse or promote products
49017 + * derived from this software without specific prior written permission.
49018 + *
49019 + *
49020 + * ALTERNATIVELY, this software may be distributed under the terms of the
49021 + * GNU General Public License ("GPL") as published by the Free Software
49022 + * Foundation, either version 2 of that License or (at your option) any
49023 + * later version.
49024 + *
49025 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49026 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49027 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49028 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49029 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49030 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49031 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49032 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49033 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49034 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49035 + */
49036 +
49037 +
49038 +/******************************************************************************
49039 + @File fm_pcd.c
49040 +
49041 + @Description FM PCD ...
49042 +*//***************************************************************************/
49043 +#include <linux/math64.h>
49044 +#include "std_ext.h"
49045 +#include "error_ext.h"
49046 +#include "string_ext.h"
49047 +#include "debug_ext.h"
49048 +#include "net_ext.h"
49049 +
49050 +#include "fm_common.h"
49051 +#include "fm_pcd.h"
49052 +#include "fm_pcd_ipc.h"
49053 +#include "fm_prs.h"
49054 +#include "fsl_fman_prs.h"
49055 +
49056 +
49057 +static void PcdPrsErrorException(t_Handle h_FmPcd)
49058 +{
49059 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49060 + uint32_t event, ev_mask;
49061 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49062 +
49063 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49064 + ev_mask = fman_prs_get_err_ev_mask(PrsRegs);
49065 +
49066 + event = fman_prs_get_err_event(PrsRegs, ev_mask);
49067 +
49068 + fman_prs_ack_err_event(PrsRegs, event);
49069 +
49070 + DBG(TRACE, ("parser error - 0x%08x\n",event));
49071 +
49072 + if(event & FM_PCD_PRS_DOUBLE_ECC)
49073 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
49074 +}
49075 +
49076 +static void PcdPrsException(t_Handle h_FmPcd)
49077 +{
49078 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49079 + uint32_t event, ev_mask;
49080 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49081 +
49082 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49083 + ev_mask = fman_prs_get_expt_ev_mask(PrsRegs);
49084 + event = fman_prs_get_expt_event(PrsRegs, ev_mask);
49085 +
49086 + ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
49087 +
49088 + DBG(TRACE, ("parser event - 0x%08x\n",event));
49089 +
49090 + fman_prs_ack_expt_event(PrsRegs, event);
49091 +
49092 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
49093 +}
49094 +
49095 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
49096 +{
49097 + t_FmPcdPrs *p_FmPcdPrs;
49098 + uintptr_t baseAddr;
49099 +
49100 + UNUSED(p_FmPcd);
49101 + UNUSED(p_FmPcdParams);
49102 +
49103 + p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
49104 + if (!p_FmPcdPrs)
49105 + {
49106 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
49107 + return NULL;
49108 + }
49109 + memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
49110 + fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg);
49111 +
49112 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
49113 + {
49114 + baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
49115 + p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);
49116 + p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
49117 + }
49118 +
49119 + p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat;
49120 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim;
49121 + p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions;
49122 +
49123 + return p_FmPcdPrs;
49124 +}
49125 +
49126 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
49127 + static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH;
49128 +#else
49129 + static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH;
49130 +#endif /* FM_CAPWAP_SUPPORT */
49131 +
49132 +t_Error PrsInit(t_FmPcd *p_FmPcd)
49133 +{
49134 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
49135 + uint32_t *p_TmpCode;
49136 + uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode,
49137 + FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE);
49138 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49139 + uint32_t i;
49140 +
49141 + ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE));
49142 +
49143 + /* nothing to do in guest-partition */
49144 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49145 + return E_OK;
49146 +
49147 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t));
49148 + if (!p_TmpCode)
49149 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
49150 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4));
49151 + memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch));
49152 +
49153 + fman_prs_init(PrsRegs, &p_Param->dfltCfg);
49154 +
49155 + /* register even if no interrupts enabled, to allow future enablement */
49156 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
49157 +
49158 + /* register even if no interrupts enabled, to allow future enablement */
49159 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
49160 +
49161 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
49162 + FmEnableRamsEcc(p_FmPcd->h_Fm);
49163 +
49164 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
49165 + FmEnableRamsEcc(p_FmPcd->h_Fm);
49166 +
49167 + /* load sw parser Ip-Frag patch */
49168 + for (i=0; i<DIV_CEIL(sizeof(swPrsPatch), 4); i++)
49169 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
49170 +
49171 + XX_FreeSmart(p_TmpCode);
49172 +
49173 + return E_OK;
49174 +}
49175 +
49176 +void PrsFree(t_FmPcd *p_FmPcd)
49177 +{
49178 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49179 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
49180 + /* register even if no interrupts enabled, to allow future enablement */
49181 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
49182 +}
49183 +
49184 +void PrsEnable(t_FmPcd *p_FmPcd)
49185 +{
49186 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49187 +
49188 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49189 + fman_prs_enable(PrsRegs);
49190 +}
49191 +
49192 +void PrsDisable(t_FmPcd *p_FmPcd)
49193 +{
49194 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49195 +
49196 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49197 + fman_prs_disable(PrsRegs);
49198 +}
49199 +
49200 +int PrsIsEnabled(t_FmPcd *p_FmPcd)
49201 +{
49202 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49203 +
49204 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49205 + return fman_prs_is_enabled(PrsRegs);
49206 +}
49207 +
49208 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
49209 +{
49210 + struct fman_prs_regs *PrsRegs;
49211 + uint32_t bitMask = 0;
49212 + uint8_t prsPortId;
49213 +
49214 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
49215 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49216 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49217 +
49218 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49219 +
49220 + GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
49221 + GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
49222 +
49223 + if (include)
49224 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
49225 + else
49226 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
49227 +
49228 + fman_prs_set_stst_port_msk(PrsRegs,
49229 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
49230 +
49231 + return E_OK;
49232 +}
49233 +
49234 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
49235 +{
49236 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49237 + t_Error err;
49238 +
49239 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
49240 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49241 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49242 +
49243 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49244 + p_FmPcd->h_IpcSession)
49245 + {
49246 + t_FmPcdIpcPrsIncludePort prsIncludePortParams;
49247 + t_FmPcdIpcMsg msg;
49248 +
49249 + prsIncludePortParams.hardwarePortId = hardwarePortId;
49250 + prsIncludePortParams.include = include;
49251 + memset(&msg, 0, sizeof(msg));
49252 + msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
49253 + memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
49254 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49255 + (uint8_t*)&msg,
49256 + sizeof(msg.msgId) +sizeof(prsIncludePortParams),
49257 + NULL,
49258 + NULL,
49259 + NULL,
49260 + NULL);
49261 + if (err != E_OK)
49262 + RETURN_ERROR(MAJOR, err, NO_MSG);
49263 + return E_OK;
49264 + }
49265 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49266 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49267 + ("running in guest-mode without IPC!"));
49268 +
49269 + return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
49270 +}
49271 +
49272 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
49273 +{
49274 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49275 + t_FmPcdPrsLabelParams *p_Label;
49276 + int i;
49277 +
49278 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
49279 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
49280 +
49281 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49282 + p_FmPcd->h_IpcSession)
49283 + {
49284 + t_Error err = E_OK;
49285 + t_FmPcdIpcSwPrsLable labelParams;
49286 + t_FmPcdIpcMsg msg;
49287 + uint32_t prsOffset = 0;
49288 + t_FmPcdIpcReply reply;
49289 + uint32_t replyLength;
49290 +
49291 + memset(&reply, 0, sizeof(reply));
49292 + memset(&msg, 0, sizeof(msg));
49293 + labelParams.enumHdr = (uint32_t)hdr;
49294 + labelParams.indexPerHdr = indexPerHdr;
49295 + msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
49296 + memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
49297 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
49298 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49299 + (uint8_t*)&msg,
49300 + sizeof(msg.msgId) +sizeof(labelParams),
49301 + (uint8_t*)&reply,
49302 + &replyLength,
49303 + NULL,
49304 + NULL);
49305 + if (err != E_OK)
49306 + RETURN_ERROR(MAJOR, err, NO_MSG);
49307 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
49308 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
49309 +
49310 + memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
49311 + return prsOffset;
49312 + }
49313 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49314 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49315 + ("running in guest-mode without IPC!"));
49316 +
49317 + ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
49318 +
49319 + for (i=0; i<p_FmPcd->p_FmPcdPrs->currLabel; i++)
49320 + {
49321 + p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
49322 +
49323 + if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
49324 + return p_Label->instructionOffset;
49325 + }
49326 +
49327 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
49328 + return (uint32_t)ILLEGAL_BASE;
49329 +}
49330 +
49331 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
49332 +{
49333 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49334 + struct fman_prs_regs *PrsRegs;
49335 +
49336 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
49337 + SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49338 +
49339 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49340 +
49341 +
49342 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49343 + {
49344 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
49345 + return;
49346 + }
49347 +
49348 + fman_prs_set_stst(PrsRegs, enable);
49349 +}
49350 +
49351 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
49352 +{
49353 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49354 + uint32_t *p_LoadTarget;
49355 + uint32_t *p_TmpCode;
49356 + int i;
49357 +
49358 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49359 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
49360 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
49361 + SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
49362 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
49363 +
49364 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49365 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!"));
49366 +
49367 + if (!p_SwPrs->override)
49368 + {
49369 + if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
49370 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
49371 + }
49372 + else
49373 + p_FmPcd->p_FmPcdPrs->currLabel = 0;
49374 +
49375 + if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
49376 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
49377 +
49378 + if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
49379 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
49380 +
49381 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t));
49382 + if (!p_TmpCode)
49383 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
49384 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4));
49385 + memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size);
49386 +
49387 + /* save sw parser labels */
49388 + memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel],
49389 + p_SwPrs->labelsTable,
49390 + p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
49391 + p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
49392 +
49393 + /* load sw parser code */
49394 + p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
49395 +
49396 + for(i=0; i<DIV_CEIL(p_SwPrs->size, 4); i++)
49397 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
49398 +
49399 + p_FmPcd->p_FmPcdPrs->p_CurrSwPrs =
49400 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4);
49401 +
49402 + /* copy data parameters */
49403 + for (i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
49404 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
49405 +
49406 + /* Clear last 4 bytes */
49407 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
49408 +
49409 + XX_FreeSmart(p_TmpCode);
49410 +
49411 + return E_OK;
49412 +}
49413 +
49414 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
49415 +{
49416 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49417 +
49418 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49419 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49420 +
49421 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49422 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
49423 +
49424 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
49425 +
49426 + return E_OK;
49427 +}
49428 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
49429 new file mode 100644
49430 index 00000000..056f225e
49431 --- /dev/null
49432 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
49433 @@ -0,0 +1,316 @@
49434 +/*
49435 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49436 + *
49437 + * Redistribution and use in source and binary forms, with or without
49438 + * modification, are permitted provided that the following conditions are met:
49439 + * * Redistributions of source code must retain the above copyright
49440 + * notice, this list of conditions and the following disclaimer.
49441 + * * Redistributions in binary form must reproduce the above copyright
49442 + * notice, this list of conditions and the following disclaimer in the
49443 + * documentation and/or other materials provided with the distribution.
49444 + * * Neither the name of Freescale Semiconductor nor the
49445 + * names of its contributors may be used to endorse or promote products
49446 + * derived from this software without specific prior written permission.
49447 + *
49448 + *
49449 + * ALTERNATIVELY, this software may be distributed under the terms of the
49450 + * GNU General Public License ("GPL") as published by the Free Software
49451 + * Foundation, either version 2 of that License or (at your option) any
49452 + * later version.
49453 + *
49454 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49455 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49456 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49457 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49458 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49459 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49460 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49461 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49462 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49463 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49464 + */
49465 +
49466 +
49467 +/******************************************************************************
49468 + @File fm_prs.h
49469 +
49470 + @Description FM Parser private header
49471 + *//***************************************************************************/
49472 +#ifndef __FM_PRS_H
49473 +#define __FM_PRS_H
49474 +
49475 +#include "std_ext.h"
49476 +
49477 +/***********************************************************************/
49478 +/* SW parser IP_FRAG patch */
49479 +/***********************************************************************/
49480 +
49481 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
49482 +#define SW_PRS_UDP_LITE_PATCH \
49483 +{\
49484 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49485 + 0x00,0x00,0x50,0x2C,0x40,0x00,0x31,0x92,0x50,0x2C, \
49486 + 0x00,0x88,0x18,0x2F,0x00,0x01,0x1B,0xFE,0x18,0x71, \
49487 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49488 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x60,0x4F, \
49489 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49490 + 0x00,0x01,0x07,0x01,0x60,0x3B,0x00,0x00,0x30,0xD0, \
49491 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49492 + 0x40,0x4C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49493 + 0x00,0x06,0x18,0x5D,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49494 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49495 + 0x00,0x08,0x28,0x1A,0x60,0x37,0x00,0x00,0x30,0xF2, \
49496 + 0x18,0x5D,0x06,0x00,0x29,0x1E,0x30,0xF2,0x2F,0x0E, \
49497 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x2F,0x0E, \
49498 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49499 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49500 + 0x2F,0x0E,0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80, \
49501 + 0x00,0x02,0x00,0x00,0x97,0x9E,0x40,0x7E,0x00,0x08, \
49502 + 0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE,0x00,0x00, \
49503 + 0x9F,0x9E,0x40,0xB3,0x00,0x00,0x02,0x1F,0x00,0x08, \
49504 + 0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0,0x60,0x9F, \
49505 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49506 + 0x00,0x01,0x07,0x01,0x60,0x8B,0x00,0x00,0x30,0xD0, \
49507 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49508 + 0x40,0x9C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49509 + 0x00,0x06,0x18,0xAD,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49510 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49511 + 0x00,0x08,0x28,0x1A,0x60,0x87,0x00,0x00,0x30,0xF2, \
49512 + 0x18,0xAD,0x06,0x00,0x29,0x1E,0x30,0xF2,0x50,0xB3, \
49513 + 0xFF,0xFF,0x18,0xB8,0x08,0x16,0x00,0x54,0x00,0x01, \
49514 + 0x1B,0xFE,0x18,0xC5,0x32,0xF1,0x28,0x5D,0x32,0xF1, \
49515 + 0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00,0x8F,0x9F, \
49516 + 0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01,0x1B,0xFF, \
49517 + 0x00,0x01,0x1B,0xFF \
49518 +}
49519 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
49520 +
49521 +#if (DPAA_VERSION == 10)
49522 +/* Version: 106.1.9 */
49523 +#define SW_PRS_OFFLOAD_PATCH \
49524 +{ \
49525 + 0x31,0x52,0x00,0xDA,0x0A,0x00,0x00,0x00,0x00,0x00, \
49526 + 0x00,0x00,0x43,0x0A,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49527 + 0x00,0x00,0x99,0x00,0x53,0x13,0x00,0x00,0x00,0x00, \
49528 + 0x9F,0x98,0x53,0x13,0x00,0x00,0x1B,0x23,0x33,0xF1, \
49529 + 0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49530 + 0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01, \
49531 + 0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80,0x1F,0xFF, \
49532 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x06,0x00, \
49533 + 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x2F,0x00,0x00, \
49534 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \
49535 + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x00,0x00, \
49536 + 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \
49537 + 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x45,0x00,0x00, \
49538 + 0x30,0x7E,0x43,0x45,0x00,0x3C,0x1B,0x5D,0x32,0x11, \
49539 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x83,0x8F, \
49540 + 0x2F,0x0F,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49541 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49542 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49543 + 0x28,0x43,0x06,0x00,0x1B,0x3E,0x30,0x7E,0x53,0x79, \
49544 + 0x00,0x2B,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49545 + 0x00,0x00,0x87,0x8F,0x28,0x23,0x06,0x00,0x32,0x11, \
49546 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49547 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49548 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x00,0x01, \
49549 + 0x1B,0xFE,0x00,0x00,0x9B,0x8E,0x53,0x90,0x00,0x00, \
49550 + 0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23,0x06,0x00, \
49551 + 0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28,0x00,0x00, \
49552 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49553 + 0x28,0x43,0x06,0x00,0x00,0x01,0x1B,0xFE,0x32,0xC1, \
49554 + 0x00,0x55,0x00,0x28,0x28,0x43,0x1B,0xCF,0x00,0x00, \
49555 + 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \
49556 + 0x28,0x43,0x30,0x7E,0x43,0xBF,0x00,0x2C,0x32,0x11, \
49557 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49558 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49559 + 0x00,0x81,0x00,0x00,0x83,0x8F,0x2F,0x0F,0x06,0x00, \
49560 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01, \
49561 + 0x00,0x81,0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50, \
49562 + 0x00,0x01,0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00, \
49563 + 0x1B,0x9C,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49564 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49565 + 0x00,0x00,0x00,0x01,0x32,0xC1,0x32,0xF0,0x00,0x4A, \
49566 + 0x00,0x80,0x1F,0xFF,0x00,0x01,0x1B,0xFE, \
49567 +}
49568 +
49569 +#else
49570 +#define SW_PRS_OFFLOAD_PATCH \
49571 +{ \
49572 + 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \
49573 + 0x00,0x00,0x51,0x16,0x08,0x4B,0x31,0x53,0x00,0xFB, \
49574 + 0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x2B, \
49575 + 0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00,0x00,0x00, \
49576 + 0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA,0x0A,0x00, \
49577 + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x20,0x00,0x00, \
49578 + 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x51,0x29, \
49579 + 0x00,0x00,0x00,0x00,0x9F,0x98,0x51,0x29,0x00,0x00, \
49580 + 0x19,0x44,0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F, \
49581 + 0x00,0x20,0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00, \
49582 + 0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3, \
49583 + 0x29,0x8F,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49584 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49585 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x00,0x01,0x1B,0xFE, \
49586 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49587 + 0x00,0x00,0x51,0x52,0x40,0x00,0x31,0x92,0x51,0x52, \
49588 + 0x00,0x88,0x19,0x55,0x08,0x05,0x00,0x00,0x19,0x99, \
49589 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49590 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x61,0x75, \
49591 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49592 + 0x00,0x01,0x07,0x01,0x61,0x61,0x00,0x00,0x30,0xD0, \
49593 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49594 + 0x41,0x72,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49595 + 0x00,0x06,0x19,0x83,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49596 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49597 + 0x00,0x08,0x28,0x1A,0x61,0x5D,0x00,0x00,0x30,0xF2, \
49598 + 0x19,0x83,0x06,0x00,0x29,0x1E,0x30,0xF2,0x29,0x0E, \
49599 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x29,0x0E, \
49600 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49601 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49602 + 0x29,0x0E,0x08,0x05,0x00,0x01,0x31,0x52,0x00,0xDA, \
49603 + 0x0E,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xAF, \
49604 + 0x04,0x4B,0x31,0x53,0x00,0xFB,0xFF,0xF0,0x00,0x00, \
49605 + 0x00,0x00,0x00,0x00,0x29,0x2B,0x33,0xF1,0x00,0xFB, \
49606 + 0x00,0xDF,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7F, \
49607 + 0x31,0x52,0x00,0xDA,0x06,0x00,0x00,0x00,0x00,0x00, \
49608 + 0x00,0x00,0x41,0xB9,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49609 + 0x31,0x52,0x00,0xDA,0x00,0x40,0x00,0x00,0x00,0x00, \
49610 + 0x00,0x00,0x42,0x06,0x00,0x00,0x00,0x00,0x9B,0x8F, \
49611 + 0x28,0x01,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49612 + 0x30,0x00,0x41,0xEB,0x00,0x2C,0x32,0x11,0x32,0xC0, \
49613 + 0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F,0x28,0x23, \
49614 + 0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49615 + 0x00,0x00,0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11, \
49616 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49617 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49618 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x19,0xC8, \
49619 + 0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F,0x00,0x20, \
49620 + 0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00,0x01,0x00, \
49621 + 0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3,0x29,0x8F, \
49622 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49623 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49624 + 0x00,0x01,0x1B,0xFE,0x30,0x50,0x52,0x0B,0x00,0x00, \
49625 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49626 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x42,0x18, \
49627 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49628 + 0x00,0x00,0x9F,0x9E,0x42,0x4D,0x00,0x00,0x02,0x1F, \
49629 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49630 + 0x62,0x39,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49631 + 0x00,0x52,0x00,0x01,0x07,0x01,0x62,0x25,0x00,0x00, \
49632 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49633 + 0x00,0x00,0x42,0x36,0x00,0x00,0x02,0x8F,0x00,0x00, \
49634 + 0x30,0xF2,0x00,0x06,0x1A,0x47,0x00,0x00,0x9F,0xFF, \
49635 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49636 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x62,0x21,0x00,0x00, \
49637 + 0x30,0xF2,0x1A,0x47,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49638 + 0x52,0x4D,0xFF,0xFF,0x1A,0x52,0x08,0x16,0x00,0x54, \
49639 + 0x00,0x01,0x1B,0xFE,0x1A,0x5F,0x32,0xF1,0x28,0x5D, \
49640 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49641 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49642 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x31,0x52,0x00,0xDA, \
49643 + 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x6D, \
49644 + 0x40,0x00,0x31,0x92,0x52,0x6D,0x00,0x88,0x1A,0x70, \
49645 + 0x08,0x05,0x00,0x00,0x1A,0xB4,0x02,0x1F,0x00,0x08, \
49646 + 0x00,0x83,0x02,0x1F,0x00,0x20,0x28,0x1B,0x00,0x05, \
49647 + 0x29,0x1F,0x30,0xD0,0x62,0x90,0x00,0x07,0x00,0x05, \
49648 + 0x00,0x00,0xC3,0x8F,0x00,0x52,0x00,0x01,0x07,0x01, \
49649 + 0x62,0x7C,0x00,0x00,0x30,0xD0,0x00,0xDA,0x00,0x01, \
49650 + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x8D,0x00,0x00, \
49651 + 0x02,0x8F,0x00,0x00,0x30,0xF2,0x00,0x06,0x1A,0x9E, \
49652 + 0x00,0x00,0x9F,0xFF,0x30,0xF2,0x00,0x06,0x29,0x1E, \
49653 + 0x07,0x08,0x30,0xD0,0x00,0x52,0x00,0x08,0x28,0x1A, \
49654 + 0x62,0x78,0x00,0x00,0x30,0xF2,0x1A,0x9E,0x06,0x00, \
49655 + 0x29,0x1E,0x30,0xF2,0x29,0x0E,0x30,0x72,0x00,0x00, \
49656 + 0x9B,0x8F,0x00,0x06,0x29,0x0E,0x32,0xF1,0x32,0xB0, \
49657 + 0x00,0x4F,0x00,0x57,0x00,0x28,0x00,0x00,0x97,0x9E, \
49658 + 0x00,0x4E,0x30,0x72,0x00,0x06,0x29,0x0E,0x08,0x05, \
49659 + 0x00,0x01,0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00, \
49660 + 0x00,0x00,0x00,0x00,0x52,0xCA,0x04,0x4B,0x31,0x53, \
49661 + 0x00,0xFB,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, \
49662 + 0x29,0x2B,0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00, \
49663 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA, \
49664 + 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xD4, \
49665 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA, \
49666 + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x37, \
49667 + 0x00,0x00,0x00,0x00,0x9B,0x8F,0x28,0x01,0x32,0xC1, \
49668 + 0x00,0x55,0x00,0x28,0x28,0x43,0x30,0x00,0x42,0xEA, \
49669 + 0x00,0x00,0x30,0x00,0x42,0xEA,0x00,0x3C,0x1B,0x02, \
49670 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00, \
49671 + 0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11,0x32,0xC0, \
49672 + 0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11, \
49673 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49674 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1A,0xE3,0x30,0x00, \
49675 + 0x43,0x20,0x00,0x2B,0x00,0x00,0x9B,0x8E,0x43,0x0E, \
49676 + 0x00,0x00,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49677 + 0x1B,0x1F,0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23, \
49678 + 0x06,0x00,0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28, \
49679 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49680 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1B,0x37,0x32,0x11, \
49681 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49682 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49683 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49684 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49685 + 0x28,0x43,0x06,0x00,0x30,0x50,0x53,0x3C,0x00,0x00, \
49686 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49687 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x43,0x49, \
49688 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49689 + 0x00,0x00,0x9F,0x9E,0x43,0x7E,0x00,0x00,0x02,0x1F, \
49690 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49691 + 0x63,0x6A,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49692 + 0x00,0x52,0x00,0x01,0x07,0x01,0x63,0x56,0x00,0x00, \
49693 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49694 + 0x00,0x00,0x43,0x67,0x00,0x00,0x02,0x8F,0x00,0x00, \
49695 + 0x30,0xF2,0x00,0x06,0x1B,0x78,0x00,0x00,0x9F,0xFF, \
49696 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49697 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x63,0x52,0x00,0x00, \
49698 + 0x30,0xF2,0x1B,0x78,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49699 + 0x53,0x7E,0xFF,0xFF,0x1B,0x83,0x08,0x16,0x00,0x54, \
49700 + 0x00,0x01,0x1B,0xFE,0x1B,0x90,0x32,0xF1,0x28,0x5D, \
49701 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49702 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49703 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x08,0x07,0x00,0x02, \
49704 + 0x00,0x00,0x8D,0x80,0x53,0x9C,0x00,0x01,0x30,0x71, \
49705 + 0x00,0x55,0x00,0x01,0x28,0x0F,0x00,0x00,0x8D,0x00, \
49706 + 0x53,0xA4,0x00,0x01,0x30,0x71,0x00,0x55,0x00,0x01, \
49707 + 0x28,0x0F,0x00,0x00,0x83,0x8E,0x53,0xB9,0x00,0x00, \
49708 + 0x00,0x00,0x86,0x08,0x30,0x71,0x00,0x7B,0x03,0xB9, \
49709 + 0x33,0xB4,0x00,0xDA,0xFF,0xFF,0x00,0x0F,0x00,0x00, \
49710 + 0x00,0x00,0x00,0x00,0x86,0x09,0x01,0x03,0x00,0x7D, \
49711 + 0x03,0xB9,0x1B,0xC8,0x33,0xD1,0x00,0xF9,0x00,0x10, \
49712 + 0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7B,0x09,0x5F, \
49713 + 0x00,0x1A,0x00,0x00,0x09,0x4F,0x00,0x1A,0x00,0x00, \
49714 + 0x00,0x01,0x1B,0xFF,0x00,0x00,0x8C,0x00,0x53,0xF0, \
49715 + 0x00,0x01,0x34,0xF5,0x00,0xFB,0xFF,0xFF,0x00,0x7F, \
49716 + 0x00,0x00,0x00,0x00,0x2A,0x9F,0x00,0x00,0x93,0x8F, \
49717 + 0x28,0x49,0x00,0x00,0x97,0x8F,0x28,0x4B,0x34,0x61, \
49718 + 0x28,0x4D,0x34,0x71,0x28,0x4F,0x34,0xB7,0x00,0xF9, \
49719 + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97, \
49720 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49721 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49722 + 0x00,0x01,0x1B,0xFF,0x00,0x01,0x1B,0xFF, \
49723 +}
49724 +#endif /* (DPAA_VERSION == 10) */
49725 +
49726 +/****************************/
49727 +/* Parser defines */
49728 +/****************************/
49729 +#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at
49730 + the end of the SW parser area */
49731 +
49732 +/* masks */
49733 +#define PRS_ERR_CAP 0x80000000
49734 +#define PRS_ERR_TYPE_DOUBLE 0x40000000
49735 +#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000
49736 +#define PRS_ERR_ADDR_MASK 0x000001FF
49737 +
49738 +/* others */
49739 +#define PRS_MAX_CYCLE_LIMIT 8191
49740 +#define PRS_SW_DATA 0x00000800
49741 +#define PRS_REGS_OFFSET 0x00000840
49742 +
49743 +#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \
49744 + prsPortId = (uint8_t)(hardwarePortId & 0x0f)
49745 +
49746 +#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \
49747 + bitMask = 0x80000000>>prsPortId
49748 +
49749 +#endif /* __FM_PRS_H */
49750 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
49751 new file mode 100644
49752 index 00000000..ee82f730
49753 --- /dev/null
49754 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
49755 @@ -0,0 +1,984 @@
49756 +/*
49757 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49758 + *
49759 + * Redistribution and use in source and binary forms, with or without
49760 + * modification, are permitted provided that the following conditions are met:
49761 + * * Redistributions of source code must retain the above copyright
49762 + * notice, this list of conditions and the following disclaimer.
49763 + * * Redistributions in binary form must reproduce the above copyright
49764 + * notice, this list of conditions and the following disclaimer in the
49765 + * documentation and/or other materials provided with the distribution.
49766 + * * Neither the name of Freescale Semiconductor nor the
49767 + * names of its contributors may be used to endorse or promote products
49768 + * derived from this software without specific prior written permission.
49769 + *
49770 + *
49771 + * ALTERNATIVELY, this software may be distributed under the terms of the
49772 + * GNU General Public License ("GPL") as published by the Free Software
49773 + * Foundation, either version 2 of that License or (at your option) any
49774 + * later version.
49775 + *
49776 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49777 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49778 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49779 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49780 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49781 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49782 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49783 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49784 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49785 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49786 + */
49787 +
49788 +
49789 +/******************************************************************************
49790 + @File fm_replic.c
49791 +
49792 + @Description FM frame replicator
49793 +*//***************************************************************************/
49794 +#include "std_ext.h"
49795 +#include "error_ext.h"
49796 +#include "string_ext.h"
49797 +#include "debug_ext.h"
49798 +#include "fm_pcd_ext.h"
49799 +#include "fm_muram_ext.h"
49800 +#include "fm_common.h"
49801 +#include "fm_hc.h"
49802 +#include "fm_replic.h"
49803 +#include "fm_cc.h"
49804 +#include "list_ext.h"
49805 +
49806 +
49807 +/****************************************/
49808 +/* static functions */
49809 +/****************************************/
49810 +static uint8_t GetMemberPosition(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49811 + uint32_t memberIndex,
49812 + bool isAddOperation)
49813 +{
49814 + uint8_t memberPosition;
49815 + uint32_t lastMemberIndex;
49816 +
49817 + ASSERT_COND(p_ReplicGroup);
49818 +
49819 + /* the last member index is different between add and remove operation -
49820 + in case of remove - this is exactly the last member index
49821 + in case of add - this is the last member index + 1 - e.g.
49822 + if we have 4 members, the index of the actual last member is 3(because the
49823 + index starts from 0) therefore in order to add a new member as the last
49824 + member we shall use memberIndex = 4 and not 3
49825 + */
49826 + if (isAddOperation)
49827 + lastMemberIndex = p_ReplicGroup->numOfEntries;
49828 + else
49829 + lastMemberIndex = p_ReplicGroup->numOfEntries-1;
49830 +
49831 + /* last */
49832 + if (memberIndex == lastMemberIndex)
49833 + memberPosition = FRM_REPLIC_LAST_MEMBER_INDEX;
49834 + else
49835 + {
49836 + /* first */
49837 + if (memberIndex == 0)
49838 + memberPosition = FRM_REPLIC_FIRST_MEMBER_INDEX;
49839 + else
49840 + {
49841 + /* middle */
49842 + ASSERT_COND(memberIndex < lastMemberIndex);
49843 + memberPosition = FRM_REPLIC_MIDDLE_MEMBER_INDEX;
49844 + }
49845 + }
49846 + return memberPosition;
49847 +}
49848 +
49849 +static t_Error MemberCheckParams(t_Handle h_FmPcd,
49850 + t_FmPcdCcNextEngineParams *p_MemberParams)
49851 +{
49852 + t_Error err;
49853 +
49854 +
49855 + if ((p_MemberParams->nextEngine != e_FM_PCD_DONE) &&
49856 + (p_MemberParams->nextEngine != e_FM_PCD_KG) &&
49857 + (p_MemberParams->nextEngine != e_FM_PCD_PLCR))
49858 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine of a member should be MatchTable(cc) or Done or Policer"));
49859 +
49860 + /* check the regular parameters of the next engine */
49861 + err = ValidateNextEngineParams(h_FmPcd, p_MemberParams, e_FM_PCD_CC_STATS_MODE_NONE);
49862 + if (err)
49863 + RETURN_ERROR(MAJOR, err, ("member next engine parameters"));
49864 +
49865 + return E_OK;
49866 +}
49867 +
49868 +static t_Error CheckParams(t_Handle h_FmPcd,
49869 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
49870 +{
49871 + int i;
49872 + t_Error err;
49873 +
49874 + /* check that max num of entries is at least 2 */
49875 + if (!IN_RANGE(2, p_ReplicGroupParam->maxNumOfEntries, FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES))
49876 + 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));
49877 +
49878 + /* check that number of entries is greater than zero */
49879 + if (!p_ReplicGroupParam->numOfEntries)
49880 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOFEntries in the frame replicator group should be greater than zero"));
49881 +
49882 + /* check that max num of entries is equal or greater than number of entries */
49883 + if (p_ReplicGroupParam->maxNumOfEntries < p_ReplicGroupParam->numOfEntries)
49884 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfEntries should be equal or greater than numOfEntries"));
49885 +
49886 + for (i=0; i<p_ReplicGroupParam->numOfEntries; i++)
49887 + {
49888 + err = MemberCheckParams(h_FmPcd, &p_ReplicGroupParam->nextEngineParams[i]);
49889 + if (err)
49890 + RETURN_ERROR(MAJOR, err, ("member check parameters"));
49891 + }
49892 + return E_OK;
49893 +}
49894 +
49895 +static t_FmPcdFrmReplicMember *GetAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49896 +{
49897 + t_FmPcdFrmReplicMember *p_ReplicMember = NULL;
49898 + t_List *p_Next;
49899 +
49900 + if (!LIST_IsEmpty(&p_ReplicGroup->availableMembersList))
49901 + {
49902 + p_Next = LIST_FIRST(&p_ReplicGroup->availableMembersList);
49903 + p_ReplicMember = LIST_OBJECT(p_Next, t_FmPcdFrmReplicMember, node);
49904 + ASSERT_COND(p_ReplicMember);
49905 + LIST_DelAndInit(p_Next);
49906 + }
49907 + return p_ReplicMember;
49908 +}
49909 +
49910 +static void PutAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49911 + t_FmPcdFrmReplicMember *p_ReplicMember)
49912 +{
49913 + LIST_AddToTail(&p_ReplicMember->node, &p_ReplicGroup->availableMembersList);
49914 +}
49915 +
49916 +static void AddMemberToList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49917 + t_FmPcdFrmReplicMember *p_CurrentMember,
49918 + t_List *p_ListHead)
49919 +{
49920 + LIST_Add(&p_CurrentMember->node, p_ListHead);
49921 +
49922 + p_ReplicGroup->numOfEntries++;
49923 +}
49924 +
49925 +static void RemoveMemberFromList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49926 + t_FmPcdFrmReplicMember *p_CurrentMember)
49927 +{
49928 + ASSERT_COND(p_ReplicGroup->numOfEntries);
49929 + LIST_DelAndInit(&p_CurrentMember->node);
49930 + p_ReplicGroup->numOfEntries--;
49931 +}
49932 +
49933 +static void LinkSourceToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49934 + t_AdOfTypeContLookup *p_SourceTd,
49935 + t_FmPcdFrmReplicMember *p_ReplicMember)
49936 +{
49937 + t_FmPcd *p_FmPcd;
49938 +
49939 + ASSERT_COND(p_SourceTd);
49940 + ASSERT_COND(p_ReplicMember);
49941 + ASSERT_COND(p_ReplicGroup);
49942 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49943 +
49944 + /* Link the first member in the group to the source TD */
49945 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49946 +
49947 + WRITE_UINT32(p_SourceTd->matchTblPtr,
49948 + (uint32_t)(XX_VirtToPhys(p_ReplicMember->p_MemberAd) -
49949 + p_FmPcd->physicalMuramBase));
49950 +}
49951 +
49952 +static void LinkMemberToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49953 + t_FmPcdFrmReplicMember *p_CurrentMember,
49954 + t_FmPcdFrmReplicMember *p_NextMember)
49955 +{
49956 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_CurrentMember->p_MemberAd;
49957 + t_AdOfTypeResult *p_NextReplicAd = NULL;
49958 + t_FmPcd *p_FmPcd;
49959 + uint32_t offset = 0;
49960 +
49961 + /* Check if the next member exists or it's NULL (- means that this is the last member) */
49962 + if (p_NextMember)
49963 + {
49964 + p_NextReplicAd = (t_AdOfTypeResult*)p_NextMember->p_MemberAd;
49965 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49966 + offset = (XX_VirtToPhys(p_NextReplicAd) - (p_FmPcd->physicalMuramBase));
49967 + offset = ((offset>>NEXT_FRM_REPLIC_ADDR_SHIFT)<< NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT);
49968 + }
49969 +
49970 + /* link the current AD to point to the AD of the next member */
49971 + WRITE_UINT32(p_CurrReplicAd->res, offset);
49972 +}
49973 +
49974 +static t_Error ModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49975 + void *p_OldDescriptor,
49976 + void *p_NewDescriptor)
49977 +{
49978 + t_Handle h_Hc;
49979 + t_Error err;
49980 + t_FmPcd *p_FmPcd;
49981 +
49982 + ASSERT_COND(p_ReplicGroup);
49983 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49984 + ASSERT_COND(p_OldDescriptor);
49985 + ASSERT_COND(p_NewDescriptor);
49986 +
49987 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49988 + h_Hc = FmPcdGetHcHandle(p_FmPcd);
49989 + if (!h_Hc)
49990 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Host command"));
49991 +
49992 + err = FmHcPcdCcDoDynamicChange(h_Hc,
49993 + (uint32_t)(XX_VirtToPhys(p_OldDescriptor) - p_FmPcd->physicalMuramBase),
49994 + (uint32_t)(XX_VirtToPhys(p_NewDescriptor) - p_FmPcd->physicalMuramBase));
49995 + if (err)
49996 + RETURN_ERROR(MAJOR, err, ("Dynamic change host command"));
49997 +
49998 + return E_OK;
49999 +}
50000 +
50001 +static void FillReplicAdOfTypeResult(void *p_ReplicAd, bool last)
50002 +{
50003 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_ReplicAd;
50004 + uint32_t tmp;
50005 +
50006 + tmp = GET_UINT32(p_CurrReplicAd->plcrProfile);
50007 + if (last)
50008 + /* clear the NL bit in case it's the last member in the group*/
50009 + WRITE_UINT32(p_CurrReplicAd->plcrProfile,(tmp & ~FRM_REPLIC_NL_BIT));
50010 + else
50011 + /* set the NL bit in case it's not the last member in the group */
50012 + WRITE_UINT32(p_CurrReplicAd->plcrProfile, (tmp |FRM_REPLIC_NL_BIT));
50013 +
50014 + /* set FR bit in the action descriptor */
50015 + tmp = GET_UINT32(p_CurrReplicAd->nia);
50016 + WRITE_UINT32(p_CurrReplicAd->nia,
50017 + (tmp | FRM_REPLIC_FR_BIT | FM_PCD_AD_RESULT_EXTENDED_MODE ));
50018 +}
50019 +
50020 +static void BuildSourceTd(void *p_Ad)
50021 +{
50022 + t_AdOfTypeContLookup *p_SourceTd;
50023 +
50024 + ASSERT_COND(p_Ad);
50025 +
50026 + p_SourceTd = (t_AdOfTypeContLookup *)p_Ad;
50027 +
50028 + IOMemSet32((uint8_t*)p_SourceTd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50029 +
50030 + /* initialize the source table descriptor */
50031 + WRITE_UINT32(p_SourceTd->ccAdBase, FM_PCD_AD_CONT_LOOKUP_TYPE);
50032 + WRITE_UINT32(p_SourceTd->pcAndOffsets, FRM_REPLIC_SOURCE_TD_OPCODE);
50033 +}
50034 +
50035 +static t_Error BuildShadowAndModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50036 + t_FmPcdFrmReplicMember *p_NextMember,
50037 + t_FmPcdFrmReplicMember *p_CurrentMember,
50038 + bool sourceDescriptor,
50039 + bool last)
50040 +{
50041 + t_FmPcd *p_FmPcd;
50042 + t_FmPcdFrmReplicMember shadowMember;
50043 + t_Error err;
50044 +
50045 + ASSERT_COND(p_ReplicGroup);
50046 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
50047 +
50048 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50049 + ASSERT_COND(p_FmPcd->p_CcShadow);
50050 +
50051 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
50052 + return ERROR_CODE(E_BUSY);
50053 +
50054 + if (sourceDescriptor)
50055 + {
50056 + BuildSourceTd(p_FmPcd->p_CcShadow);
50057 + LinkSourceToMember(p_ReplicGroup, p_FmPcd->p_CcShadow, p_NextMember);
50058 +
50059 + /* Modify the source table descriptor according to the prepared shadow descriptor */
50060 + err = ModifyDescriptor(p_ReplicGroup,
50061 + p_ReplicGroup->p_SourceTd,
50062 + p_FmPcd->p_CcShadow/* new prepared source td */);
50063 +
50064 + RELEASE_LOCK(p_FmPcd->shadowLock);
50065 + if (err)
50066 + RETURN_ERROR(MAJOR, err, ("Modify source Descriptor in BuildShadowAndModifyDescriptor"));
50067 +
50068 + }
50069 + else
50070 + {
50071 + IO2IOCpy32(p_FmPcd->p_CcShadow,
50072 + p_CurrentMember->p_MemberAd,
50073 + FM_PCD_CC_AD_ENTRY_SIZE);
50074 +
50075 + /* update the last bit in the shadow ad */
50076 + FillReplicAdOfTypeResult(p_FmPcd->p_CcShadow, last);
50077 +
50078 + shadowMember.p_MemberAd = p_FmPcd->p_CcShadow;
50079 +
50080 + /* update the next FR member index */
50081 + LinkMemberToMember(p_ReplicGroup, &shadowMember, p_NextMember);
50082 +
50083 + /* Modify the next member according to the prepared shadow descriptor */
50084 + err = ModifyDescriptor(p_ReplicGroup,
50085 + p_CurrentMember->p_MemberAd,
50086 + p_FmPcd->p_CcShadow);
50087 +
50088 + RELEASE_LOCK(p_FmPcd->shadowLock);
50089 + if (err)
50090 + RETURN_ERROR(MAJOR, err, ("Modify Descriptor in BuildShadowAndModifyDescriptor"));
50091 + }
50092 +
50093 +
50094 + return E_OK;
50095 +}
50096 +
50097 +static t_FmPcdFrmReplicMember* GetMemberByIndex(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50098 + uint16_t memberIndex)
50099 +{
50100 + int i=0;
50101 + t_List *p_Pos;
50102 + t_FmPcdFrmReplicMember *p_Member = NULL;
50103 +
50104 + LIST_FOR_EACH(p_Pos, &p_ReplicGroup->membersList)
50105 + {
50106 + if (i == memberIndex)
50107 + {
50108 + p_Member = LIST_OBJECT(p_Pos, t_FmPcdFrmReplicMember, node);
50109 + return p_Member;
50110 + }
50111 + i++;
50112 + }
50113 + return p_Member;
50114 +}
50115 +
50116 +static t_Error AllocMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
50117 +{
50118 + t_FmPcdFrmReplicMember *p_CurrentMember;
50119 + t_Handle h_Muram;
50120 +
50121 + ASSERT_COND(p_ReplicGroup);
50122 +
50123 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50124 + ASSERT_COND(h_Muram);
50125 +
50126 + /* Initialize an internal structure of a member to add to the available members list */
50127 + p_CurrentMember = (t_FmPcdFrmReplicMember *)XX_Malloc(sizeof(t_FmPcdFrmReplicMember));
50128 + if (!p_CurrentMember)
50129 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Frame replicator member"));
50130 +
50131 + memset(p_CurrentMember, 0 ,sizeof(t_FmPcdFrmReplicMember));
50132 +
50133 + /* Allocate the member AD */
50134 + p_CurrentMember->p_MemberAd =
50135 + (t_AdOfTypeResult*)FM_MURAM_AllocMem(h_Muram,
50136 + FM_PCD_CC_AD_ENTRY_SIZE,
50137 + FM_PCD_CC_AD_TABLE_ALIGN);
50138 + if (!p_CurrentMember->p_MemberAd)
50139 + {
50140 + XX_Free(p_CurrentMember);
50141 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("member AD table"));
50142 + }
50143 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50144 +
50145 + /* Add the new member to the available members list */
50146 + LIST_AddToTail(&p_CurrentMember->node, &(p_ReplicGroup->availableMembersList));
50147 +
50148 + return E_OK;
50149 +}
50150 +
50151 +static t_FmPcdFrmReplicMember* InitMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50152 + t_FmPcdCcNextEngineParams *p_MemberParams,
50153 + bool last)
50154 +{
50155 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL;
50156 +
50157 + ASSERT_COND(p_ReplicGroup);
50158 +
50159 + /* Get an available member from the internal members list */
50160 + p_CurrentMember = GetAvailableMember(p_ReplicGroup);
50161 + if (!p_CurrentMember)
50162 + {
50163 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Available member"));
50164 + return NULL;
50165 + }
50166 + p_CurrentMember->h_Manip = NULL;
50167 +
50168 + /* clear the Ad of the new member */
50169 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50170 +
50171 + INIT_LIST(&p_CurrentMember->node);
50172 +
50173 + /* Initialize the Ad of the member */
50174 + NextStepAd(p_CurrentMember->p_MemberAd,
50175 + NULL,
50176 + p_MemberParams,
50177 + p_ReplicGroup->h_FmPcd);
50178 +
50179 + /* save Manip handle (for free needs) */
50180 + if (p_MemberParams->h_Manip)
50181 + p_CurrentMember->h_Manip = p_MemberParams->h_Manip;
50182 +
50183 + /* Initialize the relevant frame replicator fields in the AD */
50184 + FillReplicAdOfTypeResult(p_CurrentMember->p_MemberAd, last);
50185 +
50186 + return p_CurrentMember;
50187 +}
50188 +
50189 +static void FreeMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50190 + t_FmPcdFrmReplicMember *p_Member)
50191 +{
50192 + /* Note: Can't free the member AD just returns the member to the available
50193 + member list - therefore only memset the AD */
50194 +
50195 + /* zero the AD */
50196 + IOMemSet32(p_Member->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50197 +
50198 +
50199 + /* return the member to the available members list */
50200 + PutAvailableMember(p_ReplicGroup, p_Member);
50201 +}
50202 +
50203 +static t_Error RemoveMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50204 + uint16_t memberIndex)
50205 +{
50206 + t_FmPcd *p_FmPcd = NULL;
50207 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL, *p_PreviousMember = NULL, *p_NextMember = NULL;
50208 + t_Error err;
50209 + uint8_t memberPosition;
50210 +
50211 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50212 + ASSERT_COND(p_FmPcd);
50213 + UNUSED(p_FmPcd);
50214 +
50215 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50216 + ASSERT_COND(p_CurrentMember);
50217 +
50218 + /* determine the member position in the group */
50219 + memberPosition = GetMemberPosition(p_ReplicGroup,
50220 + memberIndex,
50221 + FALSE/*remove operation*/);
50222 +
50223 + switch (memberPosition)
50224 + {
50225 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
50226 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
50227 + ASSERT_COND(p_NextMember);
50228 +
50229 + /* update the source td itself by using a host command */
50230 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50231 + p_NextMember,
50232 + NULL,
50233 + TRUE/*sourceDescriptor*/,
50234 + FALSE/*last*/);
50235 + break;
50236 +
50237 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50238 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50239 + ASSERT_COND(p_PreviousMember);
50240 +
50241 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
50242 + ASSERT_COND(p_NextMember);
50243 +
50244 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50245 + p_NextMember,
50246 + p_PreviousMember,
50247 + FALSE/*sourceDescriptor*/,
50248 + FALSE/*last*/);
50249 +
50250 + break;
50251 +
50252 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50253 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50254 + ASSERT_COND(p_PreviousMember);
50255 +
50256 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50257 + NULL,
50258 + p_PreviousMember,
50259 + FALSE/*sourceDescriptor*/,
50260 + TRUE/*last*/);
50261 + break;
50262 +
50263 + default:
50264 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in remove member"));
50265 + }
50266 +
50267 + if (err)
50268 + RETURN_ERROR(MAJOR, err, NO_MSG);
50269 +
50270 + if (p_CurrentMember->h_Manip)
50271 + {
50272 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
50273 + p_CurrentMember->h_Manip = NULL;
50274 + }
50275 +
50276 + /* remove the member from the driver internal members list */
50277 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
50278 +
50279 + /* return the member to the available members list */
50280 + FreeMember(p_ReplicGroup, p_CurrentMember);
50281 +
50282 + return E_OK;
50283 +}
50284 +
50285 +static void DeleteGroup(t_FmPcdFrmReplicGroup *p_ReplicGroup)
50286 +{
50287 + int i, j;
50288 + t_Handle h_Muram;
50289 + t_FmPcdFrmReplicMember *p_Member, *p_CurrentMember;
50290 +
50291 + if (p_ReplicGroup)
50292 + {
50293 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
50294 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50295 + ASSERT_COND(h_Muram);
50296 +
50297 + /* free the source table descriptor */
50298 + if (p_ReplicGroup->p_SourceTd)
50299 + {
50300 + FM_MURAM_FreeMem(h_Muram, p_ReplicGroup->p_SourceTd);
50301 + p_ReplicGroup->p_SourceTd = NULL;
50302 + }
50303 +
50304 + /* Remove all members from the members linked list (hw and sw) and
50305 + return the members to the available members list */
50306 + if (p_ReplicGroup->numOfEntries)
50307 + {
50308 + j = p_ReplicGroup->numOfEntries-1;
50309 +
50310 + /* manually removal of the member because there are no owners of
50311 + this group */
50312 + for (i=j; i>=0; i--)
50313 + {
50314 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)i/*memberIndex*/);
50315 + ASSERT_COND(p_CurrentMember);
50316 +
50317 + if (p_CurrentMember->h_Manip)
50318 + {
50319 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
50320 + p_CurrentMember->h_Manip = NULL;
50321 + }
50322 +
50323 + /* remove the member from the internal driver members list */
50324 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
50325 +
50326 + /* return the member to the available members list */
50327 + FreeMember(p_ReplicGroup, p_CurrentMember);
50328 + }
50329 + }
50330 +
50331 + /* Free members AD */
50332 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50333 + {
50334 + p_Member = GetAvailableMember(p_ReplicGroup);
50335 + ASSERT_COND(p_Member);
50336 + if (p_Member->p_MemberAd)
50337 + {
50338 + FM_MURAM_FreeMem(h_Muram, p_Member->p_MemberAd);
50339 + p_Member->p_MemberAd = NULL;
50340 + }
50341 + XX_Free(p_Member);
50342 + }
50343 +
50344 + /* release the group lock */
50345 + if (p_ReplicGroup->p_Lock)
50346 + FmPcdReleaseLock(p_ReplicGroup->h_FmPcd, p_ReplicGroup->p_Lock);
50347 +
50348 + /* free the replicator group */
50349 + XX_Free(p_ReplicGroup);
50350 + }
50351 +}
50352 +
50353 +
50354 +/*****************************************************************************/
50355 +/* Inter-module API routines */
50356 +/*****************************************************************************/
50357 +
50358 +/* NOTE: the inter-module routines are locked by cc in case of using them */
50359 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup)
50360 +{
50361 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50362 + ASSERT_COND(p_ReplicGroup);
50363 +
50364 + return (p_ReplicGroup->p_SourceTd);
50365 +}
50366 +
50367 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup,
50368 + void *p_Ad,
50369 + t_Handle *h_AdNew)
50370 +{
50371 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50372 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad;
50373 + t_FmPcd *p_FmPcd;
50374 +
50375 + ASSERT_COND(p_ReplicGroup);
50376 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50377 +
50378 + /* build a bypass ad */
50379 + WRITE_UINT32(p_AdResult->fqid, FM_PCD_AD_BYPASS_TYPE |
50380 + (uint32_t)((XX_VirtToPhys(p_ReplicGroup->p_SourceTd)) - p_FmPcd->physicalMuramBase));
50381 +
50382 + *h_AdNew = NULL;
50383 +}
50384 +
50385 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup,
50386 + bool add)
50387 +{
50388 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50389 + ASSERT_COND(p_ReplicGroup);
50390 +
50391 + /* update the group owner counter */
50392 + if (add)
50393 + p_ReplicGroup->owners++;
50394 + else
50395 + {
50396 + ASSERT_COND(p_ReplicGroup->owners);
50397 + p_ReplicGroup->owners--;
50398 + }
50399 +}
50400 +
50401 +t_Error FrmReplicGroupTryLock(t_Handle h_ReplicGroup)
50402 +{
50403 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50404 +
50405 + ASSERT_COND(h_ReplicGroup);
50406 +
50407 + if (FmPcdLockTryLock(p_ReplicGroup->p_Lock))
50408 + return E_OK;
50409 +
50410 + return ERROR_CODE(E_BUSY);
50411 +}
50412 +
50413 +void FrmReplicGroupUnlock(t_Handle h_ReplicGroup)
50414 +{
50415 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50416 +
50417 + ASSERT_COND(h_ReplicGroup);
50418 +
50419 + FmPcdLockUnlock(p_ReplicGroup->p_Lock);
50420 +}
50421 +/*********************** End of inter-module routines ************************/
50422 +
50423 +
50424 +/****************************************/
50425 +/* API Init unit functions */
50426 +/****************************************/
50427 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd,
50428 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
50429 +{
50430 + t_FmPcdFrmReplicGroup *p_ReplicGroup;
50431 + t_FmPcdFrmReplicMember *p_CurrentMember, *p_NextMember = NULL;
50432 + int i;
50433 + t_Error err;
50434 + bool last = FALSE;
50435 + t_Handle h_Muram;
50436 +
50437 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
50438 + SANITY_CHECK_RETURN_VALUE(p_ReplicGroupParam, E_INVALID_HANDLE, NULL);
50439 +
50440 + if (!FmPcdIsAdvancedOffloadSupported(h_FmPcd))
50441 + {
50442 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
50443 + return NULL;
50444 + }
50445 +
50446 + err = CheckParams(h_FmPcd, p_ReplicGroupParam);
50447 + if (err)
50448 + {
50449 + REPORT_ERROR(MAJOR, err, (NO_MSG));
50450 + return NULL;
50451 + }
50452 +
50453 + p_ReplicGroup = (t_FmPcdFrmReplicGroup*)XX_Malloc(sizeof(t_FmPcdFrmReplicGroup));
50454 + if (!p_ReplicGroup)
50455 + {
50456 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
50457 + return NULL;
50458 + }
50459 + memset(p_ReplicGroup, 0, sizeof(t_FmPcdFrmReplicGroup));
50460 +
50461 + /* initialize lists for internal driver use */
50462 + INIT_LIST(&p_ReplicGroup->availableMembersList);
50463 + INIT_LIST(&p_ReplicGroup->membersList);
50464 +
50465 + p_ReplicGroup->h_FmPcd = h_FmPcd;
50466 +
50467 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50468 + ASSERT_COND(h_Muram);
50469 +
50470 + /* initialize the group lock */
50471 + p_ReplicGroup->p_Lock = FmPcdAcquireLock(p_ReplicGroup->h_FmPcd);
50472 + if (!p_ReplicGroup->p_Lock)
50473 + {
50474 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Replic group lock"));
50475 + DeleteGroup(p_ReplicGroup);
50476 + return NULL;
50477 + }
50478 +
50479 + /* Allocate the frame replicator source table descriptor */
50480 + p_ReplicGroup->p_SourceTd =
50481 + (t_Handle)FM_MURAM_AllocMem(h_Muram,
50482 + FM_PCD_CC_AD_ENTRY_SIZE,
50483 + FM_PCD_CC_AD_TABLE_ALIGN);
50484 + if (!p_ReplicGroup->p_SourceTd)
50485 + {
50486 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("frame replicator source table descriptor"));
50487 + DeleteGroup(p_ReplicGroup);
50488 + return NULL;
50489 + }
50490 +
50491 + /* update the shadow size - required for the host commands */
50492 + err = FmPcdUpdateCcShadow(p_ReplicGroup->h_FmPcd,
50493 + FM_PCD_CC_AD_ENTRY_SIZE,
50494 + FM_PCD_CC_AD_TABLE_ALIGN);
50495 + if (err)
50496 + {
50497 + REPORT_ERROR(MAJOR, err, ("Update CC shadow"));
50498 + DeleteGroup(p_ReplicGroup);
50499 + return NULL;
50500 + }
50501 +
50502 + p_ReplicGroup->maxNumOfEntries = p_ReplicGroupParam->maxNumOfEntries;
50503 +
50504 + /* Allocate the maximal number of members ADs and Statistics AD for the group
50505 + It prevents allocation of Muram in run-time */
50506 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50507 + {
50508 + err = AllocMember(p_ReplicGroup);
50509 + if (err)
50510 + {
50511 + REPORT_ERROR(MAJOR, err, ("allocate a new member"));
50512 + DeleteGroup(p_ReplicGroup);
50513 + return NULL;
50514 + }
50515 + }
50516 +
50517 + /* Initialize the members linked lists:
50518 + (hw - the one that is used by the FMan controller and
50519 + sw - the one that is managed by the driver internally) */
50520 + for (i=(p_ReplicGroupParam->numOfEntries-1); i>=0; i--)
50521 + {
50522 + /* check if this is the last member in the group */
50523 + if (i == (p_ReplicGroupParam->numOfEntries-1))
50524 + last = TRUE;
50525 + else
50526 + last = FALSE;
50527 +
50528 + /* Initialize a new member */
50529 + p_CurrentMember = InitMember(p_ReplicGroup,
50530 + &(p_ReplicGroupParam->nextEngineParams[i]),
50531 + last);
50532 + if (!p_CurrentMember)
50533 + {
50534 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50535 + DeleteGroup(p_ReplicGroup);
50536 + return NULL;
50537 + }
50538 +
50539 + /* Build the members group - link two consecutive members in the hw linked list */
50540 + LinkMemberToMember(p_ReplicGroup, p_CurrentMember, p_NextMember);
50541 +
50542 + /* update the driver internal members list to be compatible to the hw members linked list */
50543 + AddMemberToList(p_ReplicGroup, p_CurrentMember, &p_ReplicGroup->membersList);
50544 +
50545 + p_NextMember = p_CurrentMember;
50546 + }
50547 +
50548 + /* initialize the source table descriptor */
50549 + BuildSourceTd(p_ReplicGroup->p_SourceTd);
50550 +
50551 + /* link the source table descriptor to point to the first member in the group */
50552 + LinkSourceToMember(p_ReplicGroup, p_ReplicGroup->p_SourceTd, p_NextMember);
50553 +
50554 + return p_ReplicGroup;
50555 +}
50556 +
50557 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_ReplicGroup)
50558 +{
50559 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50560 +
50561 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50562 +
50563 + if (p_ReplicGroup->owners)
50564 + RETURN_ERROR(MAJOR,
50565 + E_INVALID_STATE,
50566 + ("the group has owners and can't be deleted"));
50567 +
50568 + DeleteGroup(p_ReplicGroup);
50569 +
50570 + return E_OK;
50571 +}
50572 +
50573 +
50574 +/*****************************************************************************/
50575 +/* API Run-time Frame replicator Control unit functions */
50576 +/*****************************************************************************/
50577 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_ReplicGroup,
50578 + uint16_t memberIndex,
50579 + t_FmPcdCcNextEngineParams *p_MemberParams)
50580 +{
50581 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50582 + t_FmPcdFrmReplicMember *p_NewMember, *p_CurrentMember = NULL, *p_PreviousMember = NULL;
50583 + t_Error err;
50584 + uint8_t memberPosition;
50585 +
50586 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50587 + SANITY_CHECK_RETURN_ERROR(p_MemberParams, E_INVALID_HANDLE);
50588 +
50589 + /* group lock */
50590 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50591 + if (GET_ERROR_TYPE(err) == E_BUSY)
50592 + return ERROR_CODE(E_BUSY);
50593 +
50594 + if (memberIndex > p_ReplicGroup->numOfEntries)
50595 + {
50596 + /* unlock */
50597 + FrmReplicGroupUnlock(p_ReplicGroup);
50598 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
50599 + ("memberIndex is greater than the members in the list"));
50600 + }
50601 +
50602 + if (memberIndex >= p_ReplicGroup->maxNumOfEntries)
50603 + {
50604 + /* unlock */
50605 + FrmReplicGroupUnlock(p_ReplicGroup);
50606 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("memberIndex is greater than the allowed number of members in the group"));
50607 + }
50608 +
50609 + if ((p_ReplicGroup->numOfEntries + 1) > FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
50610 + {
50611 + /* unlock */
50612 + FrmReplicGroupUnlock(p_ReplicGroup);
50613 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
50614 + ("numOfEntries with new entry can not be larger than %d\n",
50615 + FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES));
50616 + }
50617 +
50618 + err = MemberCheckParams(p_ReplicGroup->h_FmPcd, p_MemberParams);
50619 + if (err)
50620 + {
50621 + /* unlock */
50622 + FrmReplicGroupUnlock(p_ReplicGroup);
50623 + RETURN_ERROR(MAJOR, err, ("member check parameters in add operation"));
50624 + }
50625 + /* determine the member position in the group */
50626 + memberPosition = GetMemberPosition(p_ReplicGroup,
50627 + memberIndex,
50628 + TRUE/* add operation */);
50629 +
50630 + /* Initialize a new member */
50631 + p_NewMember = InitMember(p_ReplicGroup,
50632 + p_MemberParams,
50633 + (memberPosition == FRM_REPLIC_LAST_MEMBER_INDEX ? TRUE : FALSE));
50634 + if (!p_NewMember)
50635 + {
50636 + /* unlock */
50637 + FrmReplicGroupUnlock(p_ReplicGroup);
50638 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50639 + }
50640 +
50641 + switch (memberPosition)
50642 + {
50643 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
50644 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50645 + ASSERT_COND(p_CurrentMember);
50646 +
50647 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50648 +
50649 + /* update the internal group source TD */
50650 + LinkSourceToMember(p_ReplicGroup,
50651 + p_ReplicGroup->p_SourceTd,
50652 + p_NewMember);
50653 +
50654 + /* add member to the internal sw member list */
50655 + AddMemberToList(p_ReplicGroup,
50656 + p_NewMember,
50657 + &p_ReplicGroup->membersList);
50658 + break;
50659 +
50660 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50661 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50662 + ASSERT_COND(p_CurrentMember);
50663 +
50664 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50665 + ASSERT_COND(p_PreviousMember);
50666 +
50667 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50668 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50669 +
50670 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50671 + break;
50672 +
50673 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50674 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50675 + ASSERT_COND(p_PreviousMember);
50676 +
50677 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50678 + FillReplicAdOfTypeResult(p_PreviousMember->p_MemberAd, FALSE/*last*/);
50679 +
50680 + /* add the new member to the internal sw member list */
50681 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50682 + break;
50683 +
50684 + default:
50685 + /* unlock */
50686 + FrmReplicGroupUnlock(p_ReplicGroup);
50687 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in add member"));
50688 +
50689 + }
50690 +
50691 + /* unlock */
50692 + FrmReplicGroupUnlock(p_ReplicGroup);
50693 +
50694 + return E_OK;
50695 +}
50696 +
50697 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_ReplicGroup,
50698 + uint16_t memberIndex)
50699 +{
50700 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50701 + t_Error err;
50702 +
50703 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50704 +
50705 + /* lock */
50706 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50707 + if (GET_ERROR_TYPE(err) == E_BUSY)
50708 + return ERROR_CODE(E_BUSY);
50709 +
50710 + if (memberIndex >= p_ReplicGroup->numOfEntries)
50711 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member index to remove"));
50712 +
50713 + /* Design decision: group must contain at least one member
50714 + No possibility to remove the last member from the group */
50715 + if (p_ReplicGroup->numOfEntries == 1)
50716 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Can't remove the last member. At least one member should be related to a group."));
50717 +
50718 + err = RemoveMember(p_ReplicGroup, memberIndex);
50719 +
50720 + /* unlock */
50721 + FrmReplicGroupUnlock(p_ReplicGroup);
50722 +
50723 + switch (GET_ERROR_TYPE(err))
50724 + {
50725 + case E_OK:
50726 + return E_OK;
50727 +
50728 + case E_BUSY:
50729 + DBG(TRACE, ("E_BUSY error"));
50730 + return ERROR_CODE(E_BUSY);
50731 +
50732 + default:
50733 + RETURN_ERROR(MAJOR, err, NO_MSG);
50734 + }
50735 +}
50736 +
50737 +/*********************** End of API routines ************************/
50738 +
50739 +
50740 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
50741 new file mode 100644
50742 index 00000000..0e8e8bc0
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 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
50848 new file mode 100644
50849 index 00000000..49b86e8e
50850 --- /dev/null
50851 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
50852 @@ -0,0 +1,888 @@
50853 +/*
50854 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50855 + *
50856 + * Redistribution and use in source and binary forms, with or without
50857 + * modification, are permitted provided that the following conditions are met:
50858 + * * Redistributions of source code must retain the above copyright
50859 + * notice, this list of conditions and the following disclaimer.
50860 + * * Redistributions in binary form must reproduce the above copyright
50861 + * notice, this list of conditions and the following disclaimer in the
50862 + * documentation and/or other materials provided with the distribution.
50863 + * * Neither the name of Freescale Semiconductor nor the
50864 + * names of its contributors may be used to endorse or promote products
50865 + * derived from this software without specific prior written permission.
50866 + *
50867 + *
50868 + * ALTERNATIVELY, this software may be distributed under the terms of the
50869 + * GNU General Public License ("GPL") as published by the Free Software
50870 + * Foundation, either version 2 of that License or (at your option) any
50871 + * later version.
50872 + *
50873 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50874 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50875 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50876 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50877 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50878 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50879 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50880 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50881 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50882 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50883 + */
50884 +
50885 +#include "fsl_fman_kg.h"
50886 +
50887 +/****************************************/
50888 +/* static functions */
50889 +/****************************************/
50890 +
50891 +
50892 +static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write)
50893 +{
50894 + uint32_t rw;
50895 +
50896 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50897 +
50898 + return (uint32_t)(FM_KG_KGAR_GO |
50899 + rw |
50900 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50901 + hwport_id |
50902 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
50903 +}
50904 +
50905 +static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id)
50906 +{
50907 + uint32_t ar;
50908 +
50909 + fman_kg_write_sp(regs, 0xffffffff, 0);
50910 +
50911 + ar = build_ar_bind_scheme(hwport_id, TRUE);
50912 + fman_kg_write_ar_wait(regs, ar);
50913 +}
50914 +
50915 +static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write)
50916 +{
50917 + uint32_t rw;
50918 +
50919 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50920 +
50921 + return (uint32_t)(FM_KG_KGAR_GO |
50922 + rw |
50923 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50924 + hwport_id |
50925 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
50926 +}
50927 +
50928 +static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id)
50929 +{
50930 + uint32_t ar;
50931 +
50932 + fman_kg_write_cpp(regs, 0);
50933 +
50934 + ar = build_ar_bind_cls_plan(hwport_id, TRUE);
50935 + fman_kg_write_ar_wait(regs, ar);
50936 +}
50937 +
50938 +static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src,
50939 + bool no_validation,
50940 + uint8_t *offset)
50941 +{
50942 + int code;
50943 +
50944 + switch (src) {
50945 + case E_FMAN_KG_GEN_EXTRACT_ETH:
50946 + code = no_validation ? 0x73 : 0x3;
50947 + break;
50948 +
50949 + case E_FMAN_KG_GEN_EXTRACT_ETYPE:
50950 + code = no_validation ? 0x77 : 0x7;
50951 + break;
50952 +
50953 + case E_FMAN_KG_GEN_EXTRACT_SNAP:
50954 + code = no_validation ? 0x74 : 0x4;
50955 + break;
50956 +
50957 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1:
50958 + code = no_validation ? 0x75 : 0x5;
50959 + break;
50960 +
50961 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N:
50962 + code = no_validation ? 0x76 : 0x6;
50963 + break;
50964 +
50965 + case E_FMAN_KG_GEN_EXTRACT_PPPoE:
50966 + code = no_validation ? 0x78 : 0x8;
50967 + break;
50968 +
50969 + case E_FMAN_KG_GEN_EXTRACT_MPLS_1:
50970 + code = no_validation ? 0x79 : 0x9;
50971 + break;
50972 +
50973 + case E_FMAN_KG_GEN_EXTRACT_MPLS_2:
50974 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19;
50975 + break;
50976 +
50977 + case E_FMAN_KG_GEN_EXTRACT_MPLS_3:
50978 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29;
50979 + break;
50980 +
50981 + case E_FMAN_KG_GEN_EXTRACT_MPLS_N:
50982 + code = no_validation ? 0x7a : 0xa;
50983 + break;
50984 +
50985 + case E_FMAN_KG_GEN_EXTRACT_IPv4_1:
50986 + code = no_validation ? 0x7b : 0xb;
50987 + break;
50988 +
50989 + case E_FMAN_KG_GEN_EXTRACT_IPv6_1:
50990 + code = no_validation ? 0x7b : 0x1b;
50991 + break;
50992 +
50993 + case E_FMAN_KG_GEN_EXTRACT_IPv4_2:
50994 + code = no_validation ? 0x7c : 0xc;
50995 + break;
50996 +
50997 + case E_FMAN_KG_GEN_EXTRACT_IPv6_2:
50998 + code = no_validation ? 0x7c : 0x1c;
50999 + break;
51000 +
51001 + case E_FMAN_KG_GEN_EXTRACT_MINENCAP:
51002 + code = no_validation ? 0x7c : 0x2c;
51003 + break;
51004 +
51005 + case E_FMAN_KG_GEN_EXTRACT_IP_PID:
51006 + code = no_validation ? 0x72 : 0x2;
51007 + break;
51008 +
51009 + case E_FMAN_KG_GEN_EXTRACT_GRE:
51010 + code = no_validation ? 0x7d : 0xd;
51011 + break;
51012 +
51013 + case E_FMAN_KG_GEN_EXTRACT_TCP:
51014 + code = no_validation ? 0x7e : 0xe;
51015 + break;
51016 +
51017 + case E_FMAN_KG_GEN_EXTRACT_UDP:
51018 + code = no_validation ? 0x7e : 0x1e;
51019 + break;
51020 +
51021 + case E_FMAN_KG_GEN_EXTRACT_SCTP:
51022 + code = no_validation ? 0x7e : 0x3e;
51023 + break;
51024 +
51025 + case E_FMAN_KG_GEN_EXTRACT_DCCP:
51026 + code = no_validation ? 0x7e : 0x4e;
51027 + break;
51028 +
51029 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH:
51030 + code = no_validation ? 0x7e : 0x2e;
51031 + break;
51032 +
51033 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP:
51034 + code = no_validation ? 0x7e : 0x6e;
51035 + break;
51036 +
51037 + case E_FMAN_KG_GEN_EXTRACT_SHIM_1:
51038 + code = 0x70;
51039 + break;
51040 +
51041 + case E_FMAN_KG_GEN_EXTRACT_SHIM_2:
51042 + code = 0x71;
51043 + break;
51044 +
51045 + case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT:
51046 + code = 0x10;
51047 + break;
51048 +
51049 + case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START:
51050 + code = 0x40;
51051 + break;
51052 +
51053 + case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT:
51054 + code = 0x20;
51055 + break;
51056 +
51057 + case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE:
51058 + code = 0x7f;
51059 + break;
51060 +
51061 + case E_FMAN_KG_GEN_EXTRACT_FROM_FQID:
51062 + code = 0x20;
51063 + *offset += 0x20;
51064 + break;
51065 +
51066 + default:
51067 + code = FM_KG_SCH_GEN_HT_INVALID;
51068 + }
51069 +
51070 + return (uint8_t)code;
51071 +}
51072 +
51073 +static uint32_t build_ar_scheme(uint8_t scheme,
51074 + uint8_t hwport_id,
51075 + bool update_counter,
51076 + bool write)
51077 +{
51078 + uint32_t rw;
51079 +
51080 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
51081 +
51082 + return (uint32_t)(FM_KG_KGAR_GO |
51083 + rw |
51084 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
51085 + hwport_id |
51086 + ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) |
51087 + (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
51088 +}
51089 +
51090 +static uint32_t build_ar_cls_plan(uint8_t grp,
51091 + uint8_t entries_mask,
51092 + uint8_t hwport_id,
51093 + bool write)
51094 +{
51095 + uint32_t rw;
51096 +
51097 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
51098 +
51099 + return (uint32_t)(FM_KG_KGAR_GO |
51100 + rw |
51101 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
51102 + hwport_id |
51103 + ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) |
51104 + ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT));
51105 +}
51106 +
51107 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar)
51108 +{
51109 + iowrite32be(fmkg_ar, &regs->fmkg_ar);
51110 + /* Wait for GO to be idle and read error */
51111 + while ((fmkg_ar = ioread32be(&regs->fmkg_ar)) & FM_KG_KGAR_GO) ;
51112 + if (fmkg_ar & FM_PCD_KG_KGAR_ERR)
51113 + return -EINVAL;
51114 + return 0;
51115 +}
51116 +
51117 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add)
51118 +{
51119 +
51120 + struct fman_kg_pe_regs *kgpe_regs;
51121 + uint32_t tmp;
51122 +
51123 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51124 + tmp = ioread32be(&kgpe_regs->fmkg_pe_sp);
51125 +
51126 + if (add)
51127 + tmp |= sp;
51128 + else /* clear */
51129 + tmp &= ~sp;
51130 +
51131 + iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp);
51132 +
51133 +}
51134 +
51135 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp)
51136 +{
51137 + struct fman_kg_pe_regs *kgpe_regs;
51138 +
51139 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51140 +
51141 + iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp);
51142 +}
51143 +
51144 +void fman_kg_get_event(struct fman_kg_regs *regs,
51145 + uint32_t *event,
51146 + uint32_t *scheme_idx)
51147 +{
51148 + uint32_t mask, force;
51149 +
51150 + *event = ioread32be(&regs->fmkg_eer);
51151 + mask = ioread32be(&regs->fmkg_eeer);
51152 + *scheme_idx = ioread32be(&regs->fmkg_seer);
51153 + *scheme_idx &= ioread32be(&regs->fmkg_seeer);
51154 +
51155 + *event &= mask;
51156 +
51157 + /* clear the forced events */
51158 + force = ioread32be(&regs->fmkg_feer);
51159 + if (force & *event)
51160 + iowrite32be(force & ~*event ,&regs->fmkg_feer);
51161 +
51162 + iowrite32be(*event, &regs->fmkg_eer);
51163 + iowrite32be(*scheme_idx, &regs->fmkg_seer);
51164 +}
51165 +
51166 +
51167 +void fman_kg_init(struct fman_kg_regs *regs,
51168 + uint32_t exceptions,
51169 + uint32_t dflt_nia)
51170 +{
51171 + uint32_t tmp;
51172 + int i;
51173 +
51174 + iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
51175 + &regs->fmkg_eer);
51176 +
51177 + tmp = 0;
51178 + if (exceptions & FM_EX_KG_DOUBLE_ECC)
51179 + tmp |= FM_EX_KG_DOUBLE_ECC;
51180 +
51181 + if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)
51182 + tmp |= FM_EX_KG_KEYSIZE_OVERFLOW;
51183 +
51184 + iowrite32be(tmp, &regs->fmkg_eeer);
51185 + iowrite32be(0, &regs->fmkg_fdor);
51186 + iowrite32be(0, &regs->fmkg_gdv0r);
51187 + iowrite32be(0, &regs->fmkg_gdv1r);
51188 + iowrite32be(dflt_nia, &regs->fmkg_gcr);
51189 +
51190 + /* Clear binding between ports to schemes and classification plans
51191 + * so that all ports are not bound to any scheme/classification plan */
51192 + for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
51193 + clear_pe_all_scheme(regs, (uint8_t)i);
51194 + clear_pe_all_cls_plan(regs, (uint8_t)i);
51195 + }
51196 +}
51197 +
51198 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs)
51199 +{
51200 + /* enable and enable all scheme interrupts */
51201 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seer);
51202 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seeer);
51203 +}
51204 +
51205 +void fman_kg_enable(struct fman_kg_regs *regs)
51206 +{
51207 + iowrite32be(ioread32be(&regs->fmkg_gcr) | FM_KG_KGGCR_EN,
51208 + &regs->fmkg_gcr);
51209 +}
51210 +
51211 +void fman_kg_disable(struct fman_kg_regs *regs)
51212 +{
51213 + iowrite32be(ioread32be(&regs->fmkg_gcr) & ~FM_KG_KGGCR_EN,
51214 + &regs->fmkg_gcr);
51215 +}
51216 +
51217 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset)
51218 +{
51219 + iowrite32be(offset, &regs->fmkg_fdor);
51220 +}
51221 +
51222 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
51223 + uint8_t def_id,
51224 + uint32_t val)
51225 +{
51226 + if(def_id == 0)
51227 + iowrite32be(val, &regs->fmkg_gdv0r);
51228 + else
51229 + iowrite32be(val, &regs->fmkg_gdv1r);
51230 +}
51231 +
51232 +
51233 +void fman_kg_set_exception(struct fman_kg_regs *regs,
51234 + uint32_t exception,
51235 + bool enable)
51236 +{
51237 + uint32_t tmp;
51238 +
51239 + tmp = ioread32be(&regs->fmkg_eeer);
51240 +
51241 + if (enable) {
51242 + tmp |= exception;
51243 + } else {
51244 + tmp &= ~exception;
51245 + }
51246 +
51247 + iowrite32be(tmp, &regs->fmkg_eeer);
51248 +}
51249 +
51250 +void fman_kg_get_exception(struct fman_kg_regs *regs,
51251 + uint32_t *events,
51252 + uint32_t *scheme_ids,
51253 + bool clear)
51254 +{
51255 + uint32_t mask;
51256 +
51257 + *events = ioread32be(&regs->fmkg_eer);
51258 + mask = ioread32be(&regs->fmkg_eeer);
51259 + *events &= mask;
51260 +
51261 + *scheme_ids = 0;
51262 +
51263 + if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) {
51264 + *scheme_ids = ioread32be(&regs->fmkg_seer);
51265 + mask = ioread32be(&regs->fmkg_seeer);
51266 + *scheme_ids &= mask;
51267 + }
51268 +
51269 + if (clear) {
51270 + iowrite32be(*scheme_ids, &regs->fmkg_seer);
51271 + iowrite32be(*events, &regs->fmkg_eer);
51272 + }
51273 +}
51274 +
51275 +void fman_kg_get_capture(struct fman_kg_regs *regs,
51276 + struct fman_kg_ex_ecc_attr *ecc_attr,
51277 + bool clear)
51278 +{
51279 + uint32_t tmp;
51280 +
51281 + tmp = ioread32be(&regs->fmkg_serc);
51282 +
51283 + if (tmp & KG_FMKG_SERC_CAP) {
51284 + /* Captured data is valid */
51285 + ecc_attr->valid = TRUE;
51286 + ecc_attr->double_ecc =
51287 + (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE);
51288 + ecc_attr->single_ecc_count =
51289 + (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >>
51290 + KG_FMKG_SERC_CNT_SHIFT);
51291 + ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK);
51292 +
51293 + if (clear)
51294 + iowrite32be(KG_FMKG_SERC_CAP, &regs->fmkg_serc);
51295 + } else {
51296 + /* No ECC error is captured */
51297 + ecc_attr->valid = FALSE;
51298 + }
51299 +}
51300 +
51301 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
51302 + struct fman_kg_scheme_regs *scheme_regs)
51303 +{
51304 + struct fman_kg_extract_params *extract_params;
51305 + struct fman_kg_gen_extract_params *gen_params;
51306 + uint32_t tmp_reg, i, select, mask, fqb;
51307 + uint8_t offset, shift, ht;
51308 +
51309 + /* Zero out all registers so no need to care about unused ones */
51310 + memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
51311 +
51312 + /* Mode register */
51313 + tmp_reg = fm_kg_build_nia(params->next_engine,
51314 + params->next_engine_action);
51315 + if (tmp_reg == KG_NIA_INVALID) {
51316 + return -EINVAL;
51317 + }
51318 +
51319 + if (params->next_engine == E_FMAN_PCD_PLCR) {
51320 + tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR;
51321 + }
51322 + else if (params->next_engine == E_FMAN_PCD_CC) {
51323 + tmp_reg |= (uint32_t)params->cc_params.base_offset <<
51324 + FMAN_KG_SCH_MODE_CCOBASE_SHIFT;
51325 + }
51326 +
51327 + tmp_reg |= FMAN_KG_SCH_MODE_EN;
51328 + scheme_regs->kgse_mode = tmp_reg;
51329 +
51330 + /* Match vector */
51331 + scheme_regs->kgse_mv = params->match_vector;
51332 +
51333 + extract_params = &params->extract_params;
51334 +
51335 + /* Scheme default values registers */
51336 + scheme_regs->kgse_dv0 = extract_params->def_scheme_0;
51337 + scheme_regs->kgse_dv1 = extract_params->def_scheme_1;
51338 +
51339 + /* Extract Known Fields Command register */
51340 + scheme_regs->kgse_ekfc = extract_params->known_fields;
51341 +
51342 + /* Entry Extract Known Default Value register */
51343 + tmp_reg = 0;
51344 + tmp_reg |= extract_params->known_fields_def.mac_addr <<
51345 + FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT;
51346 + tmp_reg |= extract_params->known_fields_def.vlan_tci <<
51347 + FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT;
51348 + tmp_reg |= extract_params->known_fields_def.etype <<
51349 + FMAN_KG_SCH_DEF_ETYPE_SHIFT;
51350 + tmp_reg |= extract_params->known_fields_def.ppp_sid <<
51351 + FMAN_KG_SCH_DEF_PPP_SID_SHIFT;
51352 + tmp_reg |= extract_params->known_fields_def.ppp_pid <<
51353 + FMAN_KG_SCH_DEF_PPP_PID_SHIFT;
51354 + tmp_reg |= extract_params->known_fields_def.mpls <<
51355 + FMAN_KG_SCH_DEF_MPLS_SHIFT;
51356 + tmp_reg |= extract_params->known_fields_def.ip_addr <<
51357 + FMAN_KG_SCH_DEF_IP_ADDR_SHIFT;
51358 + tmp_reg |= extract_params->known_fields_def.ptype <<
51359 + FMAN_KG_SCH_DEF_PTYPE_SHIFT;
51360 + tmp_reg |= extract_params->known_fields_def.ip_tos_tc <<
51361 + FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT;
51362 + tmp_reg |= extract_params->known_fields_def.ipv6_fl <<
51363 + FMAN_KG_SCH_DEF_IPv6_FL_SHIFT;
51364 + tmp_reg |= extract_params->known_fields_def.ipsec_spi <<
51365 + FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT;
51366 + tmp_reg |= extract_params->known_fields_def.l4_port <<
51367 + FMAN_KG_SCH_DEF_L4_PORT_SHIFT;
51368 + tmp_reg |= extract_params->known_fields_def.tcp_flg <<
51369 + FMAN_KG_SCH_DEF_TCP_FLG_SHIFT;
51370 +
51371 + scheme_regs->kgse_ekdv = tmp_reg;
51372 +
51373 + /* Generic extract registers */
51374 + if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) {
51375 + return -EINVAL;
51376 + }
51377 +
51378 + for (i = 0; i < extract_params->gen_extract_num; i++) {
51379 + gen_params = extract_params->gen_extract + i;
51380 +
51381 + tmp_reg = FMAN_KG_SCH_GEN_VALID;
51382 + tmp_reg |= (uint32_t)gen_params->def_val <<
51383 + FMAN_KG_SCH_GEN_DEF_SHIFT;
51384 +
51385 + if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) {
51386 + if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) ||
51387 + (gen_params->extract == 0)) {
51388 + return -EINVAL;
51389 + }
51390 + } else {
51391 + tmp_reg |= FMAN_KG_SCH_GEN_OR;
51392 + }
51393 +
51394 + tmp_reg |= (uint32_t)gen_params->extract <<
51395 + FMAN_KG_SCH_GEN_SIZE_SHIFT;
51396 + tmp_reg |= (uint32_t)gen_params->mask <<
51397 + FMAN_KG_SCH_GEN_MASK_SHIFT;
51398 +
51399 + offset = gen_params->offset;
51400 + ht = get_gen_ht_code(gen_params->src,
51401 + gen_params->no_validation,
51402 + &offset);
51403 + tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT;
51404 + tmp_reg |= offset;
51405 +
51406 + scheme_regs->kgse_gec[i] = tmp_reg;
51407 + }
51408 +
51409 + /* Masks registers */
51410 + if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) {
51411 + return -EINVAL;
51412 + }
51413 +
51414 + select = 0;
51415 + mask = 0;
51416 + fqb = 0;
51417 + for (i = 0; i < extract_params->masks_num; i++) {
51418 + /* MCSx fields */
51419 + KG_GET_MASK_SEL_SHIFT(shift, i);
51420 + if (extract_params->masks[i].is_known) {
51421 + /* Mask known field */
51422 + select |= extract_params->masks[i].field_or_gen_idx <<
51423 + shift;
51424 + } else {
51425 + /* Mask generic extract */
51426 + select |= (extract_params->masks[i].field_or_gen_idx +
51427 + FM_KG_MASK_SEL_GEN_BASE) << shift;
51428 + }
51429 +
51430 + /* MOx fields - spread between se_bmch and se_fqb registers */
51431 + KG_GET_MASK_OFFSET_SHIFT(shift, i);
51432 + if (i < 2) {
51433 + select |= (uint32_t)extract_params->masks[i].offset <<
51434 + shift;
51435 + } else {
51436 + fqb |= (uint32_t)extract_params->masks[i].offset <<
51437 + shift;
51438 + }
51439 +
51440 + /* BMx fields */
51441 + KG_GET_MASK_SHIFT(shift, i);
51442 + mask |= (uint32_t)extract_params->masks[i].mask << shift;
51443 + }
51444 +
51445 + /* Finish with rest of BMx fileds -
51446 + * don't mask bits for unused masks by setting
51447 + * corresponding BMx field = 0xFF */
51448 + for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) {
51449 + KG_GET_MASK_SHIFT(shift, i);
51450 + mask |= 0xFF << shift;
51451 + }
51452 +
51453 + scheme_regs->kgse_bmch = select;
51454 + scheme_regs->kgse_bmcl = mask;
51455 +
51456 + /* Finish with FQB register initialization.
51457 + * Check fqid is 24-bit value. */
51458 + if (params->base_fqid & ~0x00FFFFFF) {
51459 + return -EINVAL;
51460 + }
51461 +
51462 + fqb |= params->base_fqid;
51463 + scheme_regs->kgse_fqb = fqb;
51464 +
51465 + /* Hash Configuration register */
51466 + tmp_reg = 0;
51467 + if (params->hash_params.use_hash) {
51468 + /* Check hash mask is 24-bit value */
51469 + if (params->hash_params.mask & ~0x00FFFFFF) {
51470 + return -EINVAL;
51471 + }
51472 +
51473 + /* Hash function produces 64-bit value, 24 bits of that
51474 + * are used to generate fq_id and policer profile.
51475 + * Thus, maximal shift is 40 bits to allow 24 bits out of 64.
51476 + */
51477 + if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) {
51478 + return -EINVAL;
51479 + }
51480 +
51481 + tmp_reg |= params->hash_params.mask;
51482 + tmp_reg |= (uint32_t)params->hash_params.shift_r <<
51483 + FMAN_KG_SCH_HASH_HSHIFT_SHIFT;
51484 +
51485 + if (params->hash_params.sym) {
51486 + tmp_reg |= FMAN_KG_SCH_HASH_SYM;
51487 + }
51488 +
51489 + }
51490 +
51491 + if (params->bypass_fqid_gen) {
51492 + tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN;
51493 + }
51494 +
51495 + scheme_regs->kgse_hc = tmp_reg;
51496 +
51497 + /* Policer Profile register */
51498 + if (params->policer_params.bypass_pp_gen) {
51499 + tmp_reg = 0;
51500 + } else {
51501 + /* Lower 8 bits of 24-bits extracted from hash result
51502 + * are used for policer profile generation.
51503 + * That leaves maximum shift value = 23. */
51504 + if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) {
51505 + return -EINVAL;
51506 + }
51507 +
51508 + tmp_reg = params->policer_params.base;
51509 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51510 + FMAN_KG_SCH_PP_SH_SHIFT) &
51511 + FMAN_KG_SCH_PP_SH_MASK;
51512 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51513 + FMAN_KG_SCH_PP_SL_SHIFT) &
51514 + FMAN_KG_SCH_PP_SL_MASK;
51515 + tmp_reg |= (uint32_t)params->policer_params.mask <<
51516 + FMAN_KG_SCH_PP_MASK_SHIFT;
51517 + }
51518 +
51519 + scheme_regs->kgse_ppc = tmp_reg;
51520 +
51521 + /* Coarse Classification Bit Select register */
51522 + if (params->next_engine == E_FMAN_PCD_CC) {
51523 + scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel;
51524 + }
51525 +
51526 + /* Packets Counter register */
51527 + if (params->update_counter) {
51528 + scheme_regs->kgse_spc = params->counter_value;
51529 + }
51530 +
51531 + return 0;
51532 +}
51533 +
51534 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
51535 + uint8_t scheme_id,
51536 + uint8_t hwport_id,
51537 + struct fman_kg_scheme_regs *scheme_regs,
51538 + bool update_counter)
51539 +{
51540 + struct fman_kg_scheme_regs *kgse_regs;
51541 + uint32_t tmp_reg;
51542 + int err, i;
51543 +
51544 + /* Write indirect scheme registers */
51545 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51546 +
51547 + iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode);
51548 + iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc);
51549 + iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv);
51550 + iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch);
51551 + iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl);
51552 + iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb);
51553 + iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc);
51554 + iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc);
51555 + iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc);
51556 + iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0);
51557 + iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1);
51558 + iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs);
51559 + iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv);
51560 +
51561 + for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
51562 + iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]);
51563 +
51564 + /* Write AR (Action register) */
51565 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE);
51566 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51567 + return err;
51568 +}
51569 +
51570 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
51571 + uint8_t scheme_id,
51572 + uint8_t hwport_id)
51573 +{
51574 + struct fman_kg_scheme_regs *kgse_regs;
51575 + uint32_t tmp_reg;
51576 + int err, i;
51577 +
51578 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51579 +
51580 + /* Clear all registers including enable bit in mode register */
51581 + for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) {
51582 + iowrite32be(0, ((uint32_t *)kgse_regs + i));
51583 + }
51584 +
51585 + /* Write AR (Action register) */
51586 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE);
51587 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51588 + return err;
51589 +}
51590 +
51591 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
51592 + uint8_t scheme_id,
51593 + uint8_t hwport_id,
51594 + uint32_t *counter)
51595 +{
51596 + struct fman_kg_scheme_regs *kgse_regs;
51597 + uint32_t tmp_reg;
51598 + int err;
51599 +
51600 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51601 +
51602 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51603 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51604 +
51605 + if (err != 0)
51606 + return err;
51607 +
51608 + *counter = ioread32be(&kgse_regs->kgse_spc);
51609 +
51610 + return 0;
51611 +}
51612 +
51613 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
51614 + uint8_t scheme_id,
51615 + uint8_t hwport_id,
51616 + uint32_t counter)
51617 +{
51618 + struct fman_kg_scheme_regs *kgse_regs;
51619 + uint32_t tmp_reg;
51620 + int err;
51621 +
51622 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51623 +
51624 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51625 +
51626 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51627 + if (err != 0)
51628 + return err;
51629 +
51630 + /* Keygen indirect access memory contains all scheme_id registers
51631 + * by now. Change only counter value. */
51632 + iowrite32be(counter, &kgse_regs->kgse_spc);
51633 +
51634 + /* Write back scheme registers */
51635 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE);
51636 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51637 +
51638 + return err;
51639 +}
51640 +
51641 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs)
51642 +{
51643 + return ioread32be(&regs->fmkg_tpc);
51644 +}
51645 +
51646 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
51647 + struct fman_kg_cp_regs *cls_plan_regs)
51648 +{
51649 + uint8_t entries_set, entry_bit;
51650 + int i;
51651 +
51652 + /* Zero out all group's register */
51653 + memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs));
51654 +
51655 + /* Go over all classification entries in params->entries_mask and
51656 + * configure the corresponding cpe register */
51657 + entries_set = params->entries_mask;
51658 + for (i = 0; entries_set; i++) {
51659 + entry_bit = (uint8_t)(0x80 >> i);
51660 + if ((entry_bit & entries_set) == 0)
51661 + continue;
51662 + entries_set ^= entry_bit;
51663 + cls_plan_regs->kgcpe[i] = params->mask_vector[i];
51664 + }
51665 +
51666 + return 0;
51667 +}
51668 +
51669 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
51670 + uint8_t grp_id,
51671 + uint8_t entries_mask,
51672 + uint8_t hwport_id,
51673 + struct fman_kg_cp_regs *cls_plan_regs)
51674 +{
51675 + struct fman_kg_cp_regs *kgcpe_regs;
51676 + uint32_t tmp_reg;
51677 + int i, err;
51678 +
51679 + /* Check group index is valid and the group isn't empty */
51680 + if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM)
51681 + return -EINVAL;
51682 +
51683 + /* Write indirect classification plan registers */
51684 + kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]);
51685 +
51686 + for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) {
51687 + iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]);
51688 + }
51689 +
51690 + tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE);
51691 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51692 + return err;
51693 +}
51694 +
51695 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
51696 + uint8_t hwport_id,
51697 + uint32_t schemes)
51698 +{
51699 + struct fman_kg_pe_regs *kg_pe_regs;
51700 + uint32_t tmp_reg;
51701 + int err;
51702 +
51703 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51704 +
51705 + iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp);
51706 +
51707 + tmp_reg = build_ar_bind_scheme(hwport_id, TRUE);
51708 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51709 + return err;
51710 +}
51711 +
51712 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
51713 + uint8_t grp_mask,
51714 + uint32_t *bind_cls_plans)
51715 +{
51716 + /* Check grp_base and grp_mask are 5-bits values */
51717 + if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F))
51718 + return -EINVAL;
51719 +
51720 + *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base);
51721 + return 0;
51722 +}
51723 +
51724 +
51725 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
51726 + uint8_t hwport_id,
51727 + uint32_t bind_cls_plans)
51728 +{
51729 + struct fman_kg_pe_regs *kg_pe_regs;
51730 + uint32_t tmp_reg;
51731 + int err;
51732 +
51733 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51734 +
51735 + iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp);
51736 +
51737 + tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE);
51738 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51739 + return err;
51740 +}
51741 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
51742 new file mode 100644
51743 index 00000000..108779db
51744 --- /dev/null
51745 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
51746 @@ -0,0 +1,129 @@
51747 +/*
51748 + * Copyright 2012 Freescale Semiconductor Inc.
51749 + *
51750 + * Redistribution and use in source and binary forms, with or without
51751 + * modification, are permitted provided that the following conditions are met:
51752 + * * Redistributions of source code must retain the above copyright
51753 + * notice, this list of conditions and the following disclaimer.
51754 + * * Redistributions in binary form must reproduce the above copyright
51755 + * notice, this list of conditions and the following disclaimer in the
51756 + * documentation and/or other materials provided with the distribution.
51757 + * * Neither the name of Freescale Semiconductor nor the
51758 + * names of its contributors may be used to endorse or promote products
51759 + * derived from this software without specific prior written permission.
51760 + *
51761 + *
51762 + * ALTERNATIVELY, this software may be distributed under the terms of the
51763 + * GNU General Public License ("GPL") as published by the Free Software
51764 + * Foundation, either version 2 of that License or (at your option) any
51765 + * later version.
51766 + *
51767 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51768 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51769 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51770 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51771 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51772 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51773 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51774 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51775 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51776 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51777 + */
51778 +
51779 +#include "fsl_fman_prs.h"
51780 +
51781 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51782 +{
51783 + return ioread32be(&regs->fmpr_perr) & ev_mask;
51784 +}
51785 +
51786 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs)
51787 +{
51788 + return ioread32be(&regs->fmpr_perer);
51789 +}
51790 +
51791 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event)
51792 +{
51793 + iowrite32be(event, &regs->fmpr_perr);
51794 +}
51795 +
51796 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51797 +{
51798 + return ioread32be(&regs->fmpr_pevr) & ev_mask;
51799 +}
51800 +
51801 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs)
51802 +{
51803 + return ioread32be(&regs->fmpr_pever);
51804 +}
51805 +
51806 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event)
51807 +{
51808 + iowrite32be(event, &regs->fmpr_pevr);
51809 +}
51810 +
51811 +void fman_prs_defconfig(struct fman_prs_cfg *cfg)
51812 +{
51813 + cfg->port_id_stat = 0;
51814 + cfg->max_prs_cyc_lim = DEFAULT_MAX_PRS_CYC_LIM;
51815 + cfg->prs_exceptions = 0x03000000;
51816 +}
51817 +
51818 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg)
51819 +{
51820 + uint32_t tmp;
51821 +
51822 + iowrite32be(cfg->max_prs_cyc_lim, &regs->fmpr_rpclim);
51823 + iowrite32be((FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS),
51824 + &regs->fmpr_pevr);
51825 +
51826 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
51827 + iowrite32be(FM_PCD_PRS_SINGLE_ECC, &regs->fmpr_pever);
51828 + else
51829 + iowrite32be(0, &regs->fmpr_pever);
51830 +
51831 + iowrite32be(FM_PCD_PRS_DOUBLE_ECC, &regs->fmpr_perr);
51832 +
51833 + tmp = 0;
51834 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
51835 + tmp |= FM_PCD_PRS_DOUBLE_ECC;
51836 + iowrite32be(tmp, &regs->fmpr_perer);
51837 +
51838 + iowrite32be(cfg->port_id_stat, &regs->fmpr_ppsc);
51839 +
51840 + return 0;
51841 +}
51842 +
51843 +void fman_prs_enable(struct fman_prs_regs *regs)
51844 +{
51845 + uint32_t tmp;
51846 +
51847 + tmp = ioread32be(&regs->fmpr_rpimac) | FM_PCD_PRS_RPIMAC_EN;
51848 + iowrite32be(tmp, &regs->fmpr_rpimac);
51849 +}
51850 +
51851 +void fman_prs_disable(struct fman_prs_regs *regs)
51852 +{
51853 + uint32_t tmp;
51854 +
51855 + tmp = ioread32be(&regs->fmpr_rpimac) & ~FM_PCD_PRS_RPIMAC_EN;
51856 + iowrite32be(tmp, &regs->fmpr_rpimac);
51857 +}
51858 +
51859 +int fman_prs_is_enabled(struct fman_prs_regs *regs)
51860 +{
51861 + return ioread32be(&regs->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN;
51862 +}
51863 +
51864 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk)
51865 +{
51866 + iowrite32be(pid_msk, &regs->fmpr_ppsc);
51867 +}
51868 +
51869 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable)
51870 +{
51871 + if (enable)
51872 + iowrite32be(FM_PCD_PRS_PPSC_ALL_PORTS, &regs->fmpr_ppsc);
51873 + else
51874 + iowrite32be(0, &regs->fmpr_ppsc);
51875 +}
51876 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
51877 new file mode 100644
51878 index 00000000..7d928e0a
51879 --- /dev/null
51880 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
51881 @@ -0,0 +1,15 @@
51882 +#
51883 +# Makefile for the Freescale Ethernet controllers
51884 +#
51885 +ccflags-y += -DVERSION=\"\"
51886 +#
51887 +#Include netcomm SW specific definitions
51888 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
51889 +
51890 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
51891 +
51892 +ccflags-y += -I$(NCSW_FM_INC)
51893 +
51894 +obj-y += fsl-ncsw-Pcd.o
51895 +
51896 +fsl-ncsw-Pcd-objs := fm_port.o fm_port_im.o fman_port.o
51897 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
51898 new file mode 100644
51899 index 00000000..ec6e0ed5
51900 --- /dev/null
51901 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
51902 @@ -0,0 +1,6436 @@
51903 +/*
51904 + * Copyright 2008-2012 Freescale Semiconductor Inc.
51905 + *
51906 + * Redistribution and use in source and binary forms, with or without
51907 + * modification, are permitted provided that the following conditions are met:
51908 + * * Redistributions of source code must retain the above copyright
51909 + * notice, this list of conditions and the following disclaimer.
51910 + * * Redistributions in binary form must reproduce the above copyright
51911 + * notice, this list of conditions and the following disclaimer in the
51912 + * documentation and/or other materials provided with the distribution.
51913 + * * Neither the name of Freescale Semiconductor nor the
51914 + * names of its contributors may be used to endorse or promote products
51915 + * derived from this software without specific prior written permission.
51916 + *
51917 + *
51918 + * ALTERNATIVELY, this software may be distributed under the terms of the
51919 + * GNU General Public License ("GPL") as published by the Free Software
51920 + * Foundation, either version 2 of that License or (at your option) any
51921 + * later version.
51922 + *
51923 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51924 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51925 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51926 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51927 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51928 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51929 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51930 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51931 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51932 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51933 + */
51934 +
51935 +
51936 +/******************************************************************************
51937 + @File fm_port.c
51938 +
51939 + @Description FM driver routines implementation.
51940 + *//***************************************************************************/
51941 +#include "error_ext.h"
51942 +#include "std_ext.h"
51943 +#include "string_ext.h"
51944 +#include "sprint_ext.h"
51945 +#include "debug_ext.h"
51946 +#include "fm_muram_ext.h"
51947 +
51948 +#include "fman_common.h"
51949 +#include "fm_port.h"
51950 +#include "fm_port_dsar.h"
51951 +#include "common/general.h"
51952 +
51953 +/****************************************/
51954 +/* static functions */
51955 +/****************************************/
51956 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
51957 +
51958 +static t_Error CheckInitParameters(t_FmPort *p_FmPort)
51959 +{
51960 + t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
51961 + struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
51962 + t_Error ans = E_OK;
51963 + uint32_t unusedMask;
51964 +
51965 + if (p_FmPort->imEn)
51966 + {
51967 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51968 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51969 + > 2)
51970 + RETURN_ERROR(
51971 + MAJOR,
51972 + E_INVALID_VALUE,
51973 + ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
51974 +
51975 + if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
51976 + return ERROR_CODE(ans);
51977 + }
51978 + else
51979 + {
51980 + /****************************************/
51981 + /* Rx only */
51982 + /****************************************/
51983 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51984 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51985 + {
51986 + /* external buffer pools */
51987 + if (!p_Params->extBufPools.numOfPoolsUsed)
51988 + RETURN_ERROR(
51989 + MAJOR,
51990 + E_INVALID_VALUE,
51991 + ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
51992 +
51993 + if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
51994 + p_Params->p_BackupBmPools,
51995 + &p_Params->bufPoolDepletion) != E_OK)
51996 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51997 +
51998 + /* Check that part of IC that needs copying is small enough to enter start margin */
51999 + if (p_Params->intContext.size
52000 + && (p_Params->intContext.size
52001 + + p_Params->intContext.extBufOffset
52002 + > p_Params->bufMargins.startMargins))
52003 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52004 + ("intContext.size is larger than start margins"));
52005 +
52006 + if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
52007 + && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
52008 + RETURN_ERROR(
52009 + MAJOR,
52010 + E_INVALID_VALUE,
52011 + ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
52012 +
52013 +#ifdef FM_NO_BACKUP_POOLS
52014 + if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
52015 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52016 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
52017 +#endif /* FM_NO_BACKUP_POOLS */
52018 + }
52019 +
52020 + /****************************************/
52021 + /* Non Rx ports */
52022 + /****************************************/
52023 + else
52024 + {
52025 + if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
52026 + RETURN_ERROR(
52027 + MAJOR,
52028 + E_INVALID_VALUE,
52029 + (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
52030 +
52031 + /* to protect HW internal-context from overwrite */
52032 + if ((p_Params->intContext.size)
52033 + && (p_Params->intContext.intContextOffset
52034 + < MIN_TX_INT_OFFSET))
52035 + RETURN_ERROR(
52036 + MAJOR,
52037 + E_INVALID_VALUE,
52038 + ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
52039 +
52040 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
52041 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52042 + /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
52043 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52044 + != DEFAULT_notSupported))
52045 + {
52046 + /* Check that not larger than 8 */
52047 + if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
52048 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52049 + > MAX_FIFO_PIPELINE_DEPTH))
52050 + RETURN_ERROR(
52051 + MAJOR,
52052 + E_INVALID_VALUE,
52053 + ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
52054 + }
52055 + }
52056 +
52057 + /****************************************/
52058 + /* Rx Or Offline Parsing */
52059 + /****************************************/
52060 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52061 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52062 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
52063 + {
52064 + if (!p_Params->dfltFqid)
52065 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52066 + ("dfltFqid must be between 1 and 2^24-1"));
52067 +#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
52068 + if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
52069 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
52070 +#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
52071 + }
52072 +
52073 + /****************************************/
52074 + /* All ports */
52075 + /****************************************/
52076 + /* common BMI registers values */
52077 + /* Check that Queue Id is not larger than 2^24, and is not 0 */
52078 + if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
52079 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52080 + ("errFqid must be between 1 and 2^24-1"));
52081 + if (p_Params->dfltFqid & ~0x00FFFFFF)
52082 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52083 + ("dfltFqid must be between 1 and 2^24-1"));
52084 + }
52085 +
52086 + /****************************************/
52087 + /* Rx only */
52088 + /****************************************/
52089 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52090 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52091 + {
52092 + if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
52093 + RETURN_ERROR(
52094 + MAJOR,
52095 + E_INVALID_VALUE,
52096 + ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
52097 + if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
52098 + || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
52099 + RETURN_ERROR(
52100 + MAJOR,
52101 + E_INVALID_VALUE,
52102 + ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52103 + if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
52104 + RETURN_ERROR(
52105 + MAJOR,
52106 + E_INVALID_VALUE,
52107 + ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
52108 + if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
52109 + || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
52110 + RETURN_ERROR(
52111 + MAJOR,
52112 + E_INVALID_VALUE,
52113 + ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52114 +
52115 + /* Check that not larger than 16 */
52116 + if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
52117 + RETURN_ERROR(
52118 + MAJOR,
52119 + E_INVALID_VALUE,
52120 + ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
52121 +
52122 + if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
52123 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52124 +
52125 + /* extra FIFO size (allowed only to Rx ports) */
52126 + if (p_Params->setSizeOfFifo
52127 + && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
52128 + RETURN_ERROR(
52129 + MAJOR,
52130 + E_INVALID_VALUE,
52131 + ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
52132 +
52133 + if (p_Params->bufPoolDepletion.poolsGrpModeEnable
52134 + && !p_Params->bufPoolDepletion.numOfPools)
52135 + RETURN_ERROR(
52136 + MAJOR,
52137 + E_INVALID_VALUE,
52138 + ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
52139 +#ifdef FM_CSI_CFED_LIMIT
52140 + if (p_FmPort->fmRevInfo.majorRev == 4)
52141 + {
52142 + /* Check that not larger than 16 */
52143 + if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
52144 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
52145 + }
52146 +#endif /* FM_CSI_CFED_LIMIT */
52147 + }
52148 +
52149 + /****************************************/
52150 + /* Non Rx ports */
52151 + /****************************************/
52152 + /* extra FIFO size (allowed only to Rx ports) */
52153 + else
52154 + if (p_FmPort->fifoBufs.extra)
52155 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52156 + (" No fifoBufs.extra for non Rx ports"));
52157 +
52158 + /****************************************/
52159 + /* Tx only */
52160 + /****************************************/
52161 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
52162 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
52163 + {
52164 + if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
52165 + RETURN_ERROR(
52166 + MAJOR,
52167 + E_INVALID_VALUE,
52168 + ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
52169 + if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
52170 + RETURN_ERROR(
52171 + MAJOR,
52172 + E_INVALID_VALUE,
52173 + ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
52174 + if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
52175 + RETURN_ERROR(
52176 + MAJOR,
52177 + E_INVALID_VALUE,
52178 + ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
52179 + if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
52180 + || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
52181 + RETURN_ERROR(
52182 + MAJOR,
52183 + E_INVALID_VALUE,
52184 + ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52185 +
52186 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
52187 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52188 + > 2)
52189 + RETURN_ERROR(
52190 + MAJOR, E_INVALID_VALUE,
52191 + ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
52192 + }
52193 +
52194 + /****************************************/
52195 + /* Non Tx Ports */
52196 + /****************************************/
52197 + /* If discard override was selected , no frames may be discarded. */
52198 + else
52199 + if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
52200 + RETURN_ERROR(
52201 + MAJOR,
52202 + E_CONFLICT,
52203 + ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
52204 +
52205 + /****************************************/
52206 + /* Rx and Offline parsing */
52207 + /****************************************/
52208 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52209 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52210 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
52211 + {
52212 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52213 + unusedMask = BMI_STATUS_OP_MASK_UNUSED;
52214 + else
52215 + unusedMask = BMI_STATUS_RX_MASK_UNUSED;
52216 +
52217 + /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
52218 + if (p_Params->errorsToDiscard & unusedMask)
52219 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
52220 + ("errorsToDiscard contains undefined bits"));
52221 + }
52222 +
52223 + /****************************************/
52224 + /* Offline Ports */
52225 + /****************************************/
52226 +#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
52227 + if ((p_FmPort->fmRevInfo.majorRev >= 6)
52228 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52229 + && p_Params->setNumOfOpenDmas
52230 + && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
52231 + RETURN_ERROR(
52232 + MAJOR,
52233 + E_INVALID_VALUE,
52234 + ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
52235 +#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
52236 +
52237 + /****************************************/
52238 + /* Offline & HC Ports */
52239 + /****************************************/
52240 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52241 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
52242 + {
52243 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
52244 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
52245 + (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
52246 + /* this is an indication that user called config for this mode which is not supported in this integration */
52247 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
52248 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
52249 +
52250 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
52251 + if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
52252 + (p_FmPort->fmRevInfo.majorRev >= 6))) &&
52253 + (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
52254 + /* this is an indication that user called config for this mode which is not supported in this integration */
52255 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
52256 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
52257 + }
52258 +
52259 + /****************************************/
52260 + /* All ports */
52261 + /****************************************/
52262 + /* Check that not larger than 16 */
52263 + if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
52264 + && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
52265 + RETURN_ERROR(
52266 + MAJOR,
52267 + E_INVALID_VALUE,
52268 + ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
52269 +
52270 + if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
52271 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52272 +
52273 + /* common BMI registers values */
52274 + if (p_Params->setNumOfTasks
52275 + && ((!p_FmPort->tasks.num)
52276 + || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
52277 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52278 + ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
52279 + if (p_Params->setNumOfTasks
52280 + && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
52281 + RETURN_ERROR(
52282 + MAJOR,
52283 + E_INVALID_VALUE,
52284 + ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
52285 + if (p_Params->setNumOfOpenDmas
52286 + && ((!p_FmPort->openDmas.num)
52287 + || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
52288 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52289 + ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
52290 + if (p_Params->setNumOfOpenDmas
52291 + && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
52292 + RETURN_ERROR(
52293 + MAJOR,
52294 + E_INVALID_VALUE,
52295 + ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
52296 + if (p_Params->setSizeOfFifo
52297 + && (!p_FmPort->fifoBufs.num
52298 + || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
52299 + RETURN_ERROR(
52300 + MAJOR,
52301 + E_INVALID_VALUE,
52302 + ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52303 + if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
52304 + RETURN_ERROR(
52305 + MAJOR, E_INVALID_VALUE,
52306 + ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
52307 +
52308 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
52309 + if (p_FmPort->fmRevInfo.majorRev == 4)
52310 + if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
52311 + /* this is an indication that user called config for this mode which is not supported in this integration */
52312 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
52313 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
52314 +
52315 + return E_OK;
52316 +}
52317 +
52318 +static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
52319 +{
52320 + uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
52321 +
52322 + /*************************/
52323 + /* TX PORTS */
52324 + /*************************/
52325 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
52326 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
52327 + {
52328 + minFifoSizeRequired =
52329 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52330 + + (3 * BMI_FIFO_UNITS));
52331 + if (!p_FmPort->imEn)
52332 + minFifoSizeRequired +=
52333 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52334 + * BMI_FIFO_UNITS;
52335 +
52336 + optFifoSizeForB2B = minFifoSizeRequired;
52337 +
52338 + /* Add some margin for back-to-back capability to improve performance,
52339 + allows the hardware to pipeline new frame dma while the previous
52340 + frame not yet transmitted. */
52341 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52342 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52343 + else
52344 + optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
52345 + }
52346 +
52347 + /*************************/
52348 + /* RX IM PORTS */
52349 + /*************************/
52350 + else
52351 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52352 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52353 + && p_FmPort->imEn)
52354 + {
52355 + optFifoSizeForB2B =
52356 + minFifoSizeRequired =
52357 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52358 + + (4 * BMI_FIFO_UNITS));
52359 + }
52360 +
52361 + /*************************/
52362 + /* RX non-IM PORTS */
52363 + /*************************/
52364 + else
52365 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52366 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52367 + && !p_FmPort->imEn)
52368 + {
52369 + if (p_FmPort->fmRevInfo.majorRev == 4)
52370 + {
52371 + if (p_FmPort->rxPoolsParams.numOfPools == 1)
52372 + minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
52373 + else
52374 + minFifoSizeRequired =
52375 + (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
52376 + + (7 * BMI_FIFO_UNITS));
52377 + }
52378 + else
52379 + {
52380 +#if (DPAA_VERSION >= 11)
52381 + minFifoSizeRequired =
52382 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52383 + + (5 * BMI_FIFO_UNITS));
52384 + /* 4 according to spec + 1 for FOF>0 */
52385 +#else
52386 + minFifoSizeRequired = (uint32_t)
52387 + (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
52388 + + (7*BMI_FIFO_UNITS));
52389 +#endif /* (DPAA_VERSION >= 11) */
52390 + }
52391 +
52392 + optFifoSizeForB2B = minFifoSizeRequired;
52393 +
52394 + /* Add some margin for back-to-back capability to improve performance,
52395 + allows the hardware to pipeline new frame dma while the previous
52396 + frame not yet transmitted. */
52397 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52398 + optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
52399 + else
52400 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52401 + }
52402 +
52403 + /* For O/H ports, check fifo size and update if necessary */
52404 + else
52405 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52406 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
52407 + {
52408 +#if (DPAA_VERSION >= 11)
52409 + optFifoSizeForB2B =
52410 + minFifoSizeRequired =
52411 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52412 + + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52413 + + 5) * BMI_FIFO_UNITS));
52414 + /* 4 according to spec + 1 for FOF>0 */
52415 +#else
52416 + optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
52417 +#endif /* (DPAA_VERSION >= 11) */
52418 + }
52419 +
52420 + ASSERT_COND(minFifoSizeRequired > 0);
52421 + ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
52422 +
52423 + /* Verify the size */
52424 + if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
52425 + DBG(INFO,
52426 + ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
52427 + else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
52428 + DBG(INFO,
52429 + ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
52430 +
52431 + return E_OK;
52432 +}
52433 +
52434 +static void FmPortDriverParamFree(t_FmPort *p_FmPort)
52435 +{
52436 + if (p_FmPort->p_FmPortDriverParam)
52437 + {
52438 + XX_Free(p_FmPort->p_FmPortDriverParam);
52439 + p_FmPort->p_FmPortDriverParam = NULL;
52440 + }
52441 +}
52442 +
52443 +static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
52444 +{
52445 + t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
52446 + t_FmBufPoolDepletion *p_BufPoolDepletion =
52447 + &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
52448 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
52449 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
52450 + int i = 0, j = 0, err;
52451 + struct fman_port_bpools bpools;
52452 +
52453 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
52454 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
52455 + memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
52456 +
52457 + FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
52458 + sizesArray);
52459 +
52460 + /* Prepare flibs bpools structure */
52461 + memset(&bpools, 0, sizeof(struct fman_port_bpools));
52462 + bpools.count = p_ExtBufPools->numOfPoolsUsed;
52463 + bpools.counters_enable = TRUE;
52464 + for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
52465 + {
52466 + bpools.bpool[i].bpid = orderedArray[i];
52467 + bpools.bpool[i].size = sizesArray[orderedArray[i]];
52468 + /* functionality available only for some derivatives (limited by config) */
52469 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52470 + for (j = 0;
52471 + j
52472 + < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
52473 + j++)
52474 + if (orderedArray[i]
52475 + == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
52476 + {
52477 + bpools.bpool[i].is_backup = TRUE;
52478 + break;
52479 + }
52480 + }
52481 +
52482 + /* save pools parameters for later use */
52483 + p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
52484 + p_FmPort->rxPoolsParams.largestBufSize =
52485 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
52486 + p_FmPort->rxPoolsParams.secondLargestBufSize =
52487 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
52488 +
52489 + /* FMBM_RMPD reg. - pool depletion */
52490 + if (p_BufPoolDepletion->poolsGrpModeEnable)
52491 + {
52492 + bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
52493 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52494 + {
52495 + if (p_BufPoolDepletion->poolsToConsider[i])
52496 + {
52497 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52498 + {
52499 + if (i == orderedArray[j])
52500 + {
52501 + bpools.bpool[j].grp_bp_depleted = TRUE;
52502 + break;
52503 + }
52504 + }
52505 + }
52506 + }
52507 + }
52508 +
52509 + if (p_BufPoolDepletion->singlePoolModeEnable)
52510 + {
52511 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52512 + {
52513 + if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
52514 + {
52515 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52516 + {
52517 + if (i == orderedArray[j])
52518 + {
52519 + bpools.bpool[j].single_bp_depleted = TRUE;
52520 + break;
52521 + }
52522 + }
52523 + }
52524 + }
52525 + }
52526 +
52527 +#if (DPAA_VERSION >= 11)
52528 + /* fill QbbPEV */
52529 + if (p_BufPoolDepletion->poolsGrpModeEnable
52530 + || p_BufPoolDepletion->singlePoolModeEnable)
52531 + {
52532 + for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
52533 + {
52534 + if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
52535 + {
52536 + bpools.bpool[i].pfc_priorities_en = TRUE;
52537 + }
52538 + }
52539 + }
52540 +#endif /* (DPAA_VERSION >= 11) */
52541 +
52542 + /* Issue flibs function */
52543 + err = fman_port_set_bpools(&p_FmPort->port, &bpools);
52544 + if (err != 0)
52545 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
52546 +
52547 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52548 + XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
52549 +
52550 + return E_OK;
52551 +}
52552 +
52553 +static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
52554 +{
52555 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52556 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
52557 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
52558 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
52559 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
52560 + return E_OK;
52561 +}
52562 +
52563 +static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
52564 +{
52565 + t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
52566 + struct fman_port_params portParams;
52567 + uint32_t tmpVal;
52568 + t_Error err;
52569 +
52570 + /* Set up flibs parameters and issue init function */
52571 +
52572 + memset(&portParams, 0, sizeof(struct fman_port_params));
52573 + portParams.discard_mask = p_DriverParams->errorsToDiscard;
52574 + portParams.dflt_fqid = p_DriverParams->dfltFqid;
52575 + portParams.err_fqid = p_DriverParams->errFqid;
52576 + portParams.deq_sp = p_DriverParams->deqSubPortal;
52577 + portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
52578 + switch (p_FmPort->portType)
52579 + {
52580 + case (e_FM_PORT_TYPE_RX_10G):
52581 + case (e_FM_PORT_TYPE_RX):
52582 + portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
52583 + if (!p_FmPort->imEn)
52584 + {
52585 + if (p_DriverParams->forwardReuseIntContext)
52586 + p_DriverParams->dfltCfg.rx_fd_bits =
52587 + (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
52588 + }
52589 + break;
52590 +
52591 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52592 + portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
52593 + break;
52594 + break;
52595 +
52596 + default:
52597 + break;
52598 + }
52599 +
52600 + tmpVal =
52601 + (uint32_t)(
52602 + (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
52603 + / OFFSET_UNITS + 1) :
52604 + (p_FmPort->internalBufferOffset / OFFSET_UNITS));
52605 + p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
52606 + p_DriverParams->dfltCfg.int_buf_start_margin =
52607 + p_FmPort->internalBufferOffset;
52608 +
52609 + p_DriverParams->dfltCfg.ext_buf_start_margin =
52610 + p_DriverParams->bufMargins.startMargins;
52611 + p_DriverParams->dfltCfg.ext_buf_end_margin =
52612 + p_DriverParams->bufMargins.endMargins;
52613 +
52614 + p_DriverParams->dfltCfg.ic_ext_offset =
52615 + p_DriverParams->intContext.extBufOffset;
52616 + p_DriverParams->dfltCfg.ic_int_offset =
52617 + p_DriverParams->intContext.intContextOffset;
52618 + p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
52619 +
52620 + p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
52621 + p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
52622 + p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
52623 +
52624 + p_DriverParams->dfltCfg.perf_cnt_params.task_val =
52625 + (uint8_t)p_FmPort->tasks.num;
52626 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
52627 + p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
52628 + else
52629 + p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
52630 + p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
52631 + (uint8_t)p_FmPort->openDmas.num;
52632 + p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
52633 +
52634 + if (0
52635 + != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
52636 + &portParams))
52637 + RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
52638 +
52639 + if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
52640 + RETURN_ERROR(MAJOR, err, NO_MSG);
52641 + else
52642 + {
52643 + // from QMIInit
52644 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52645 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52646 + {
52647 + if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
52648 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52649 + FALSE);
52650 + else
52651 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52652 + TRUE);
52653 + }
52654 + }
52655 + /* The code bellow is a trick so the FM will not release the buffer
52656 + to BM nor will try to enqueue the frame to QM */
52657 + if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52658 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
52659 + {
52660 + if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
52661 + {
52662 + /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
52663 + * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
52664 + * buffers to BM regardless of fmbm_tfene
52665 + */
52666 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
52667 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
52668 + NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
52669 + }
52670 + }
52671 +
52672 + return E_OK;
52673 +}
52674 +
52675 +static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52676 +{
52677 + UNUSED(p_FmPort);
52678 +
52679 + switch (counter)
52680 + {
52681 + case (e_FM_PORT_COUNTERS_CYCLE):
52682 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52683 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52684 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52685 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52686 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52687 + case (e_FM_PORT_COUNTERS_FRAME):
52688 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52689 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52690 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52691 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52692 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52693 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52694 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52695 + case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
52696 + return TRUE;
52697 + default:
52698 + return FALSE;
52699 + }
52700 +}
52701 +
52702 +static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52703 +{
52704 + UNUSED(p_FmPort);
52705 +
52706 + switch (counter)
52707 + {
52708 + case (e_FM_PORT_COUNTERS_CYCLE):
52709 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52710 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52711 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52712 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52713 + case (e_FM_PORT_COUNTERS_FRAME):
52714 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52715 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52716 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52717 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52718 + return TRUE;
52719 + default:
52720 + return FALSE;
52721 + }
52722 +}
52723 +
52724 +static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52725 +{
52726 + switch (counter)
52727 + {
52728 + case (e_FM_PORT_COUNTERS_CYCLE):
52729 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52730 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52731 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52732 + case (e_FM_PORT_COUNTERS_FRAME):
52733 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52734 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52735 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52736 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52737 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52738 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52739 + return TRUE;
52740 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52741 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
52742 + return FALSE;
52743 + else
52744 + return TRUE;
52745 + default:
52746 + return FALSE;
52747 + }
52748 +}
52749 +
52750 +static t_Error BmiPortCheckAndGetCounterType(
52751 + t_FmPort *p_FmPort, e_FmPortCounters counter,
52752 + enum fman_port_stats_counters *p_StatsType,
52753 + enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
52754 +{
52755 + volatile uint32_t *p_Reg;
52756 + bool isValid;
52757 +
52758 + switch (p_FmPort->portType)
52759 + {
52760 + case (e_FM_PORT_TYPE_RX_10G):
52761 + case (e_FM_PORT_TYPE_RX):
52762 + p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
52763 + isValid = CheckRxBmiCounter(p_FmPort, counter);
52764 + break;
52765 + case (e_FM_PORT_TYPE_TX_10G):
52766 + case (e_FM_PORT_TYPE_TX):
52767 + p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
52768 + isValid = CheckTxBmiCounter(p_FmPort, counter);
52769 + break;
52770 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52771 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
52772 + p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
52773 + isValid = CheckOhBmiCounter(p_FmPort, counter);
52774 + break;
52775 + default:
52776 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
52777 + }
52778 +
52779 + if (!isValid)
52780 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52781 + ("Requested counter is not available for this port type"));
52782 +
52783 + /* check that counters are enabled */
52784 + switch (counter)
52785 + {
52786 + case (e_FM_PORT_COUNTERS_CYCLE):
52787 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52788 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52789 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52790 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52791 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52792 + /* performance counters - may be read when disabled */
52793 + *p_IsStats = FALSE;
52794 + break;
52795 + case (e_FM_PORT_COUNTERS_FRAME):
52796 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52797 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52798 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52799 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52800 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52801 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52802 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52803 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52804 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52805 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52806 + *p_IsStats = TRUE;
52807 + if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
52808 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52809 + ("Requested counter was not enabled"));
52810 + break;
52811 + default:
52812 + break;
52813 + }
52814 +
52815 + /* Set counter */
52816 + switch (counter)
52817 + {
52818 + case (e_FM_PORT_COUNTERS_CYCLE):
52819 + *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
52820 + break;
52821 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52822 + *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
52823 + break;
52824 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52825 + *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
52826 + break;
52827 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52828 + *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
52829 + break;
52830 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52831 + *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
52832 + break;
52833 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52834 + *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
52835 + break;
52836 + case (e_FM_PORT_COUNTERS_FRAME):
52837 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
52838 + break;
52839 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52840 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
52841 + break;
52842 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52843 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
52844 + break;
52845 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52846 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
52847 + break;
52848 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52849 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
52850 + break;
52851 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52852 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
52853 + break;
52854 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52855 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
52856 + break;
52857 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52858 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
52859 + break;
52860 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52861 + *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
52862 + break;
52863 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52864 + *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
52865 + break;
52866 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52867 + *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
52868 + break;
52869 + default:
52870 + break;
52871 + }
52872 +
52873 + return E_OK;
52874 +}
52875 +
52876 +static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
52877 + t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
52878 + uint32_t *p_SoftSeqAttachReg)
52879 +{
52880 + uint8_t hdrNum, Ipv4HdrNum;
52881 + u_FmPcdHdrPrsOpts *p_prsOpts;
52882 + uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
52883 +
52884 + if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
52885 + || IS_SPECIAL_HEADER(p_HdrParams->hdr))
52886 + RETURN_ERROR(
52887 + MAJOR, E_NOT_SUPPORTED,
52888 + ("No additional parameters for private or special headers."));
52889 +
52890 + if (p_HdrParams->errDisable)
52891 + tmpReg |= PRS_HDR_ERROR_DIS;
52892 +
52893 + /* Set parser options */
52894 + if (p_HdrParams->usePrsOpts)
52895 + {
52896 + p_prsOpts = &p_HdrParams->prsOpts;
52897 + switch (p_HdrParams->hdr)
52898 + {
52899 + case (HEADER_TYPE_MPLS):
52900 + if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
52901 + tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
52902 + hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
52903 + if (hdrNum == ILLEGAL_HDR_NUM)
52904 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52905 + Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
52906 + if (hdrNum < Ipv4HdrNum)
52907 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52908 + ("Header must be equal or higher than IPv4"));
52909 + tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
52910 + << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
52911 + break;
52912 + case (HEADER_TYPE_PPPoE):
52913 + if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
52914 + tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
52915 + break;
52916 + case (HEADER_TYPE_IPv6):
52917 + if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
52918 + tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
52919 + break;
52920 + case (HEADER_TYPE_TCP):
52921 + if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
52922 + tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
52923 + else
52924 + tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
52925 + break;
52926 + case (HEADER_TYPE_UDP):
52927 + if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
52928 + tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
52929 + else
52930 + tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
52931 + break;
52932 + default:
52933 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
52934 + }
52935 + }
52936 +
52937 + /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
52938 + if (p_HdrParams->swPrsEnable)
52939 + {
52940 + tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
52941 + p_HdrParams->indexPerHdr);
52942 + if (tmpPrsOffset == ILLEGAL_BASE)
52943 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52944 + tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
52945 + }
52946 + *p_SoftSeqAttachReg = tmpReg;
52947 +
52948 + return E_OK;
52949 +}
52950 +
52951 +static uint32_t GetPortSchemeBindParams(
52952 + t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
52953 +{
52954 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52955 + uint32_t walking1Mask = 0x80000000, tmp;
52956 + uint8_t idx = 0;
52957 +
52958 + p_SchemeBind->netEnvId = p_FmPort->netEnvId;
52959 + p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
52960 + p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
52961 + p_SchemeBind->numOfSchemes = 0;
52962 + tmp = p_FmPort->schemesPerPortVector;
52963 + if (tmp)
52964 + {
52965 + while (tmp)
52966 + {
52967 + if (tmp & walking1Mask)
52968 + {
52969 + p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
52970 + p_SchemeBind->numOfSchemes++;
52971 + tmp &= ~walking1Mask;
52972 + }
52973 + walking1Mask >>= 1;
52974 + idx++;
52975 + }
52976 + }
52977 +
52978 + return tmp;
52979 +}
52980 +
52981 +static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
52982 +{
52983 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52984 + volatile uint32_t *p_BmiCfgReg = NULL;
52985 + uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
52986 + uint32_t lcv, walking1Mask = 0x80000000;
52987 + uint8_t cnt = 0;
52988 +
52989 + ASSERT_COND(p_FmPort);
52990 + ASSERT_COND(p_FmPort->h_FmPcd);
52991 + ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
52992 +
52993 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52994 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52995 + return;
52996 +
52997 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
52998 + /* get LCV for MACSEC */
52999 + if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
53000 + != 0)
53001 + {
53002 + while (!(lcv & walking1Mask))
53003 + {
53004 + cnt++;
53005 + walking1Mask >>= 1;
53006 + }
53007 +
53008 + macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
53009 + WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
53010 + }
53011 +}
53012 +
53013 +static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
53014 +{
53015 + t_Error err = E_OK;
53016 + uint32_t tmpReg;
53017 + volatile uint32_t *p_BmiNia = NULL;
53018 + volatile uint32_t *p_BmiPrsNia = NULL;
53019 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53020 + volatile uint32_t *p_BmiInitPrsResult = NULL;
53021 + volatile uint32_t *p_BmiCcBase = NULL;
53022 + uint16_t hdrNum, L3HdrNum, greHdrNum;
53023 + int i;
53024 + bool isEmptyClsPlanGrp;
53025 + uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
53026 + uint16_t absoluteProfileId;
53027 + uint8_t physicalSchemeId;
53028 + uint32_t ccTreePhysOffset;
53029 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
53030 + uint32_t initialSwPrs = 0;
53031 +
53032 + ASSERT_COND(p_FmPort);
53033 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53034 +
53035 + if (p_FmPort->imEn)
53036 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53037 + ("available for non-independant mode ports only"));
53038 +
53039 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
53040 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
53041 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53042 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53043 + ("available for Rx and offline parsing ports only"));
53044 +
53045 + p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
53046 +
53047 + p_FmPort->pcdEngines = 0;
53048 +
53049 + /* initialize p_FmPort->pcdEngines field in port's structure */
53050 + switch (p_PcdParams->pcdSupport)
53051 + {
53052 + case (e_FM_PORT_PCD_SUPPORT_NONE):
53053 + RETURN_ERROR(
53054 + MAJOR,
53055 + E_INVALID_STATE,
53056 + ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
53057 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
53058 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53059 + break;
53060 + case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
53061 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53062 + break;
53063 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
53064 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53065 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53066 + break;
53067 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
53068 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53069 + p_FmPort->pcdEngines |= FM_PCD_KG;
53070 + break;
53071 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
53072 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53073 + p_FmPort->pcdEngines |= FM_PCD_CC;
53074 + p_FmPort->pcdEngines |= FM_PCD_KG;
53075 + break;
53076 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
53077 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53078 + p_FmPort->pcdEngines |= FM_PCD_KG;
53079 + p_FmPort->pcdEngines |= FM_PCD_CC;
53080 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53081 + break;
53082 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
53083 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53084 + p_FmPort->pcdEngines |= FM_PCD_CC;
53085 + break;
53086 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
53087 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53088 + p_FmPort->pcdEngines |= FM_PCD_CC;
53089 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53090 + break;
53091 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
53092 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53093 + p_FmPort->pcdEngines |= FM_PCD_KG;
53094 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53095 + break;
53096 + case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
53097 + p_FmPort->pcdEngines |= FM_PCD_CC;
53098 + break;
53099 +#ifdef FM_CAPWAP_SUPPORT
53100 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
53101 + p_FmPort->pcdEngines |= FM_PCD_CC;
53102 + p_FmPort->pcdEngines |= FM_PCD_KG;
53103 + break;
53104 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
53105 + p_FmPort->pcdEngines |= FM_PCD_CC;
53106 + p_FmPort->pcdEngines |= FM_PCD_KG;
53107 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53108 + break;
53109 +#endif /* FM_CAPWAP_SUPPORT */
53110 +
53111 + default:
53112 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
53113 + }
53114 +
53115 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
53116 + && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
53117 + > FM_PCD_PRS_NUM_OF_HDRS))
53118 + RETURN_ERROR(
53119 + MAJOR,
53120 + E_INVALID_VALUE,
53121 + ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
53122 +
53123 + /* check that parameters exist for each and only each defined engine */
53124 + if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
53125 + || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
53126 + != !!p_PcdParams->p_KgParams)
53127 + || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
53128 + != !!p_PcdParams->p_CcParams))
53129 + RETURN_ERROR(
53130 + MAJOR,
53131 + E_INVALID_STATE,
53132 + ("PCD initialization structure is not consistent with pcdSupport"));
53133 +
53134 + /* get PCD registers pointers */
53135 + switch (p_FmPort->portType)
53136 + {
53137 + case (e_FM_PORT_TYPE_RX_10G):
53138 + case (e_FM_PORT_TYPE_RX):
53139 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53140 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
53141 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53142 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
53143 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
53144 + break;
53145 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53146 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53147 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
53148 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53149 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
53150 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
53151 + break;
53152 + default:
53153 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53154 + }
53155 +
53156 + /* set PCD port parameter */
53157 + if (p_FmPort->pcdEngines & FM_PCD_CC)
53158 + {
53159 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
53160 + p_PcdParams->p_CcParams->h_CcTree,
53161 + &ccTreePhysOffset, p_FmPort);
53162 + if (err)
53163 + RETURN_ERROR(MAJOR, err, NO_MSG);
53164 +
53165 + WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
53166 + p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
53167 + }
53168 +
53169 + if (p_FmPort->pcdEngines & FM_PCD_KG)
53170 + {
53171 + if (p_PcdParams->p_KgParams->numOfSchemes == 0)
53172 + RETURN_ERROR(
53173 + MAJOR,
53174 + E_INVALID_VALUE,
53175 + ("For ports using Keygen, at least one scheme must be bound. "));
53176 +
53177 + err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
53178 + p_FmPort->hardwarePortId,
53179 + p_FmPort->netEnvId,
53180 + p_FmPort->optArray,
53181 + &p_FmPort->clsPlanGrpId,
53182 + &isEmptyClsPlanGrp);
53183 + if (err)
53184 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53185 + ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
53186 +
53187 + p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
53188 +
53189 + schemeBind.netEnvId = p_FmPort->netEnvId;
53190 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
53191 + schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
53192 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
53193 +
53194 + /* for each scheme */
53195 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
53196 + {
53197 + ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
53198 + physicalSchemeId = FmPcdKgGetSchemeId(
53199 + p_PcdParams->p_KgParams->h_Schemes[i]);
53200 + schemeBind.schemesIds[i] = physicalSchemeId;
53201 + /* build vector */
53202 + p_FmPort->schemesPerPortVector |= 1
53203 + << (31 - (uint32_t)physicalSchemeId);
53204 +#if (DPAA_VERSION >= 11)
53205 + /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
53206 + if !VSPE - in port, for relevant scheme VSPE can not be set*/
53207 + if (!p_FmPort->vspe
53208 + && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
53209 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53210 + ("VSPE is not at port level"));
53211 +#endif /* (DPAA_VERSION >= 11) */
53212 + }
53213 +
53214 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
53215 + if (err)
53216 + RETURN_ERROR(MAJOR, err, NO_MSG);
53217 + }
53218 +
53219 + /***************************/
53220 + /* configure NIA after BMI */
53221 + /***************************/
53222 + /* rfne may contain FDCS bits, so first we read them. */
53223 + p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
53224 +
53225 + /* If policer is used directly after BMI or PRS */
53226 + if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
53227 + && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
53228 + || (p_PcdParams->pcdSupport
53229 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
53230 + {
53231 + if (!p_PcdParams->p_PlcrParams->h_Profile)
53232 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53233 + ("Profile should be initialized"));
53234 +
53235 + absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
53236 + p_PcdParams->p_PlcrParams->h_Profile);
53237 +
53238 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
53239 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53240 + ("Private port profile not valid."));
53241 +
53242 + tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
53243 +
53244 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
53245 + /* update BMI HPNIA */
53246 + WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
53247 + else
53248 + /* e_FM_PCD_SUPPORT_PLCR_ONLY */
53249 + /* update BMI NIA */
53250 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
53251 + }
53252 +
53253 + /* if CC is used directly after BMI */
53254 + if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
53255 +#ifdef FM_CAPWAP_SUPPORT
53256 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
53257 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
53258 +#endif /* FM_CAPWAP_SUPPORT */
53259 + )
53260 + {
53261 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53262 + RETURN_ERROR(
53263 + MAJOR,
53264 + E_INVALID_OPERATION,
53265 + ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
53266 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
53267 + /* check that prs start offset == RIM[FOF] */
53268 + }
53269 +
53270 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53271 + {
53272 + ASSERT_COND(p_PcdParams->p_PrsParams);
53273 +#if (DPAA_VERSION >= 11)
53274 + if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
53275 + hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
53276 + else
53277 + {
53278 +#endif /* (DPAA_VERSION >= 11) */
53279 + /* if PRS is used it is always first */
53280 + hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
53281 + if (hdrNum == ILLEGAL_HDR_NUM)
53282 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
53283 +#if (DPAA_VERSION >= 11)
53284 + }
53285 +#endif /* (DPAA_VERSION >= 11) */
53286 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
53287 + /* set after parser NIA */
53288 + tmpReg = 0;
53289 + switch (p_PcdParams->pcdSupport)
53290 + {
53291 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
53292 + WRITE_UINT32(*p_BmiPrsNia,
53293 + GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
53294 + break;
53295 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
53296 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
53297 + tmpReg = NIA_KG_CC_EN;
53298 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
53299 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
53300 + if (p_PcdParams->p_KgParams->directScheme)
53301 + {
53302 + physicalSchemeId = FmPcdKgGetSchemeId(
53303 + p_PcdParams->p_KgParams->h_DirectScheme);
53304 + /* check that this scheme was bound to this port */
53305 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
53306 + if (p_PcdParams->p_KgParams->h_DirectScheme
53307 + == p_PcdParams->p_KgParams->h_Schemes[i])
53308 + break;
53309 + if (i == p_PcdParams->p_KgParams->numOfSchemes)
53310 + RETURN_ERROR(
53311 + MAJOR,
53312 + E_INVALID_VALUE,
53313 + ("Direct scheme is not one of the port selected schemes."));
53314 + tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
53315 + }
53316 + WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
53317 + break;
53318 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
53319 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
53320 + WRITE_UINT32(*p_BmiPrsNia,
53321 + (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
53322 + break;
53323 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
53324 + break;
53325 + default:
53326 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
53327 + }
53328 +
53329 + /* set start parsing offset */
53330 + WRITE_UINT32(*p_BmiPrsStartOffset,
53331 + p_PcdParams->p_PrsParams->parsingOffset);
53332 +
53333 + /************************************/
53334 + /* Parser port parameters */
53335 + /************************************/
53336 + /* stop before configuring */
53337 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53338 + /* wait for parser to be in idle state */
53339 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53340 + ;
53341 +
53342 + /* set soft seq attachment register */
53343 + memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
53344 +
53345 + /* set protocol options */
53346 + for (i = 0; p_FmPort->optArray[i]; i++)
53347 + switch (p_FmPort->optArray[i])
53348 + {
53349 + case (ETH_BROADCAST):
53350 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
53351 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
53352 + break;
53353 + case (ETH_MULTICAST):
53354 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
53355 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
53356 + break;
53357 + case (VLAN_STACKED):
53358 + hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
53359 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
53360 + break;
53361 + case (MPLS_STACKED):
53362 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53363 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
53364 + break;
53365 + case (IPV4_BROADCAST_1):
53366 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53367 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
53368 + break;
53369 + case (IPV4_MULTICAST_1):
53370 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53371 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
53372 + break;
53373 + case (IPV4_UNICAST_2):
53374 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53375 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
53376 + break;
53377 + case (IPV4_MULTICAST_BROADCAST_2):
53378 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53379 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
53380 + break;
53381 + case (IPV6_MULTICAST_1):
53382 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53383 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
53384 + break;
53385 + case (IPV6_UNICAST_2):
53386 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53387 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
53388 + break;
53389 + case (IPV6_MULTICAST_2):
53390 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53391 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
53392 + break;
53393 + }
53394 +
53395 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53396 + HEADER_TYPE_UDP_ENCAP_ESP))
53397 + {
53398 + if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
53399 + RETURN_ERROR(
53400 + MINOR, E_INVALID_VALUE,
53401 + ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
53402 +
53403 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
53404 + HEADER_TYPE_UDP;
53405 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
53406 + TRUE;
53407 + p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
53408 + }
53409 +
53410 + /* set MPLS default next header - HW reset workaround */
53411 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53412 + tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
53413 + L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
53414 + tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
53415 +
53416 + /* for GRE, disable errors */
53417 + greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
53418 + tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
53419 +
53420 + /* For UDP remove PAD from L4 checksum calculation */
53421 + hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
53422 + tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
53423 + /* For TCP remove PAD from L4 checksum calculation */
53424 + hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
53425 + tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
53426 +
53427 + /* config additional params for specific headers */
53428 + for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
53429 + i++)
53430 + {
53431 + /* case for using sw parser as the initial NIA address, before
53432 + * HW parsing
53433 + */
53434 + if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
53435 + p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
53436 + {
53437 + initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
53438 + p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
53439 + if (initialSwPrs == ILLEGAL_BASE)
53440 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53441 +
53442 + /* clear parser first HXS */
53443 + p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
53444 + /* rewrite with soft parser start */
53445 + p_FmPort->savedBmiNia |= initialSwPrs;
53446 + continue;
53447 + }
53448 +
53449 + hdrNum =
53450 + GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
53451 + if (hdrNum == ILLEGAL_HDR_NUM)
53452 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53453 + if (hdrNum == NO_HDR_NUM)
53454 + RETURN_ERROR(
53455 + MAJOR, E_INVALID_VALUE,
53456 + ("Private headers may not use additional parameters"));
53457 +
53458 + err = AdditionalPrsParams(
53459 + p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
53460 + &tmpHxs[hdrNum]);
53461 + if (err)
53462 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53463 + }
53464 +
53465 + /* Check if ip-reassembly port - need to link sw-parser code */
53466 + if (p_FmPort->h_IpReassemblyManip)
53467 + {
53468 + /* link to sw parser code for IP Frag - only if no other code is applied. */
53469 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53470 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53471 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
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_IPR_LABEL);
53475 + } else {
53476 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
53477 + {
53478 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53479 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53480 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53481 + } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53482 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
53483 + {
53484 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53485 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53486 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53487 + }
53488 + }
53489 +
53490 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
53491 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53492 + HEADER_TYPE_UDP_LITE))
53493 + {
53494 + /* link to sw parser code for udp lite - only if no other code is applied. */
53495 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53496 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53497 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
53498 + }
53499 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
53500 + for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
53501 + {
53502 + /* For all header set LCV as taken from netEnv*/
53503 + WRITE_UINT32(
53504 + p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
53505 + FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
53506 + /* set HXS register according to default+Additional params+protocol options */
53507 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
53508 + tmpHxs[i]);
53509 + }
53510 +
53511 + /* set tpid. */
53512 + tmpReg = PRS_TPID_DFLT;
53513 + if (p_PcdParams->p_PrsParams->setVlanTpid1)
53514 + {
53515 + tmpReg &= PRS_TPID2_MASK;
53516 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
53517 + << PRS_PCTPID_SHIFT;
53518 + }
53519 + if (p_PcdParams->p_PrsParams->setVlanTpid2)
53520 + {
53521 + tmpReg &= PRS_TPID1_MASK;
53522 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
53523 + }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
53524 +
53525 + /* enable parser */
53526 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
53527 +
53528 + if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
53529 + p_FmPort->privateInfo =
53530 + p_PcdParams->p_PrsParams->prsResultPrivateInfo;
53531 +
53532 + } /* end parser */
53533 + else {
53534 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53535 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53536 + {
53537 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53538 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
53539 + (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
53540 + }
53541 +
53542 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53543 +
53544 + p_FmPort->privateInfo = 0;
53545 + }
53546 +
53547 + FmPortCheckNApplyMacsec(p_FmPort);
53548 +
53549 + WRITE_UINT32(
53550 + *p_BmiPrsStartOffset,
53551 + GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
53552 +
53553 + /* set initial parser result - used for all engines */
53554 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
53555 + {
53556 + if (!i)
53557 + WRITE_UINT32(
53558 + *(p_BmiInitPrsResult),
53559 + (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
53560 + else
53561 + {
53562 + if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
53563 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
53564 + else
53565 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
53566 + }
53567 + }
53568 +
53569 + return E_OK;
53570 +}
53571 +
53572 +static t_Error DeletePcd(t_FmPort *p_FmPort)
53573 +{
53574 + t_Error err = E_OK;
53575 + volatile uint32_t *p_BmiNia = NULL;
53576 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53577 +
53578 + ASSERT_COND(p_FmPort);
53579 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53580 +
53581 + if (p_FmPort->imEn)
53582 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53583 + ("available for non-independant mode ports only"));
53584 +
53585 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
53586 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
53587 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53588 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53589 + ("available for Rx and offline parsing ports only"));
53590 +
53591 + if (!p_FmPort->pcdEngines)
53592 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
53593 +
53594 + /* get PCD registers pointers */
53595 + switch (p_FmPort->portType)
53596 + {
53597 + case (e_FM_PORT_TYPE_RX_10G):
53598 + case (e_FM_PORT_TYPE_RX):
53599 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53600 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53601 + break;
53602 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53603 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53604 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53605 + break;
53606 + default:
53607 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53608 + }
53609 +
53610 + if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53611 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53612 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53613 + ("port has to be detached previousely"));
53614 +
53615 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53616 +
53617 + /* "cut" PCD out of the port's flow - go to BMI */
53618 + /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
53619 +
53620 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53621 + {
53622 + /* stop parser */
53623 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53624 + /* wait for parser to be in idle state */
53625 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53626 + ;
53627 + }
53628 +
53629 + if (p_FmPort->pcdEngines & FM_PCD_KG)
53630 + {
53631 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
53632 +
53633 + /* unbind all schemes */
53634 + p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
53635 + &schemeBind);
53636 +
53637 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
53638 + if (err)
53639 + RETURN_ERROR(MAJOR, err, NO_MSG);
53640 +
53641 + err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
53642 + p_FmPort->hardwarePortId,
53643 + p_FmPort->clsPlanGrpId);
53644 + if (err)
53645 + RETURN_ERROR(MAJOR, err, NO_MSG);
53646 + p_FmPort->useClsPlan = FALSE;
53647 + }
53648 +
53649 + if (p_FmPort->pcdEngines & FM_PCD_CC)
53650 + {
53651 + /* unbind - we need to get the treeId too */
53652 + err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
53653 + if (err)
53654 + RETURN_ERROR(MAJOR, err, NO_MSG);
53655 + }
53656 +
53657 + p_FmPort->pcdEngines = 0;
53658 +
53659 + return E_OK;
53660 +}
53661 +
53662 +static t_Error AttachPCD(t_FmPort *p_FmPort)
53663 +{
53664 + volatile uint32_t *p_BmiNia = NULL;
53665 +
53666 + ASSERT_COND(p_FmPort);
53667 +
53668 + /* get PCD registers pointers */
53669 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53670 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53671 + else
53672 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53673 +
53674 + /* check that current NIA is BMI to BMI */
53675 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
53676 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53677 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53678 + ("may be called only for ports in BMI-to-BMI state."));
53679 +
53680 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53681 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
53682 + p_FmPort->orFmanCtrl) != E_OK)
53683 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53684 +
53685 + if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
53686 + {
53687 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53688 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
53689 + p_FmPort->savedBmiCmne);
53690 + else
53691 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
53692 + p_FmPort->savedBmiCmne);
53693 + }
53694 +
53695 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53696 + WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
53697 + p_FmPort->savedQmiPnen);
53698 +
53699 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53700 + {
53701 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53702 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53703 + p_FmPort->savedBmiFene);
53704 + else
53705 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53706 + p_FmPort->savedBmiFene);
53707 + }
53708 +
53709 + if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
53710 + {
53711 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53712 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
53713 + p_FmPort->savedBmiFpne);
53714 + else
53715 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
53716 + p_FmPort->savedBmiFpne);
53717 + }
53718 +
53719 + if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
53720 + {
53721 + ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
53722 +
53723 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
53724 + p_FmPort->savedBmiOfp);
53725 + }
53726 +
53727 + WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
53728 +
53729 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53730 + {
53731 + p_FmPort->origNonRxQmiRegsPndn =
53732 + GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
53733 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53734 + p_FmPort->savedNonRxQmiRegsPndn);
53735 + }
53736 +
53737 + return E_OK;
53738 +}
53739 +
53740 +static t_Error DetachPCD(t_FmPort *p_FmPort)
53741 +{
53742 + volatile uint32_t *p_BmiNia = NULL;
53743 +
53744 + ASSERT_COND(p_FmPort);
53745 +
53746 + /* get PCD registers pointers */
53747 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53748 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53749 + p_FmPort->origNonRxQmiRegsPndn);
53750 +
53751 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53752 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53753 + else
53754 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53755 +
53756 + WRITE_UINT32(
53757 + *p_BmiNia,
53758 + (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
53759 +
53760 + if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
53761 + FmPcdHcSync(p_FmPort->h_FmPcd);
53762 +
53763 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53764 + {
53765 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53766 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53767 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53768 + else
53769 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53770 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53771 + }
53772 +
53773 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53774 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
53775 + NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
53776 +
53777 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53778 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
53779 + p_FmPort->orFmanCtrl) != E_OK)
53780 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53781 +
53782 + p_FmPort->requiredAction = 0;
53783 +
53784 + return E_OK;
53785 +}
53786 +
53787 +/*****************************************************************************/
53788 +/* Inter-module API routines */
53789 +/*****************************************************************************/
53790 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
53791 +{
53792 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53793 + volatile uint32_t *p_BmiCfgReg = NULL;
53794 + uint32_t tmpReg;
53795 +
53796 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
53797 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53798 +
53799 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
53800 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
53801 + {
53802 + REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
53803 + return;
53804 + }
53805 +
53806 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
53807 + tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
53808 + tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
53809 + tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
53810 + & BMI_CMD_ATTR_MACCMD_SC_MASK);
53811 +
53812 + WRITE_UINT32(*p_BmiCfgReg, tmpReg);
53813 +}
53814 +
53815 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
53816 +{
53817 + return ((t_FmPort*)h_FmPort)->netEnvId;
53818 +}
53819 +
53820 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
53821 +{
53822 + return ((t_FmPort*)h_FmPort)->hardwarePortId;
53823 +}
53824 +
53825 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
53826 +{
53827 + return ((t_FmPort*)h_FmPort)->pcdEngines;
53828 +}
53829 +
53830 +#if (DPAA_VERSION >= 11)
53831 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
53832 + void **p_Value)
53833 +{
53834 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53835 + uint32_t muramPageOffset;
53836 +
53837 + ASSERT_COND(p_FmPort);
53838 + ASSERT_COND(p_Value);
53839 +
53840 + if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
53841 + {
53842 + if (p_FmPort->gprFunc != gprFunc)
53843 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53844 + ("gpr was assigned with different func"));
53845 + }
53846 + else
53847 + {
53848 + switch (gprFunc)
53849 + {
53850 + case (e_FM_PORT_GPR_MURAM_PAGE):
53851 + p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
53852 + 256, 8);
53853 + if (!p_FmPort->p_ParamsPage)
53854 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
53855 +
53856 + IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
53857 + muramPageOffset =
53858 + (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
53859 + - p_FmPort->fmMuramPhysBaseAddr);
53860 + switch (p_FmPort->portType)
53861 + {
53862 + case (e_FM_PORT_TYPE_RX_10G):
53863 + case (e_FM_PORT_TYPE_RX):
53864 + WRITE_UINT32(
53865 + p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
53866 + muramPageOffset);
53867 + break;
53868 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53869 + WRITE_UINT32(
53870 + p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
53871 + muramPageOffset);
53872 + break;
53873 + default:
53874 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53875 + ("Invalid port type"));
53876 + }
53877 + break;
53878 + default:
53879 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53880 + }
53881 + p_FmPort->gprFunc = gprFunc;
53882 + }
53883 +
53884 + switch (p_FmPort->gprFunc)
53885 + {
53886 + case (e_FM_PORT_GPR_MURAM_PAGE):
53887 + *p_Value = p_FmPort->p_ParamsPage;
53888 + break;
53889 + default:
53890 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53891 + }
53892 +
53893 + return E_OK;
53894 +}
53895 +#endif /* (DPAA_VERSION >= 11) */
53896 +
53897 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
53898 + t_FmPortGetSetCcParams *p_CcParams)
53899 +{
53900 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53901 + int tmpInt;
53902 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53903 +
53904 + /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
53905 +
53906 + if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
53907 + && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
53908 + {
53909 + p_CcParams->getCcParams.prOffset =
53910 + (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
53911 + p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
53912 + }
53913 + if (p_CcParams->getCcParams.type & HW_PORT_ID)
53914 + {
53915 + p_CcParams->getCcParams.hardwarePortId =
53916 + (uint8_t)p_FmPort->hardwarePortId;
53917 + p_CcParams->getCcParams.type &= ~HW_PORT_ID;
53918 + }
53919 + if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
53920 + && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
53921 + {
53922 + p_CcParams->getCcParams.dataOffset =
53923 + (uint16_t)p_FmPort->bufferOffsets.dataOffset;
53924 + p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
53925 + }
53926 + if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
53927 + {
53928 + p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
53929 + p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
53930 + }
53931 + if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
53932 + {
53933 + p_CcParams->getCcParams.numOfExtraTasks =
53934 + (uint8_t)p_FmPort->tasks.extra;
53935 + p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
53936 + }
53937 + if (p_CcParams->getCcParams.type & FM_REV)
53938 + {
53939 + p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
53940 + p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
53941 + p_CcParams->getCcParams.type &= ~FM_REV;
53942 + }
53943 + if (p_CcParams->getCcParams.type & DISCARD_MASK)
53944 + {
53945 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53946 + p_CcParams->getCcParams.discardMask =
53947 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
53948 + else
53949 + p_CcParams->getCcParams.discardMask =
53950 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
53951 + p_CcParams->getCcParams.type &= ~DISCARD_MASK;
53952 + }
53953 + if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
53954 + {
53955 + p_CcParams->getCcParams.internalBufferOffset =
53956 + p_FmPort->internalBufferOffset;
53957 + p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
53958 + }
53959 + if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
53960 + {
53961 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53962 + p_CcParams->getCcParams.nia =
53963 + GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
53964 + else
53965 + p_CcParams->getCcParams.nia =
53966 + GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
53967 + p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
53968 + }
53969 + if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
53970 + {
53971 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53972 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53973 + p_CcParams->getCcParams.nia =
53974 + GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
53975 + p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
53976 + }
53977 +
53978 + if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53979 + && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
53980 + {
53981 + p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
53982 + p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
53983 + }
53984 +
53985 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53986 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
53987 + {
53988 + p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
53989 + p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
53990 + }
53991 + else
53992 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53993 + {
53994 + if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
53995 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53996 + ("PNEN was defined previously different"));
53997 + }
53998 +
53999 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
54000 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
54001 + {
54002 + p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
54003 + p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
54004 + }
54005 + else
54006 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
54007 + {
54008 + if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
54009 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
54010 + ("PNDN was defined previously different"));
54011 + }
54012 +
54013 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
54014 + && (p_CcParams->setCcParams.overwrite
54015 + || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
54016 + {
54017 + p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
54018 + p_FmPort->requiredAction |= UPDATE_NIA_FENE;
54019 + }
54020 + else
54021 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
54022 + {
54023 + if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
54024 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
54025 + ("xFENE was defined previously different"));
54026 + }
54027 +
54028 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
54029 + && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
54030 + {
54031 + p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
54032 + p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
54033 + }
54034 + else
54035 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
54036 + {
54037 + if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
54038 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
54039 + ("xFPNE was defined previously different"));
54040 + }
54041 +
54042 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
54043 + && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
54044 + {
54045 + p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
54046 + p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
54047 + }
54048 + else
54049 + if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
54050 + {
54051 + if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
54052 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
54053 + ("xCMNE was defined previously different"));
54054 + }
54055 +
54056 + if ((p_CcParams->setCcParams.type & UPDATE_PSO)
54057 + && !(p_FmPort->requiredAction & UPDATE_PSO))
54058 + {
54059 + /* get PCD registers pointers */
54060 + switch (p_FmPort->portType)
54061 + {
54062 + case (e_FM_PORT_TYPE_RX_10G):
54063 + case (e_FM_PORT_TYPE_RX):
54064 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
54065 + break;
54066 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54067 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
54068 + break;
54069 + default:
54070 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54071 + }
54072 +
54073 + /* set start parsing offset */
54074 + tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
54075 + + p_CcParams->setCcParams.psoSize;
54076 + if (tmpInt > 0)
54077 + WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
54078 +
54079 + p_FmPort->requiredAction |= UPDATE_PSO;
54080 + p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
54081 + }
54082 + else
54083 + if (p_CcParams->setCcParams.type & UPDATE_PSO)
54084 + {
54085 + if (p_FmPort->savedPrsStartOffset
54086 + != p_CcParams->setCcParams.psoSize)
54087 + RETURN_ERROR(
54088 + MAJOR,
54089 + E_INVALID_STATE,
54090 + ("parser start offset was defoned previousley different"));
54091 + }
54092 +
54093 + if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
54094 + && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
54095 + {
54096 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54097 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54098 + p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
54099 + p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
54100 + p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
54101 + << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
54102 + p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
54103 + }
54104 +
54105 + return E_OK;
54106 +}
54107 +/*********************** End of inter-module routines ************************/
54108 +
54109 +/****************************************/
54110 +/* API Init unit functions */
54111 +/****************************************/
54112 +
54113 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
54114 +{
54115 + t_FmPort *p_FmPort;
54116 + uintptr_t baseAddr = p_FmPortParams->baseAddr;
54117 + uint32_t tmpReg;
54118 +
54119 + /* Allocate FM structure */
54120 + p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
54121 + if (!p_FmPort)
54122 + {
54123 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
54124 + return NULL;
54125 + }
54126 + memset(p_FmPort, 0, sizeof(t_FmPort));
54127 +
54128 + /* Allocate the FM driver's parameters structure */
54129 + p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
54130 + sizeof(t_FmPortDriverParam));
54131 + if (!p_FmPort->p_FmPortDriverParam)
54132 + {
54133 + XX_Free(p_FmPort);
54134 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
54135 + return NULL;
54136 + }
54137 + memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
54138 +
54139 + /* Initialize FM port parameters which will be kept by the driver */
54140 + p_FmPort->portType = p_FmPortParams->portType;
54141 + p_FmPort->portId = p_FmPortParams->portId;
54142 + p_FmPort->pcdEngines = FM_PCD_NONE;
54143 + p_FmPort->f_Exception = p_FmPortParams->f_Exception;
54144 + p_FmPort->h_App = p_FmPortParams->h_App;
54145 + p_FmPort->h_Fm = p_FmPortParams->h_Fm;
54146 +
54147 + /* get FM revision */
54148 + FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
54149 +
54150 + /* calculate global portId number */
54151 + p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
54152 + p_FmPortParams->portId,
54153 + p_FmPort->fmRevInfo.majorRev,
54154 + p_FmPort->fmRevInfo.minorRev);
54155 +
54156 + if (p_FmPort->fmRevInfo.majorRev >= 6)
54157 + {
54158 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
54159 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
54160 + DBG(WARNING,
54161 + ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
54162 + FM_OH_PORT_ID));
54163 +
54164 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54165 + && (p_FmPortParams->portId == FM_OH_PORT_ID))
54166 + DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
54167 + }
54168 +
54169 + /* Set up FM port parameters for initialization phase only */
54170 +
54171 + /* First, fill in flibs struct */
54172 + fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
54173 + (enum fman_port_type)p_FmPort->portType);
54174 + /* Overwrite some integration specific parameters */
54175 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
54176 + DEFAULT_PORT_rxFifoPriElevationLevel;
54177 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
54178 + DEFAULT_PORT_rxFifoThreshold;
54179 +
54180 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
54181 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
54182 +#else
54183 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
54184 +#endif
54185 + if ((p_FmPort->fmRevInfo.majorRev == 6)
54186 + && (p_FmPort->fmRevInfo.minorRev == 0))
54187 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
54188 + else
54189 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
54190 +
54191 + /* Excessive Threshold register - exists for pre-FMv3 chips only */
54192 + if (p_FmPort->fmRevInfo.majorRev < 6)
54193 + {
54194 +#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
54195 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
54196 + TRUE;
54197 +#endif
54198 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
54199 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
54200 + }
54201 + else
54202 + {
54203 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
54204 + FALSE;
54205 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
54206 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
54207 + }
54208 + if (p_FmPort->fmRevInfo.majorRev == 4)
54209 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
54210 + else
54211 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
54212 +
54213 + /* Continue with other parameters */
54214 + p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
54215 + /* set memory map pointers */
54216 + p_FmPort->p_FmPortQmiRegs =
54217 + (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
54218 + p_FmPort->p_FmPortBmiRegs =
54219 + (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
54220 + p_FmPort->p_FmPortPrsRegs =
54221 + (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
54222 +
54223 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
54224 + DEFAULT_PORT_bufferPrefixContent_privDataSize;
54225 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
54226 + DEFAULT_PORT_bufferPrefixContent_passPrsResult;
54227 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
54228 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
54229 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
54230 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
54231 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
54232 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
54233 + /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
54234 + p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
54235 + p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
54236 + p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
54237 + p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
54238 + */
54239 + p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
54240 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
54241 + DEFAULT_PORT_cheksumLastBytesIgnore;
54242 +
54243 + p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
54244 + /* resource distribution. */
54245 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
54246 + * BMI_FIFO_UNITS;
54247 + p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
54248 + * BMI_FIFO_UNITS;
54249 + p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
54250 + p_FmPort->openDmas.extra =
54251 + DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
54252 + p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
54253 + p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
54254 +
54255 +
54256 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
54257 + if ((p_FmPort->fmRevInfo.majorRev == 6)
54258 + && (p_FmPort->fmRevInfo.minorRev == 0)
54259 + && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54260 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
54261 + {
54262 + p_FmPort->openDmas.num = 16;
54263 + p_FmPort->openDmas.extra = 0;
54264 + }
54265 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
54266 +
54267 + /* Port type specific initialization: */
54268 + switch (p_FmPort->portType)
54269 + {
54270 + case (e_FM_PORT_TYPE_RX):
54271 + case (e_FM_PORT_TYPE_RX_10G):
54272 + /* Initialize FM port parameters for initialization phase only */
54273 + p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
54274 + DEFAULT_PORT_cutBytesFromEnd;
54275 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
54276 + p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
54277 + DEFAULT_PORT_frmDiscardOverride;
54278 +
54279 + tmpReg =
54280 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
54281 + p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
54282 + (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
54283 + >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
54284 + * BMI_FIFO_UNITS;
54285 + p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
54286 + & BMI_RX_FIFO_THRESHOLD_MASK)
54287 + >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
54288 +
54289 + p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
54290 + DEFAULT_PORT_BufMargins_endMargins;
54291 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
54292 + DEFAULT_PORT_errorsToDiscard;
54293 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
54294 + DEFAULT_PORT_forwardIntContextReuse;
54295 +#if (DPAA_VERSION >= 11)
54296 + p_FmPort->p_FmPortDriverParam->noScatherGather =
54297 + DEFAULT_PORT_noScatherGather;
54298 +#endif /* (DPAA_VERSION >= 11) */
54299 + break;
54300 +
54301 + case (e_FM_PORT_TYPE_TX):
54302 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
54303 +#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
54304 + tmpReg = 0x00001013;
54305 + WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
54306 + tmpReg);
54307 +#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
54308 + case (e_FM_PORT_TYPE_TX_10G):
54309 + tmpReg =
54310 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
54311 + p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
54312 + & BMI_TX_FIFO_MIN_FILL_MASK)
54313 + >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
54314 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54315 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
54316 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
54317 + p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
54318 + & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
54319 + * BMI_FIFO_UNITS;
54320 +
54321 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
54322 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
54323 + DEFAULT_PORT_deqPrefetchOption;
54324 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
54325 + (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
54326 + DEFAULT_PORT_deqHighPriority_10G);
54327 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
54328 + (uint16_t)(
54329 + (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
54330 + DEFAULT_PORT_deqByteCnt_10G);
54331 + break;
54332 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54333 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
54334 + DEFAULT_PORT_errorsToDiscard;
54335 +#if (DPAA_VERSION >= 11)
54336 + p_FmPort->p_FmPortDriverParam->noScatherGather =
54337 + DEFAULT_PORT_noScatherGather;
54338 +#endif /* (DPAA_VERSION >= 11) */
54339 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54340 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
54341 + DEFAULT_PORT_deqPrefetchOption_HC;
54342 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
54343 + DEFAULT_PORT_deqHighPriority_1G;
54344 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
54345 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
54346 + DEFAULT_PORT_deqByteCnt_1G;
54347 +
54348 + tmpReg =
54349 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
54350 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54351 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
54352 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
54353 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
54354 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
54355 + {
54356 + /* Overwrite HC defaults */
54357 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54358 + DEFAULT_PORT_fifoDeqPipelineDepth_OH;
54359 + }
54360 +
54361 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
54362 + if (p_FmPort->fmRevInfo.majorRev < 6)
54363 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
54364 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
54365 +
54366 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54367 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54368 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54369 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
54370 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54371 + break;
54372 +
54373 + default:
54374 + XX_Free(p_FmPort->p_FmPortDriverParam);
54375 + XX_Free(p_FmPort);
54376 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54377 + return NULL;
54378 + }
54379 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
54380 + if (p_FmPort->fmRevInfo.majorRev == 4)
54381 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
54382 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
54383 +
54384 + p_FmPort->imEn = p_FmPortParams->independentModeEnable;
54385 +
54386 + if (p_FmPort->imEn)
54387 + {
54388 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
54389 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
54390 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54391 + DEFAULT_PORT_fifoDeqPipelineDepth_IM;
54392 + FmPortConfigIM(p_FmPort, p_FmPortParams);
54393 + }
54394 + else
54395 + {
54396 + switch (p_FmPort->portType)
54397 + {
54398 + case (e_FM_PORT_TYPE_RX):
54399 + case (e_FM_PORT_TYPE_RX_10G):
54400 + /* Initialize FM port parameters for initialization phase only */
54401 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54402 + &p_FmPortParams->specificParams.rxParams.extBufPools,
54403 + sizeof(t_FmExtPools));
54404 + p_FmPort->p_FmPortDriverParam->errFqid =
54405 + p_FmPortParams->specificParams.rxParams.errFqid;
54406 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54407 + p_FmPortParams->specificParams.rxParams.dfltFqid;
54408 + p_FmPort->p_FmPortDriverParam->liodnOffset =
54409 + p_FmPortParams->specificParams.rxParams.liodnOffset;
54410 + break;
54411 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54412 + case (e_FM_PORT_TYPE_TX):
54413 + case (e_FM_PORT_TYPE_TX_10G):
54414 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54415 + p_FmPort->p_FmPortDriverParam->errFqid =
54416 + p_FmPortParams->specificParams.nonRxParams.errFqid;
54417 + p_FmPort->p_FmPortDriverParam->deqSubPortal =
54418 + (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
54419 + & QMI_DEQ_CFG_SUBPORTAL_MASK);
54420 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54421 + p_FmPortParams->specificParams.nonRxParams.dfltFqid;
54422 + break;
54423 + default:
54424 + XX_Free(p_FmPort->p_FmPortDriverParam);
54425 + XX_Free(p_FmPort);
54426 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54427 + return NULL;
54428 + }
54429 + }
54430 +
54431 + memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
54432 + if (Sprint(
54433 + p_FmPort->name,
54434 + "FM-%d-port-%s-%d",
54435 + FmGetId(p_FmPort->h_Fm),
54436 + ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
54437 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
54438 + (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
54439 + (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
54440 + (p_FmPort->portType
54441 + == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
54442 + "10g-TX")))),
54443 + p_FmPort->portId) == 0)
54444 + {
54445 + XX_Free(p_FmPort->p_FmPortDriverParam);
54446 + XX_Free(p_FmPort);
54447 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54448 + return NULL;
54449 + }
54450 +
54451 + p_FmPort->h_Spinlock = XX_InitSpinlock();
54452 + if (!p_FmPort->h_Spinlock)
54453 + {
54454 + XX_Free(p_FmPort->p_FmPortDriverParam);
54455 + XX_Free(p_FmPort);
54456 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54457 + return NULL;
54458 + }
54459 +
54460 + return p_FmPort;
54461 +}
54462 +
54463 +t_FmPort *rx_port = 0;
54464 +t_FmPort *tx_port = 0;
54465 +
54466 +/**************************************************************************//**
54467 + @Function FM_PORT_Init
54468 +
54469 + @Description Initializes the FM module
54470 +
54471 + @Param[in] h_FmPort - FM module descriptor
54472 +
54473 + @Return E_OK on success; Error code otherwise.
54474 + *//***************************************************************************/
54475 +t_Error FM_PORT_Init(t_Handle h_FmPort)
54476 +{
54477 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54478 + t_FmPortDriverParam *p_DriverParams;
54479 + t_Error errCode;
54480 + t_FmInterModulePortInitParams fmParams;
54481 + t_FmRevisionInfo revInfo;
54482 +
54483 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
54484 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54485 +
54486 + errCode = FmSpBuildBufferStructure(
54487 + &p_FmPort->p_FmPortDriverParam->intContext,
54488 + &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54489 + &p_FmPort->p_FmPortDriverParam->bufMargins,
54490 + &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
54491 + if (errCode != E_OK)
54492 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54493 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
54494 + if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
54495 + (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54496 + {
54497 + p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
54498 + if (!p_FmPort->fifoBufs.num)
54499 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
54500 + p_FmPort->fifoBufs.num += 4*KILOBYTE;
54501 + }
54502 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
54503 +
54504 + CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
54505 +
54506 + p_DriverParams = p_FmPort->p_FmPortDriverParam;
54507 +
54508 + /* Set up flibs port structure */
54509 + memset(&p_FmPort->port, 0, sizeof(struct fman_port));
54510 + p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
54511 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54512 + p_FmPort->port.fm_rev_maj = revInfo.majorRev;
54513 + p_FmPort->port.fm_rev_min = revInfo.minorRev;
54514 + p_FmPort->port.bmi_regs =
54515 + (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
54516 + p_FmPort->port.qmi_regs =
54517 + (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
54518 + p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
54519 + p_FmPort->port.im_en = p_FmPort->imEn;
54520 + p_FmPort->p_FmPortPrsRegs =
54521 + (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
54522 +
54523 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54524 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
54525 + {
54526 + /* Call the external Buffer routine which also checks fifo
54527 + size and updates it if necessary */
54528 + /* define external buffer pools and pool depletion*/
54529 + errCode = SetExtBufferPools(p_FmPort);
54530 + if (errCode)
54531 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54532 + /* check if the largest external buffer pool is large enough */
54533 + if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
54534 + + p_DriverParams->bufMargins.endMargins
54535 + > p_FmPort->rxPoolsParams.largestBufSize)
54536 + RETURN_ERROR(
54537 + MAJOR,
54538 + E_INVALID_VALUE,
54539 + ("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));
54540 + }
54541 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54542 + {
54543 + {
54544 +#ifdef FM_NO_OP_OBSERVED_POOLS
54545 + t_FmRevisionInfo revInfo;
54546 +
54547 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54548 + if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
54549 +#endif /* FM_NO_OP_OBSERVED_POOLS */
54550 + {
54551 + /* define external buffer pools */
54552 + errCode = SetExtBufferPools(p_FmPort);
54553 + if (errCode)
54554 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54555 + }
54556 + }
54557 + }
54558 +
54559 + /************************************************************/
54560 + /* Call FM module routine for communicating parameters */
54561 + /************************************************************/
54562 + memset(&fmParams, 0, sizeof(fmParams));
54563 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54564 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54565 + fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
54566 + fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
54567 + fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
54568 + fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
54569 +
54570 + if (p_FmPort->fifoBufs.num)
54571 + {
54572 + errCode = VerifySizeOfFifo(p_FmPort);
54573 + if (errCode != E_OK)
54574 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54575 + }
54576 + fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
54577 + fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
54578 + fmParams.independentMode = p_FmPort->imEn;
54579 + fmParams.liodnOffset = p_DriverParams->liodnOffset;
54580 + fmParams.liodnBase = p_DriverParams->liodnBase;
54581 + fmParams.deqPipelineDepth =
54582 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54583 + fmParams.maxFrameLength = p_FmPort->maxFrameLength;
54584 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54585 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
54586 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
54587 + {
54588 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54589 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54590 + /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
54591 + * for deq threshold calculation.
54592 + */
54593 + fmParams.deqPipelineDepth = 2;
54594 + }
54595 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54596 +
54597 + errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
54598 + if (errCode)
54599 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54600 +
54601 + /* get params for use in init */
54602 + p_FmPort->fmMuramPhysBaseAddr =
54603 + (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
54604 + | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
54605 + p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
54606 +
54607 + errCode = InitLowLevelDriver(p_FmPort);
54608 + if (errCode != E_OK)
54609 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54610 +
54611 + FmPortDriverParamFree(p_FmPort);
54612 +
54613 +#if (DPAA_VERSION >= 11)
54614 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54615 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
54616 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54617 + {
54618 + t_FmPcdCtrlParamsPage *p_ParamsPage;
54619 +
54620 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
54621 + (void**)&p_ParamsPage);
54622 + ASSERT_COND(p_ParamsPage);
54623 +
54624 + WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
54625 +#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
54626 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54627 + {
54628 + WRITE_UINT32(
54629 + p_ParamsPage->misc,
54630 + (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
54631 + WRITE_UINT32(
54632 + p_ParamsPage->discardMask,
54633 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
54634 + }
54635 +#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
54636 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
54637 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54638 + WRITE_UINT32(
54639 + p_ParamsPage->errorsDiscardMask,
54640 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
54641 + else
54642 + WRITE_UINT32(
54643 + p_ParamsPage->errorsDiscardMask,
54644 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
54645 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
54646 + }
54647 +#endif /* (DPAA_VERSION >= 11) */
54648 +
54649 + if (p_FmPort->deepSleepVars.autoResMaxSizes)
54650 + FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
54651 + return E_OK;
54652 +}
54653 +
54654 +/**************************************************************************//**
54655 + @Function FM_PORT_Free
54656 +
54657 + @Description Frees all resources that were assigned to FM module.
54658 +
54659 + Calling this routine invalidates the descriptor.
54660 +
54661 + @Param[in] h_FmPort - FM module descriptor
54662 +
54663 + @Return E_OK on success; Error code otherwise.
54664 + *//***************************************************************************/
54665 +t_Error FM_PORT_Free(t_Handle h_FmPort)
54666 +{
54667 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54668 + t_FmInterModulePortFreeParams fmParams;
54669 +
54670 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54671 +
54672 + if (p_FmPort->pcdEngines)
54673 + RETURN_ERROR(
54674 + MAJOR,
54675 + E_INVALID_STATE,
54676 + ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
54677 +
54678 + if (p_FmPort->enabled)
54679 + {
54680 + if (FM_PORT_Disable(p_FmPort) != E_OK)
54681 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
54682 + }
54683 +
54684 + if (p_FmPort->imEn)
54685 + FmPortImFree(p_FmPort);
54686 +
54687 + FmPortDriverParamFree(p_FmPort);
54688 +
54689 + memset(&fmParams, 0, sizeof(fmParams));
54690 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54691 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54692 + fmParams.deqPipelineDepth =
54693 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54694 +
54695 + FmFreePortParams(p_FmPort->h_Fm, &fmParams);
54696 +
54697 +#if (DPAA_VERSION >= 11)
54698 + if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
54699 + != E_OK)
54700 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
54701 +
54702 + if (p_FmPort->p_ParamsPage)
54703 + FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
54704 +#endif /* (DPAA_VERSION >= 11) */
54705 +
54706 + if (p_FmPort->h_Spinlock)
54707 + XX_FreeSpinlock(p_FmPort->h_Spinlock);
54708 +
54709 + XX_Free(p_FmPort);
54710 +
54711 + return E_OK;
54712 +}
54713 +
54714 +/*************************************************/
54715 +/* API Advanced Init unit functions */
54716 +/*************************************************/
54717 +
54718 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
54719 +{
54720 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54721 +
54722 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54723 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54724 +
54725 + p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
54726 + memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
54727 +
54728 + return E_OK;
54729 +}
54730 +
54731 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
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 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
54739 + p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
54740 + return E_OK;
54741 +}
54742 +
54743 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
54744 +{
54745 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54746 +
54747 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54748 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54749 +
54750 + p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
54751 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
54752 +
54753 + return E_OK;
54754 +}
54755 +
54756 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
54757 +{
54758 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54759 +
54760 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54761 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54762 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54763 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54764 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
54765 +
54766 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
54767 +
54768 + return E_OK;
54769 +}
54770 +
54771 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
54772 +{
54773 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54774 +
54775 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54776 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54777 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54778 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54779 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54780 + ("not available for Rx ports"));
54781 +
54782 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
54783 + (enum fman_port_deq_type)deqType;
54784 +
54785 + return E_OK;
54786 +}
54787 +
54788 +t_Error FM_PORT_ConfigDeqPrefetchOption(
54789 + t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
54790 +{
54791 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54792 +
54793 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54794 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54795 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54796 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54797 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54798 + ("not available for Rx ports"));
54799 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
54800 + (enum fman_port_deq_prefetch)deqPrefetchOption;
54801 +
54802 + return E_OK;
54803 +}
54804 +
54805 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
54806 + t_FmBackupBmPools *p_BackupBmPools)
54807 +{
54808 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54809 +
54810 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54811 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54812 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54813 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54814 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54815 + ("available for Rx ports only"));
54816 +
54817 + p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
54818 + (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
54819 + if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
54820 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
54821 + memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
54822 + sizeof(t_FmBackupBmPools));
54823 +
54824 + return E_OK;
54825 +}
54826 +
54827 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
54828 +{
54829 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54830 +
54831 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54832 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54833 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54834 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54835 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54836 + ("not available for Rx ports"));
54837 +
54838 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
54839 +
54840 + return E_OK;
54841 +}
54842 +
54843 +t_Error FM_PORT_ConfigBufferPrefixContent(
54844 + t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
54845 +{
54846 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54847 +
54848 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54849 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54850 +
54851 + memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54852 + p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
54853 + /* if dataAlign was not initialized by user, we return to driver's default */
54854 + if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
54855 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
54856 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
54857 +
54858 + return E_OK;
54859 +}
54860 +
54861 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
54862 + uint8_t checksumLastBytesIgnore)
54863 +{
54864 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54865 +
54866 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54867 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54868 +
54869 + p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
54870 + checksumLastBytesIgnore;
54871 +
54872 + return E_OK;
54873 +}
54874 +
54875 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
54876 + uint8_t cutBytesFromEnd)
54877 +{
54878 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54879 +
54880 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54881 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54882 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54883 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54884 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54885 + ("available for Rx ports only"));
54886 +
54887 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
54888 +
54889 + return E_OK;
54890 +}
54891 +
54892 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
54893 + t_FmBufPoolDepletion *p_BufPoolDepletion)
54894 +{
54895 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54896 +
54897 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54898 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54899 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54900 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54901 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54902 + ("available for Rx ports only"));
54903 +
54904 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54905 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
54906 + sizeof(t_FmBufPoolDepletion));
54907 +
54908 + return E_OK;
54909 +}
54910 +
54911 +t_Error FM_PORT_ConfigObservedPoolDepletion(
54912 + t_Handle h_FmPort,
54913 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
54914 +{
54915 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54916 +
54917 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54918 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54919 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54920 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54921 + ("available for OP ports only"));
54922 +
54923 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54924 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
54925 + &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
54926 + sizeof(t_FmBufPoolDepletion));
54927 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54928 + &p_FmPortObservedBufPoolDepletion->poolsParams,
54929 + sizeof(t_FmExtPools));
54930 +
54931 + return E_OK;
54932 +}
54933 +
54934 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
54935 +{
54936 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54937 +
54938 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54939 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54940 +
54941 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54942 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54943 + ("available for OP ports only"));
54944 +
54945 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
54946 + sizeof(t_FmExtPools));
54947 +
54948 + return E_OK;
54949 +}
54950 +
54951 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
54952 +{
54953 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54954 +
54955 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54956 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54957 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54958 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54959 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54960 + ("available for Tx ports only"));
54961 +
54962 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
54963 +
54964 + return E_OK;
54965 +}
54966 +
54967 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
54968 +{
54969 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54970 +
54971 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54972 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54973 + p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
54974 +
54975 + return E_OK;
54976 +}
54977 +
54978 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
54979 +{
54980 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54981 +
54982 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54983 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54984 +
54985 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54986 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54987 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54988 + ("Not available for Tx ports"));
54989 +
54990 + p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
54991 +
54992 + return E_OK;
54993 +}
54994 +
54995 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
54996 +{
54997 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54998 +
54999 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55000 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55001 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
55002 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
55003 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55004 + ("Not available for Tx ports"));
55005 +
55006 + p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
55007 +
55008 + return E_OK;
55009 +}
55010 +
55011 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
55012 + fmPortFrameErrSelect_t errs)
55013 +{
55014 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55015 +
55016 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55017 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55018 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55019 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
55020 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
55021 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55022 + ("available for Rx and offline parsing ports only"));
55023 +
55024 + p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
55025 +
55026 + return E_OK;
55027 +}
55028 +
55029 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
55030 +{
55031 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55032 +
55033 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55034 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55035 +
55036 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
55037 + (enum fman_port_dma_swap)swapData;
55038 +
55039 + return E_OK;
55040 +}
55041 +
55042 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
55043 + e_FmDmaCacheOption intContextCacheAttr)
55044 +{
55045 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55046 +
55047 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55048 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55049 +
55050 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
55051 + (bool)(intContextCacheAttr == e_FM_DMA_STASH);
55052 +
55053 + return E_OK;
55054 +}
55055 +
55056 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
55057 + e_FmDmaCacheOption headerCacheAttr)
55058 +{
55059 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55060 +
55061 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55062 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55063 +
55064 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
55065 + (bool)(headerCacheAttr == e_FM_DMA_STASH);
55066 +
55067 + return E_OK;
55068 +}
55069 +
55070 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(
55071 + t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
55072 +{
55073 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55074 +
55075 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55076 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55077 +
55078 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
55079 + (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
55080 +
55081 + return E_OK;
55082 +}
55083 +
55084 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
55085 +{
55086 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55087 +
55088 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55089 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55090 +
55091 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
55092 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
55093 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55094 + ("Not available for Tx ports"));
55095 +
55096 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
55097 +
55098 + return E_OK;
55099 +}
55100 +
55101 +#if (DPAA_VERSION >= 11)
55102 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
55103 +{
55104 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55105 +
55106 + UNUSED(noScatherGather);
55107 + UNUSED(p_FmPort);
55108 +
55109 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55110 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55111 +
55112 + p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather;
55113 +
55114 + return E_OK;
55115 +}
55116 +#endif /* (DPAA_VERSION >= 11) */
55117 +
55118 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
55119 + bool forwardReuse)
55120 +{
55121 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55122 +
55123 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55124 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55125 +
55126 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55127 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55128 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55129 + ("available for Rx ports only"));
55130 +
55131 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
55132 +
55133 + return E_OK;
55134 +}
55135 +
55136 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
55137 +{
55138 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55139 +
55140 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55141 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55142 +
55143 + p_FmPort->maxFrameLength = length;
55144 +
55145 + return E_OK;
55146 +}
55147 +
55148 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
55149 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
55150 +{
55151 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55152 +
55153 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55154 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55155 +
55156 + p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
55157 +
55158 + return E_OK;
55159 +}
55160 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
55161 +
55162 +/****************************************************/
55163 +/* Hidden-DEBUG Only API */
55164 +/****************************************************/
55165 +
55166 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
55167 + uint32_t minFillLevel)
55168 +{
55169 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55170 +
55171 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55172 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55173 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
55174 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
55175 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55176 + ("available for Tx ports only"));
55177 +
55178 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
55179 +
55180 + return E_OK;
55181 +}
55182 +
55183 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
55184 + uint8_t deqPipelineDepth)
55185 +{
55186 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55187 +
55188 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55189 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55190 +
55191 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55192 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
55193 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55194 + ("Not available for Rx ports"));
55195 +
55196 + if (p_FmPort->imEn)
55197 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55198 + ("Not available for IM ports!"));
55199 +
55200 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
55201 + deqPipelineDepth;
55202 +
55203 + return E_OK;
55204 +}
55205 +
55206 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
55207 + uint32_t fifoLowComfLevel)
55208 +{
55209 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55210 +
55211 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55212 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55213 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
55214 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
55215 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55216 + ("available for Tx ports only"));
55217 +
55218 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
55219 + fifoLowComfLevel;
55220 +
55221 + return E_OK;
55222 +}
55223 +
55224 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
55225 +{
55226 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55227 +
55228 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55229 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55230 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55231 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55232 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55233 + ("available for Rx ports only"));
55234 +
55235 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
55236 +
55237 + return E_OK;
55238 +}
55239 +
55240 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
55241 + uint32_t priElevationLevel)
55242 +{
55243 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55244 +
55245 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55246 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55247 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55248 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55249 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55250 + ("available for Rx ports only"));
55251 +
55252 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
55253 +
55254 + return E_OK;
55255 +}
55256 +/****************************************************/
55257 +/* API Run-time Control unit functions */
55258 +/****************************************************/
55259 +
55260 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
55261 + t_FmPortRsrc *p_NumOfOpenDmas)
55262 +{
55263 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55264 + t_Error err;
55265 +
55266 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55267 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55268 +
55269 + if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
55270 + RETURN_ERROR( MAJOR, E_INVALID_VALUE,
55271 + ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
55272 + if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
55273 + RETURN_ERROR(
55274 + MAJOR,
55275 + E_INVALID_VALUE,
55276 + ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
55277 + err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55278 + (uint8_t*)&p_NumOfOpenDmas->num,
55279 + (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
55280 + if (err)
55281 + RETURN_ERROR(MAJOR, err, NO_MSG);
55282 +
55283 + memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
55284 +
55285 + return E_OK;
55286 +}
55287 +
55288 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
55289 +{
55290 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55291 + t_Error err;
55292 +
55293 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55294 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55295 +
55296 + /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */
55297 + ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
55298 +
55299 + if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
55300 + RETURN_ERROR(
55301 + MAJOR, E_INVALID_VALUE,
55302 + ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
55303 + if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
55304 + RETURN_ERROR(
55305 + MAJOR,
55306 + E_INVALID_VALUE,
55307 + ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
55308 +
55309 + err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55310 + (uint8_t*)&p_NumOfTasks->num,
55311 + (uint8_t*)&p_NumOfTasks->extra, FALSE);
55312 + if (err)
55313 + RETURN_ERROR(MAJOR, err, NO_MSG);
55314 +
55315 + /* update driver's struct */
55316 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
55317 + return E_OK;
55318 +}
55319 +
55320 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
55321 +{
55322 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55323 + t_Error err;
55324 +
55325 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55326 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55327 +
55328 + if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
55329 + RETURN_ERROR(
55330 + MAJOR,
55331 + E_INVALID_VALUE,
55332 + ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
55333 + if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
55334 + RETURN_ERROR(
55335 + MAJOR, E_INVALID_VALUE,
55336 + ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
55337 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55338 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55339 + {
55340 + /* extra FIFO size (allowed only to Rx ports) */
55341 + if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
55342 + RETURN_ERROR(
55343 + MAJOR,
55344 + E_INVALID_VALUE,
55345 + ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
55346 + }
55347 + else
55348 + if (p_SizeOfFifo->extra)
55349 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
55350 + (" No SizeOfFifo-extra for non Rx ports"));
55351 +
55352 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
55353 +
55354 + /* we do not change user's parameter */
55355 + err = VerifySizeOfFifo(p_FmPort);
55356 + if (err)
55357 + RETURN_ERROR(MAJOR, err, NO_MSG);
55358 +
55359 + err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55360 + &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
55361 + if (err)
55362 + RETURN_ERROR(MAJOR, err, NO_MSG);
55363 +
55364 + return E_OK;
55365 +}
55366 +
55367 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
55368 +{
55369 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55370 +
55371 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55372 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55373 + 0);
55374 +
55375 + return p_FmPort->bufferOffsets.dataOffset;
55376 +}
55377 +
55378 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
55379 +{
55380 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55381 +
55382 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55383 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55384 + NULL);
55385 +
55386 + if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
55387 + return NULL;
55388 +
55389 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
55390 +}
55391 +
55392 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
55393 +{
55394 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55395 +
55396 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55397 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55398 + NULL);
55399 +
55400 + if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
55401 + return NULL;
55402 +
55403 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
55404 +}
55405 +
55406 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
55407 +{
55408 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55409 +
55410 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55411 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55412 + NULL);
55413 +
55414 + if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
55415 + return NULL;
55416 +
55417 + return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
55418 +}
55419 +
55420 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
55421 +{
55422 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55423 +
55424 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55425 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55426 + NULL);
55427 +
55428 + if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
55429 + return NULL;
55430 +
55431 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
55432 +}
55433 +
55434 +t_Error FM_PORT_Disable(t_Handle h_FmPort)
55435 +{
55436 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55437 + int err;
55438 +
55439 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55440 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55441 +
55442 + if (p_FmPort->imEn)
55443 + FmPortImDisable(p_FmPort);
55444 +
55445 + err = fman_port_disable(&p_FmPort->port);
55446 + if (err == -EBUSY)
55447 + {
55448 + DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
55449 + p_FmPort->name));
55450 + }
55451 + else
55452 + if (err != 0)
55453 + {
55454 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
55455 + }
55456 +
55457 + p_FmPort->enabled = FALSE;
55458 +
55459 + return E_OK;
55460 +}
55461 +
55462 +t_Error FM_PORT_Enable(t_Handle h_FmPort)
55463 +{
55464 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55465 + int err;
55466 +
55467 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55468 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55469 +
55470 + /* Used by FM_PORT_Free routine as indication
55471 + if to disable port. Thus set it to TRUE prior
55472 + to enabling itself. This way if part of enable
55473 + process fails there will be still things
55474 + to disable during Free. For example, if BMI
55475 + enable succeeded but QMI failed, still BMI
55476 + needs to be disabled by Free. */
55477 + p_FmPort->enabled = TRUE;
55478 +
55479 + if (p_FmPort->imEn)
55480 + FmPortImEnable(p_FmPort);
55481 +
55482 + err = fman_port_enable(&p_FmPort->port);
55483 + if (err != 0)
55484 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
55485 +
55486 + return E_OK;
55487 +}
55488 +
55489 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
55490 +{
55491 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55492 + uint8_t factor, countUnitBit;
55493 + uint16_t baseGran;
55494 + struct fman_port_rate_limiter params;
55495 + int err;
55496 +
55497 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55498 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55499 +
55500 + switch (p_FmPort->portType)
55501 + {
55502 + case (e_FM_PORT_TYPE_TX_10G):
55503 + case (e_FM_PORT_TYPE_TX):
55504 + baseGran = BMI_RATE_LIMIT_GRAN_TX;
55505 + break;
55506 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55507 + baseGran = BMI_RATE_LIMIT_GRAN_OP;
55508 + break;
55509 + default:
55510 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55511 + ("available for Tx and Offline parsing ports only"));
55512 + }
55513 +
55514 + countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
55515 + /* normally, we use 1 usec as the reference count */
55516 + factor = 1;
55517 + /* if ratelimit is too small for a 1usec factor, multiply the factor */
55518 + while (p_RateLimit->rateLimit < baseGran / factor)
55519 + {
55520 + if (countUnitBit == 31)
55521 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
55522 +
55523 + countUnitBit++;
55524 + factor <<= 1;
55525 + }
55526 + /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
55527 + if (p_RateLimit->rateLimit
55528 + > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
55529 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
55530 +
55531 + if (!p_RateLimit->maxBurstSize
55532 + || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
55533 + RETURN_ERROR(
55534 + MAJOR,
55535 + E_INVALID_VALUE,
55536 + ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
55537 +
55538 + params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
55539 + params.high_burst_size_gran = FALSE;
55540 + params.burst_size = p_RateLimit->maxBurstSize;
55541 + params.rate = p_RateLimit->rateLimit;
55542 + params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
55543 +
55544 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55545 + {
55546 +#ifndef FM_NO_ADVANCED_RATE_LIMITER
55547 +
55548 + if ((p_FmPort->fmRevInfo.majorRev == 4)
55549 + || (p_FmPort->fmRevInfo.majorRev >= 6))
55550 + {
55551 + params.high_burst_size_gran = TRUE;
55552 + }
55553 + else
55554 +#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
55555 + {
55556 + if (p_RateLimit->rateLimitDivider
55557 + != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
55558 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
55559 + ("FM_PORT_ConfigDualRateLimitScaleDown"));
55560 +
55561 + if (p_RateLimit->maxBurstSize % 1000)
55562 + {
55563 + p_RateLimit->maxBurstSize =
55564 + (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
55565 + DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
55566 + }
55567 + else
55568 + p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
55569 + / 1000);
55570 + }
55571 + params.rate_factor =
55572 + (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
55573 + params.burst_size = p_RateLimit->maxBurstSize;
55574 + }
55575 +
55576 + err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
55577 + if (err != 0)
55578 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55579 +
55580 + return E_OK;
55581 +}
55582 +
55583 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
55584 +{
55585 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55586 + int err;
55587 +
55588 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55589 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55590 +
55591 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55592 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
55593 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55594 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55595 + ("available for Tx and Offline parsing ports only"));
55596 +
55597 + err = fman_port_delete_rate_limiter(&p_FmPort->port);
55598 + if (err != 0)
55599 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55600 + return E_OK;
55601 +}
55602 +
55603 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
55604 + uint8_t wq)
55605 +{
55606 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55607 + uint32_t tmpReg;
55608 + uint32_t wqTmpReg;
55609 +
55610 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55611 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55612 +
55613 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
55614 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
55615 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55616 + ("PFC mapping is available for Tx ports only"));
55617 +
55618 + if (prio > 7)
55619 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55620 + ("PFC priority (%d) is out of range (0-7)", prio));
55621 + if (wq > 7)
55622 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55623 + ("WQ (%d) is out of range (0-7)", wq));
55624 +
55625 + tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
55626 + tmpReg &= ~(0xf << ((7 - prio) * 4));
55627 + wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
55628 + tmpReg |= wqTmpReg;
55629 +
55630 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
55631 + tmpReg);
55632 +
55633 + return E_OK;
55634 +}
55635 +
55636 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
55637 +{
55638 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55639 +
55640 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55641 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55642 +
55643 + fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
55644 +
55645 + return E_OK;
55646 +}
55647 +
55648 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
55649 +{
55650 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55651 + int err;
55652 +
55653 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55654 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55655 +
55656 + err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
55657 + if (err != 0)
55658 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
55659 + return E_OK;
55660 +}
55661 +
55662 +t_Error FM_PORT_SetPerformanceCountersParams(
55663 + t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
55664 +{
55665 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55666 + struct fman_port_perf_cnt_params params;
55667 + int err;
55668 +
55669 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55670 +
55671 + /* check parameters */
55672 + if (!p_FmPortPerformanceCnt->taskCompVal
55673 + || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
55674 + RETURN_ERROR(
55675 + MAJOR,
55676 + E_INVALID_VALUE,
55677 + ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
55678 + if (!p_FmPortPerformanceCnt->dmaCompVal
55679 + || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
55680 + RETURN_ERROR(
55681 + MAJOR,
55682 + E_INVALID_VALUE,
55683 + ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
55684 + if (!p_FmPortPerformanceCnt->fifoCompVal
55685 + || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
55686 + RETURN_ERROR(
55687 + MAJOR,
55688 + E_INVALID_VALUE,
55689 + ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
55690 + if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
55691 + RETURN_ERROR(
55692 + MAJOR,
55693 + E_INVALID_VALUE,
55694 + ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
55695 +
55696 + switch (p_FmPort->portType)
55697 + {
55698 + case (e_FM_PORT_TYPE_RX_10G):
55699 + case (e_FM_PORT_TYPE_RX):
55700 + if (!p_FmPortPerformanceCnt->queueCompVal
55701 + || (p_FmPortPerformanceCnt->queueCompVal
55702 + > MAX_PERFORMANCE_RX_QUEUE_COMP))
55703 + RETURN_ERROR(
55704 + MAJOR,
55705 + E_INVALID_VALUE,
55706 + ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
55707 + break;
55708 + case (e_FM_PORT_TYPE_TX_10G):
55709 + case (e_FM_PORT_TYPE_TX):
55710 + if (!p_FmPortPerformanceCnt->queueCompVal
55711 + || (p_FmPortPerformanceCnt->queueCompVal
55712 + > MAX_PERFORMANCE_TX_QUEUE_COMP))
55713 + RETURN_ERROR(
55714 + MAJOR,
55715 + E_INVALID_VALUE,
55716 + ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
55717 + break;
55718 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55719 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
55720 + if (p_FmPortPerformanceCnt->queueCompVal)
55721 + RETURN_ERROR(
55722 + MAJOR,
55723 + E_INVALID_VALUE,
55724 + ("performanceCnt.queueCompVal is not relevant for H/O ports."));
55725 + break;
55726 + default:
55727 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55728 + }
55729 +
55730 + params.task_val = p_FmPortPerformanceCnt->taskCompVal;
55731 + params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
55732 + params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
55733 + params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
55734 +
55735 + err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
55736 + if (err != 0)
55737 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
55738 +
55739 + return E_OK;
55740 +}
55741 +
55742 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
55743 +{
55744 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55745 + t_FmPortPerformanceCnt currParams, savedParams;
55746 + t_Error err;
55747 + bool underTest, failed = FALSE;
55748 +
55749 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55750 +
55751 + XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
55752 + p_FmPort->portType, p_FmPort->portId);
55753 +
55754 + currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
55755 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55756 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55757 + currParams.queueCompVal = 0;
55758 + else
55759 + currParams.queueCompVal = 1;
55760 + currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
55761 + currParams.fifoCompVal = p_FmPort->fifoBufs.num;
55762 +
55763 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55764 + ClearPerfCnts(p_FmPort);
55765 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55766 + != E_OK)
55767 + RETURN_ERROR(MAJOR, err, NO_MSG);
55768 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55769 + XX_UDelay(1000000);
55770 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55771 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55772 + {
55773 + XX_Print(
55774 + "Max num of defined port tasks (%d) utilized - Please enlarge\n",
55775 + p_FmPort->tasks.num);
55776 + failed = TRUE;
55777 + }
55778 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55779 + {
55780 + XX_Print(
55781 + "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
55782 + p_FmPort->openDmas.num);
55783 + failed = TRUE;
55784 + }
55785 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55786 + {
55787 + XX_Print(
55788 + "Max size of defined port fifo (%d) utilized - Please enlarge\n",
55789 + p_FmPort->fifoBufs.num);
55790 + failed = TRUE;
55791 + }
55792 + if (failed)
55793 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
55794 +
55795 + memset(&savedParams, 0, sizeof(savedParams));
55796 + while (TRUE)
55797 + {
55798 + underTest = FALSE;
55799 + if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
55800 + {
55801 + currParams.taskCompVal--;
55802 + underTest = TRUE;
55803 + }
55804 + if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
55805 + {
55806 + currParams.dmaCompVal--;
55807 + underTest = TRUE;
55808 + }
55809 + if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
55810 + && !savedParams.fifoCompVal)
55811 + {
55812 + currParams.fifoCompVal -= BMI_FIFO_UNITS;
55813 + underTest = TRUE;
55814 + }
55815 + if (!underTest)
55816 + break;
55817 +
55818 + ClearPerfCnts(p_FmPort);
55819 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55820 + != E_OK)
55821 + RETURN_ERROR(MAJOR, err, NO_MSG);
55822 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55823 + XX_UDelay(1000000);
55824 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55825 +
55826 + if (!savedParams.taskCompVal
55827 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55828 + savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
55829 + if (!savedParams.dmaCompVal
55830 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55831 + savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
55832 + if (!savedParams.fifoCompVal
55833 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55834 + savedParams.fifoCompVal = currParams.fifoCompVal
55835 + + (2 * BMI_FIFO_UNITS);
55836 + }
55837 +
55838 + XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
55839 + savedParams.taskCompVal, savedParams.dmaCompVal,
55840 + savedParams.fifoCompVal);
55841 + return E_OK;
55842 +}
55843 +
55844 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
55845 +{
55846 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55847 + int err;
55848 +
55849 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55850 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55851 +
55852 + err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
55853 + if (err != 0)
55854 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
55855 + return E_OK;
55856 +}
55857 +
55858 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
55859 +{
55860 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55861 + volatile uint32_t *p_ErrDiscard = NULL;
55862 + int err;
55863 +
55864 + UNUSED(p_ErrDiscard);
55865 + err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
55866 + if (err != 0)
55867 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
55868 +
55869 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
55870 + if (p_FmPort->fmRevInfo.majorRev >= 6)
55871 + {
55872 + t_FmPcdCtrlParamsPage *p_ParamsPage;
55873 +
55874 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
55875 + (void**)&p_ParamsPage);
55876 + ASSERT_COND(p_ParamsPage);
55877 + switch (p_FmPort->portType)
55878 + {
55879 + case (e_FM_PORT_TYPE_RX_10G):
55880 + case (e_FM_PORT_TYPE_RX):
55881 + p_ErrDiscard =
55882 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
55883 + break;
55884 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55885 + p_ErrDiscard =
55886 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
55887 + break;
55888 + default:
55889 + RETURN_ERROR(
55890 + MAJOR, E_INVALID_OPERATION,
55891 + ("available for Rx and offline parsing ports only"));
55892 + }
55893 + WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
55894 + GET_UINT32(*p_ErrDiscard) | errs);
55895 + }
55896 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
55897 +
55898 + return E_OK;
55899 +}
55900 +
55901 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
55902 + bool enable)
55903 +{
55904 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55905 + int err;
55906 +
55907 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55908 + SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
55909 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55910 +
55911 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55912 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55913 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55914 + ("available for Rx ports only"));
55915 +
55916 + err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
55917 + if (err != 0)
55918 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
55919 + return E_OK;
55920 +}
55921 +
55922 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
55923 +{
55924 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55925 +
55926 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55927 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
55928 + p_BmiStats->cntCycle =
55929 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55930 + /* fmbm_rccn */
55931 + p_BmiStats->cntTaskUtil =
55932 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55933 + /* fmbm_rtuc */
55934 + p_BmiStats->cntQueueUtil =
55935 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55936 + /* fmbm_rrquc */
55937 + p_BmiStats->cntDmaUtil =
55938 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55939 + /* fmbm_rduc */
55940 + p_BmiStats->cntFifoUtil =
55941 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55942 + /* fmbm_rfuc */
55943 + p_BmiStats->cntRxPauseActivation =
55944 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
55945 + /* fmbm_rpac */
55946 + p_BmiStats->cntFrame =
55947 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55948 + /* fmbm_rfrc */
55949 + p_BmiStats->cntDiscardFrame =
55950 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55951 + /* fmbm_rfdc */
55952 + p_BmiStats->cntDeallocBuf =
55953 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55954 + /* fmbm_rbdc */
55955 + p_BmiStats->cntRxBadFrame =
55956 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
55957 + /* fmbm_rfbc */
55958 + p_BmiStats->cntRxLargeFrame =
55959 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
55960 + /* fmbm_rlfc */
55961 + p_BmiStats->cntRxFilterFrame =
55962 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
55963 + /* fmbm_rffc */
55964 + p_BmiStats->cntRxListDmaErr =
55965 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
55966 + /* fmbm_rfldec */
55967 + p_BmiStats->cntRxOutOfBuffersDiscard =
55968 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
55969 + /* fmbm_rodc */
55970 + p_BmiStats->cntWredDiscard = 0;
55971 + p_BmiStats->cntLengthErr = 0;
55972 + p_BmiStats->cntUnsupportedFormat = 0;
55973 + }
55974 + else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
55975 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
55976 + p_BmiStats->cntCycle =
55977 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55978 + /* fmbm_tccn */
55979 + p_BmiStats->cntTaskUtil =
55980 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55981 + /* fmbm_ttuc */
55982 + p_BmiStats->cntQueueUtil =
55983 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55984 + /* fmbm_ttcquc */
55985 + p_BmiStats->cntDmaUtil =
55986 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55987 + /* fmbm_tduc */
55988 + p_BmiStats->cntFifoUtil =
55989 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55990 + /* fmbm_tfuc */
55991 + p_BmiStats->cntRxPauseActivation = 0;
55992 + p_BmiStats->cntFrame =
55993 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55994 + /* fmbm_tfrc */
55995 + p_BmiStats->cntDiscardFrame =
55996 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55997 + /* fmbm_tfdc */
55998 + p_BmiStats->cntDeallocBuf =
55999 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
56000 + /* fmbm_tbdc */
56001 + p_BmiStats->cntRxBadFrame = 0;
56002 + p_BmiStats->cntRxLargeFrame = 0;
56003 + p_BmiStats->cntRxFilterFrame = 0;
56004 + p_BmiStats->cntRxListDmaErr = 0;
56005 + p_BmiStats->cntRxOutOfBuffersDiscard = 0;
56006 + p_BmiStats->cntWredDiscard = 0;
56007 + p_BmiStats->cntLengthErr =
56008 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
56009 + /* fmbm_tfledc */
56010 + p_BmiStats->cntUnsupportedFormat =
56011 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
56012 + /* fmbm_tfufdc */
56013 + }
56014 + else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
56015 + p_BmiStats->cntCycle =
56016 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
56017 + /* fmbm_occn */
56018 + p_BmiStats->cntTaskUtil =
56019 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
56020 + /* fmbm_otuc */
56021 + p_BmiStats->cntQueueUtil = 0;
56022 + p_BmiStats->cntDmaUtil =
56023 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
56024 + /* fmbm_oduc */
56025 + p_BmiStats->cntFifoUtil =
56026 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
56027 + /* fmbm_ofuc*/
56028 + p_BmiStats->cntRxPauseActivation = 0;
56029 + p_BmiStats->cntFrame =
56030 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
56031 + /* fmbm_ofrc */
56032 + p_BmiStats->cntDiscardFrame =
56033 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
56034 + /* fmbm_ofdc */
56035 + p_BmiStats->cntDeallocBuf =
56036 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
56037 + /* fmbm_obdc*/
56038 + p_BmiStats->cntRxBadFrame = 0;
56039 + p_BmiStats->cntRxLargeFrame = 0;
56040 + p_BmiStats->cntRxFilterFrame =
56041 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
56042 + /* fmbm_offc */
56043 + p_BmiStats->cntRxListDmaErr =
56044 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
56045 + /* fmbm_ofldec */
56046 + p_BmiStats->cntRxOutOfBuffersDiscard =
56047 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
56048 + /* fmbm_rodc */
56049 + p_BmiStats->cntWredDiscard =
56050 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
56051 + /* fmbm_ofwdc */
56052 + p_BmiStats->cntLengthErr =
56053 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
56054 + /* fmbm_ofledc */
56055 + p_BmiStats->cntUnsupportedFormat =
56056 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
56057 + /* fmbm_ofufdc */
56058 + }
56059 + return E_OK;
56060 +}
56061 +
56062 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
56063 +{
56064 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56065 + bool bmiCounter = FALSE;
56066 + enum fman_port_stats_counters statsType;
56067 + enum fman_port_perf_counters perfType;
56068 + enum fman_port_qmi_counters queueType;
56069 + bool isStats;
56070 + t_Error errCode;
56071 +
56072 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
56073 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56074 +
56075 + switch (counter)
56076 + {
56077 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56078 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56079 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56080 + /* check that counter is available for the port type */
56081 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
56082 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56083 + {
56084 + REPORT_ERROR(MINOR, E_INVALID_STATE,
56085 + ("Requested counter is not available for Rx ports"));
56086 + return 0;
56087 + }
56088 + bmiCounter = FALSE;
56089 + break;
56090 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56091 + bmiCounter = FALSE;
56092 + break;
56093 + default: /* BMI counters (or error - will be checked in BMI routine )*/
56094 + bmiCounter = TRUE;
56095 + break;
56096 + }
56097 +
56098 + if (bmiCounter)
56099 + {
56100 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
56101 + &perfType, &isStats);
56102 + if (errCode != E_OK)
56103 + {
56104 + REPORT_ERROR(MINOR, errCode, NO_MSG);
56105 + return 0;
56106 + }
56107 + if (isStats)
56108 + return fman_port_get_stats_counter(&p_FmPort->port, statsType);
56109 + else
56110 + return fman_port_get_perf_counter(&p_FmPort->port, perfType);
56111 + }
56112 + else /* QMI counter */
56113 + {
56114 + /* check that counters are enabled */
56115 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
56116 + & QMI_PORT_CFG_EN_COUNTERS))
56117 +
56118 + {
56119 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
56120 + return 0;
56121 + }
56122 +
56123 + /* Set counter */
56124 + switch (counter)
56125 + {
56126 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56127 + queueType = E_FMAN_PORT_ENQ_TOTAL;
56128 + break;
56129 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56130 + queueType = E_FMAN_PORT_DEQ_TOTAL;
56131 + break;
56132 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56133 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
56134 + break;
56135 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56136 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
56137 + break;
56138 + default:
56139 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
56140 + return 0;
56141 + }
56142 +
56143 + return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
56144 + }
56145 +
56146 + return 0;
56147 +}
56148 +
56149 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
56150 + uint32_t value)
56151 +{
56152 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56153 + bool bmiCounter = FALSE;
56154 + enum fman_port_stats_counters statsType;
56155 + enum fman_port_perf_counters perfType;
56156 + enum fman_port_qmi_counters queueType;
56157 + bool isStats;
56158 + t_Error errCode;
56159 +
56160 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56161 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56162 +
56163 + switch (counter)
56164 + {
56165 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56166 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56167 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56168 + /* check that counter is available for the port type */
56169 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
56170 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56171 + RETURN_ERROR(
56172 + MINOR, E_INVALID_STATE,
56173 + ("Requested counter is not available for Rx ports"));
56174 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56175 + bmiCounter = FALSE;
56176 + break;
56177 + default: /* BMI counters (or error - will be checked in BMI routine )*/
56178 + bmiCounter = TRUE;
56179 + break;
56180 + }
56181 +
56182 + if (bmiCounter)
56183 + {
56184 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
56185 + &perfType, &isStats);
56186 + if (errCode != E_OK)
56187 + {
56188 + RETURN_ERROR(MINOR, errCode, NO_MSG);
56189 + }
56190 + if (isStats)
56191 + fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
56192 + else
56193 + fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
56194 + }
56195 + else /* QMI counter */
56196 + {
56197 + /* check that counters are enabled */
56198 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
56199 + & QMI_PORT_CFG_EN_COUNTERS))
56200 + {
56201 + RETURN_ERROR(MINOR, E_INVALID_STATE,
56202 + ("Requested counter was not enabled"));
56203 + }
56204 +
56205 + /* Set counter */
56206 + switch (counter)
56207 + {
56208 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56209 + queueType = E_FMAN_PORT_ENQ_TOTAL;
56210 + break;
56211 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56212 + queueType = E_FMAN_PORT_DEQ_TOTAL;
56213 + break;
56214 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56215 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
56216 + break;
56217 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56218 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
56219 + break;
56220 + default:
56221 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56222 + ("Requested counter is not available"));
56223 + }
56224 +
56225 + fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
56226 + }
56227 +
56228 + return E_OK;
56229 +}
56230 +
56231 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
56232 +{
56233 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56234 +
56235 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
56236 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56237 +
56238 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
56239 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56240 + {
56241 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
56242 + return 0;
56243 + }
56244 + return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
56245 +}
56246 +
56247 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
56248 + uint32_t value)
56249 +{
56250 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
56251 +
56252 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56253 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56254 +
56255 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
56256 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56257 + RETURN_ERROR( MINOR, E_INVALID_STATE,
56258 + ("Requested counter is not available for non-Rx ports"));
56259 +
56260 + fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
56261 + return E_OK;
56262 +}
56263 +bool FM_PORT_IsStalled(t_Handle h_FmPort)
56264 +{
56265 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56266 + t_Error err;
56267 + bool isStalled;
56268 +
56269 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
56270 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
56271 + FALSE);
56272 +
56273 + err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
56274 + if (err != E_OK)
56275 + {
56276 + REPORT_ERROR(MAJOR, err, NO_MSG);
56277 + return TRUE;
56278 + }
56279 + return isStalled;
56280 +}
56281 +
56282 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
56283 +{
56284 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56285 +
56286 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56287 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56288 +
56289 + return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
56290 +}
56291 +
56292 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
56293 +{
56294 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56295 + int err;
56296 +
56297 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56298 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56299 +
56300 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56301 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56302 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56303 + ("available for Rx ports only"));
56304 +
56305 + if (l4Checksum)
56306 + err = fman_port_modify_rx_fd_bits(
56307 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
56308 + TRUE);
56309 + else
56310 + err = fman_port_modify_rx_fd_bits(
56311 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
56312 + FALSE);
56313 + if (err != 0)
56314 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
56315 +
56316 + return E_OK;
56317 +}
56318 +
56319 +/*****************************************************************************/
56320 +/* API Run-time PCD Control unit functions */
56321 +/*****************************************************************************/
56322 +
56323 +#if (DPAA_VERSION >= 11)
56324 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
56325 +{
56326 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56327 + t_Error err = E_OK;
56328 + volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
56329 + uint32_t tmpReg = 0, tmp = 0;
56330 + uint16_t hwStoragePrflId;
56331 +
56332 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56333 + SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
56334 + /*for numOfProfiles = 0 don't call this function*/
56335 + SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
56336 + /*dfltRelativeId should be in the range of numOfProfiles*/
56337 + SANITY_CHECK_RETURN_ERROR(
56338 + p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
56339 + E_INVALID_VALUE);
56340 + /*p_FmPort should be from Rx type or OP*/
56341 + SANITY_CHECK_RETURN_ERROR(
56342 + ((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)),
56343 + E_INVALID_VALUE);
56344 + /*port should be disabled*/
56345 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
56346 + /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
56347 + SANITY_CHECK_RETURN_ERROR(
56348 + ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
56349 + E_INVALID_VALUE);
56350 + /*should be called before SetPCD - this port should be without PCD*/
56351 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
56352 +
56353 + /*alloc window of VSPs for this port*/
56354 + err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
56355 + p_FmPort->portId, p_VSPParams->numOfProfiles);
56356 + if (err != E_OK)
56357 + RETURN_ERROR(MAJOR, err, NO_MSG);
56358 +
56359 + /*get absolute VSP ID for dfltRelative*/
56360 + err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
56361 + p_FmPort->portId,
56362 + p_VSPParams->dfltRelativeId,
56363 + &hwStoragePrflId);
56364 + if (err != E_OK)
56365 + RETURN_ERROR(MAJOR, err, NO_MSG);
56366 +
56367 + /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
56368 + switch (p_FmPort->portType)
56369 + {
56370 + case (e_FM_PORT_TYPE_RX_10G):
56371 + case (e_FM_PORT_TYPE_RX):
56372 + p_BmiStorageProfileId =
56373 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
56374 + p_BmiVspe =
56375 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
56376 +
56377 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56378 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56379 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56380 +
56381 + tmpReg = GET_UINT32(*p_BmiVspe);
56382 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
56383 +
56384 + p_BmiStorageProfileId =
56385 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
56386 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
56387 + hwStoragePrflId = p_VSPParams->dfltRelativeId;
56388 + break;
56389 +
56390 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56391 + tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
56392 + WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
56393 + tmpReg);
56394 +
56395 + p_BmiStorageProfileId =
56396 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
56397 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
56398 + tmp |= BMI_EBD_EN;
56399 + break;
56400 +
56401 + default:
56402 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56403 + ("available for Rx and offline parsing ports only"));
56404 + }
56405 +
56406 + p_FmPort->vspe = TRUE;
56407 + p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
56408 +
56409 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56410 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56411 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56412 +
56413 + tmpReg = GET_UINT32(*p_BmiVspe);
56414 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
56415 + return E_OK;
56416 +}
56417 +#endif /* (DPAA_VERSION >= 11) */
56418 +
56419 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
56420 +{
56421 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56422 + t_Error err = E_OK;
56423 +
56424 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56425 + ASSERT_COND(p_FmPort->h_FmPcd);
56426 +
56427 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56428 + {
56429 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56430 + return ERROR_CODE(E_BUSY);
56431 + }
56432 +
56433 + if (numOfProfiles)
56434 + {
56435 + err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
56436 + p_FmPort->hardwarePortId, numOfProfiles);
56437 + if (err)
56438 + RETURN_ERROR(MAJOR, err, NO_MSG);
56439 + }
56440 + /* set the port handle within the PCD policer, even if no profiles defined */
56441 + FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
56442 +
56443 + RELEASE_LOCK(p_FmPort->lock);
56444 +
56445 + return E_OK;
56446 +}
56447 +
56448 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
56449 +{
56450 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56451 + t_Error err = E_OK;
56452 +
56453 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56454 + {
56455 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56456 + return ERROR_CODE(E_BUSY);
56457 + }
56458 +
56459 + err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
56460 +
56461 + RELEASE_LOCK(p_FmPort->lock);
56462 +
56463 + if (err)
56464 + RETURN_ERROR(MAJOR, err, NO_MSG);
56465 +
56466 + return E_OK;
56467 +}
56468 +
56469 +t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
56470 + t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
56471 +{
56472 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56473 + volatile uint32_t *p_BmiHpnia = NULL;
56474 + uint32_t tmpReg;
56475 + uint8_t relativeSchemeId;
56476 + uint8_t physicalSchemeId;
56477 +
56478 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56479 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56480 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
56481 + E_INVALID_STATE);
56482 +
56483 + tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
56484 + switch (p_FmPort->portType)
56485 + {
56486 + case (e_FM_PORT_TYPE_RX_10G):
56487 + case (e_FM_PORT_TYPE_RX):
56488 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56489 + break;
56490 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56491 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56492 + break;
56493 + default:
56494 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56495 + ("available for Rx and offline parsing ports only"));
56496 + }
56497 +
56498 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56499 + {
56500 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56501 + return ERROR_CODE(E_BUSY);
56502 + }
56503 +
56504 + /* if we want to change to direct scheme, we need to check that this scheme is valid */
56505 + if (p_FmPcdKgScheme->direct)
56506 + {
56507 + physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
56508 + /* check that this scheme is bound to this port */
56509 + if (!(p_FmPort->schemesPerPortVector
56510 + & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
56511 + {
56512 + RELEASE_LOCK(p_FmPort->lock);
56513 + RETURN_ERROR(
56514 + MAJOR, E_INVALID_STATE,
56515 + ("called with a scheme that is not bound to this port"));
56516 + }
56517 +
56518 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
56519 + physicalSchemeId);
56520 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
56521 + {
56522 + RELEASE_LOCK(p_FmPort->lock);
56523 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
56524 + ("called with invalid Scheme "));
56525 + }
56526 +
56527 + if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
56528 + {
56529 + RELEASE_LOCK(p_FmPort->lock);
56530 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56531 + ("called with uninitialized Scheme "));
56532 + }
56533 +
56534 + WRITE_UINT32(
56535 + *p_BmiHpnia,
56536 + NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
56537 + }
56538 + else
56539 + /* change to indirect scheme */
56540 + WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
56541 + RELEASE_LOCK(p_FmPort->lock);
56542 +
56543 + return E_OK;
56544 +}
56545 +
56546 +t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
56547 + t_Handle h_Profile)
56548 +{
56549 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56550 + volatile uint32_t *p_BmiNia;
56551 + volatile uint32_t *p_BmiHpnia;
56552 + uint32_t tmpReg;
56553 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
56554 +
56555 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56556 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56557 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
56558 + E_INVALID_STATE);
56559 +
56560 + /* check relevance of this routine - only when policer is used
56561 + directly after BMI or Parser */
56562 + if ((p_FmPort->pcdEngines & FM_PCD_KG)
56563 + || (p_FmPort->pcdEngines & FM_PCD_CC))
56564 + RETURN_ERROR(
56565 + MAJOR,
56566 + E_INVALID_STATE,
56567 + ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
56568 +
56569 + switch (p_FmPort->portType)
56570 + {
56571 + case (e_FM_PORT_TYPE_RX_10G):
56572 + case (e_FM_PORT_TYPE_RX):
56573 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56574 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56575 + tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
56576 + break;
56577 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56578 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56579 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56580 + tmpReg = 0;
56581 + break;
56582 + default:
56583 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56584 + ("available for Rx and offline parsing ports only"));
56585 + }
56586 +
56587 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56588 + {
56589 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56590 + return ERROR_CODE(E_BUSY);
56591 + }
56592 +
56593 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
56594 + {
56595 + RELEASE_LOCK(p_FmPort->lock);
56596 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
56597 + }
56598 +
56599 + tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
56600 +
56601 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
56602 + {
56603 + /* update BMI HPNIA */
56604 + WRITE_UINT32(*p_BmiHpnia, tmpReg);
56605 + }
56606 + else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
56607 + {
56608 + /* rfne may contain FDCS bits, so first we read them. */
56609 + tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
56610 + /* update BMI NIA */
56611 + WRITE_UINT32(*p_BmiNia, tmpReg);
56612 + }RELEASE_LOCK(p_FmPort->lock);
56613 +
56614 + return E_OK;
56615 +}
56616 +
56617 +t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
56618 +{
56619 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56620 + t_Error err = E_OK;
56621 + volatile uint32_t *p_BmiCcBase = NULL;
56622 + volatile uint32_t *p_BmiNia = NULL;
56623 + uint32_t ccTreePhysOffset;
56624 +
56625 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56626 + SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
56627 +
56628 + if (p_FmPort->imEn)
56629 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56630 + ("available for non-independent mode ports only"));
56631 +
56632 + /* get PCD registers pointers */
56633 + switch (p_FmPort->portType)
56634 + {
56635 + case (e_FM_PORT_TYPE_RX_10G):
56636 + case (e_FM_PORT_TYPE_RX):
56637 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56638 + break;
56639 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56640 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56641 + break;
56642 + default:
56643 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56644 + ("available for Rx and offline parsing ports only"));
56645 + }
56646 +
56647 + /* check that current NIA is BMI to BMI */
56648 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
56649 + != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
56650 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56651 + ("may be called only for ports in BMI-to-BMI state."));
56652 +
56653 + if (p_FmPort->pcdEngines & FM_PCD_CC)
56654 + {
56655 + if (p_FmPort->h_IpReassemblyManip)
56656 + {
56657 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56658 + p_FmPort->h_IpReassemblyManip, FALSE);
56659 + if (err != E_OK)
56660 + {
56661 + RETURN_ERROR(MAJOR, err, NO_MSG);
56662 + }
56663 + }
56664 + else
56665 + if (p_FmPort->h_CapwapReassemblyManip)
56666 + {
56667 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56668 + p_FmPort->h_CapwapReassemblyManip,
56669 + FALSE);
56670 + if (err != E_OK)
56671 + {
56672 + RETURN_ERROR(MAJOR, err, NO_MSG);
56673 + }
56674 + }
56675 + switch (p_FmPort->portType)
56676 + {
56677 + case (e_FM_PORT_TYPE_RX_10G):
56678 + case (e_FM_PORT_TYPE_RX):
56679 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
56680 + break;
56681 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56682 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
56683 + break;
56684 + default:
56685 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
56686 + }
56687 +
56688 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56689 + {
56690 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56691 + return ERROR_CODE(E_BUSY);
56692 + }
56693 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
56694 + &ccTreePhysOffset, h_FmPort);
56695 + if (err)
56696 + {
56697 + RELEASE_LOCK(p_FmPort->lock);
56698 + RETURN_ERROR(MAJOR, err, NO_MSG);
56699 + }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
56700 +
56701 + p_FmPort->ccTreeId = h_CcTree;
56702 + RELEASE_LOCK(p_FmPort->lock);
56703 + }
56704 + else
56705 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56706 + ("Coarse Classification not defined for this port."));
56707 +
56708 + return E_OK;
56709 +}
56710 +
56711 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
56712 +{
56713 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56714 + t_Error err = E_OK;
56715 +
56716 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56717 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56718 +
56719 + if (p_FmPort->imEn)
56720 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56721 + ("available for non-independent mode ports only"));
56722 +
56723 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56724 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56725 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56726 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56727 + ("available for Rx and offline parsing ports only"));
56728 +
56729 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56730 + {
56731 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56732 + return ERROR_CODE(E_BUSY);
56733 + }
56734 +
56735 + if (p_FmPort->h_ReassemblyTree)
56736 + p_FmPort->pcdEngines |= FM_PCD_CC;
56737 +
56738 + err = AttachPCD(h_FmPort);
56739 + RELEASE_LOCK(p_FmPort->lock);
56740 +
56741 + return err;
56742 +}
56743 +
56744 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
56745 +{
56746 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56747 + t_Error err = E_OK;
56748 +
56749 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56750 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56751 +
56752 + if (p_FmPort->imEn)
56753 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56754 + ("available for non-independent mode ports only"));
56755 +
56756 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56757 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56758 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56759 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56760 + ("available for Rx and offline parsing ports only"));
56761 +
56762 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56763 + {
56764 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56765 + return ERROR_CODE(E_BUSY);
56766 + }
56767 +
56768 + err = DetachPCD(h_FmPort);
56769 + if (err != E_OK)
56770 + {
56771 + RELEASE_LOCK(p_FmPort->lock);
56772 + RETURN_ERROR(MAJOR, err, NO_MSG);
56773 + }
56774 +
56775 + if (p_FmPort->h_ReassemblyTree)
56776 + p_FmPort->pcdEngines &= ~FM_PCD_CC;
56777 + RELEASE_LOCK(p_FmPort->lock);
56778 +
56779 + return E_OK;
56780 +}
56781 +
56782 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
56783 +{
56784 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56785 + t_Error err = E_OK;
56786 + t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
56787 + t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
56788 + t_FmPortPcdCcParams fmPortPcdCcParams;
56789 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
56790 +
56791 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56792 + SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
56793 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56794 +
56795 + if (p_FmPort->imEn)
56796 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56797 + ("available for non-independent mode ports only"));
56798 +
56799 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56800 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56801 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56802 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56803 + ("available for Rx and offline parsing ports only"));
56804 +
56805 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56806 + {
56807 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56808 + return ERROR_CODE(E_BUSY);
56809 + }
56810 +
56811 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56812 + ASSERT_COND(p_FmPort->h_FmPcd);
56813 +
56814 + if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
56815 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
56816 + ("Tree handle must be given if CC is required"));
56817 +
56818 + memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
56819 + p_PcdParams = &modifiedPcdParams;
56820 + if ((p_PcdParams->h_IpReassemblyManip)
56821 +#if (DPAA_VERSION >= 11)
56822 + || (p_PcdParams->h_CapwapReassemblyManip)
56823 +#endif /* (DPAA_VERSION >= 11) */
56824 + )
56825 + {
56826 + if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56827 + && (p_PcdParams->pcdSupport
56828 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
56829 + && (p_PcdParams->pcdSupport
56830 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
56831 + && (p_PcdParams->pcdSupport
56832 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
56833 + {
56834 + RELEASE_LOCK(p_FmPort->lock);
56835 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56836 + ("pcdSupport must have KG for supporting Reassembly"));
56837 + }
56838 + p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
56839 +#if (DPAA_VERSION >= 11)
56840 + if ((p_PcdParams->h_IpReassemblyManip)
56841 + && (p_PcdParams->h_CapwapReassemblyManip))
56842 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56843 + ("Either IP-R or CAPWAP-R is allowed"));
56844 + if ((p_PcdParams->h_CapwapReassemblyManip)
56845 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56846 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56847 + ("CAPWAP-R is allowed only on offline-port"));
56848 + if (p_PcdParams->h_CapwapReassemblyManip)
56849 + p_FmPort->h_CapwapReassemblyManip =
56850 + p_PcdParams->h_CapwapReassemblyManip;
56851 +#endif /* (DPAA_VERSION >= 11) */
56852 +
56853 + if (!p_PcdParams->p_CcParams)
56854 + {
56855 + if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56856 + || (p_PcdParams->pcdSupport
56857 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
56858 + {
56859 + RELEASE_LOCK(p_FmPort->lock);
56860 + RETURN_ERROR(
56861 + MAJOR,
56862 + E_INVALID_STATE,
56863 + ("PCD initialization structure is not consistent with pcdSupport"));
56864 + }
56865 +
56866 + /* No user-tree, need to build internal tree */
56867 + p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
56868 + sizeof(t_FmPcdCcTreeParams));
56869 + if (!p_FmPcdCcTreeParams)
56870 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
56871 + memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
56872 + p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
56873 + p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
56874 + p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
56875 +
56876 + if (!p_FmPort->h_ReassemblyTree)
56877 + {
56878 + RELEASE_LOCK(p_FmPort->lock);
56879 + XX_Free(p_FmPcdCcTreeParams);
56880 + RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
56881 + ("FM_PCD_CcBuildTree for Reassembly failed"));
56882 + }
56883 + if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56884 + p_PcdParams->pcdSupport =
56885 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
56886 + else
56887 + p_PcdParams->pcdSupport =
56888 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
56889 +
56890 + memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
56891 + fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
56892 + p_PcdParams->p_CcParams = &fmPortPcdCcParams;
56893 + XX_Free(p_FmPcdCcTreeParams);
56894 + }
56895 +
56896 + if (p_FmPort->h_IpReassemblyManip)
56897 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
56898 + p_PcdParams->p_CcParams->h_CcTree,
56899 + p_PcdParams->h_NetEnv,
56900 + p_FmPort->h_IpReassemblyManip, TRUE);
56901 +#if (DPAA_VERSION >= 11)
56902 + else
56903 + if (p_FmPort->h_CapwapReassemblyManip)
56904 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
56905 + p_PcdParams->p_CcParams->h_CcTree,
56906 + p_PcdParams->h_NetEnv,
56907 + p_FmPort->h_CapwapReassemblyManip,
56908 + TRUE);
56909 +#endif /* (DPAA_VERSION >= 11) */
56910 +
56911 + if (err != E_OK)
56912 + {
56913 + if (p_FmPort->h_ReassemblyTree)
56914 + {
56915 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56916 + p_FmPort->h_ReassemblyTree = NULL;
56917 + }RELEASE_LOCK(p_FmPort->lock);
56918 + RETURN_ERROR(MAJOR, err, NO_MSG);
56919 + }
56920 + }
56921 +
56922 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
56923 + {
56924 + if (p_FmPort->h_ReassemblyTree)
56925 + {
56926 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56927 + p_FmPort->h_ReassemblyTree = NULL;
56928 + }RELEASE_LOCK(p_FmPort->lock);
56929 + DBG(TRACE, ("Try LockAll - BUSY"));
56930 + return ERROR_CODE(E_BUSY);
56931 + }
56932 +
56933 + err = SetPcd(h_FmPort, p_PcdParams);
56934 + if (err)
56935 + {
56936 + if (p_FmPort->h_ReassemblyTree)
56937 + {
56938 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56939 + p_FmPort->h_ReassemblyTree = NULL;
56940 + }
56941 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56942 + RELEASE_LOCK(p_FmPort->lock);
56943 + RETURN_ERROR(MAJOR, err, NO_MSG);
56944 + }
56945 +
56946 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
56947 + && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
56948 + {
56949 + err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
56950 + p_FmPort->hardwarePortId, TRUE);
56951 + if (err)
56952 + {
56953 + DeletePcd(p_FmPort);
56954 + if (p_FmPort->h_ReassemblyTree)
56955 + {
56956 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56957 + p_FmPort->h_ReassemblyTree = NULL;
56958 + }
56959 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56960 + RELEASE_LOCK(p_FmPort->lock);
56961 + RETURN_ERROR(MAJOR, err, NO_MSG);
56962 + }
56963 + p_FmPort->includeInPrsStatistics = TRUE;
56964 + }
56965 +
56966 + FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
56967 +
56968 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56969 + {
56970 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
56971 +
56972 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56973 + {
56974 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
56975 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
56976 + (p_FmPort->pcdEngines & FM_PCD_KG))
56977 + {
56978 + int i;
56979 + for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
56980 + /* The following function must be locked */
56981 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
56982 + p_PcdParams->p_KgParams->h_Schemes[i],
56983 + UPDATE_KG_NIA_CC_WA,
56984 + 0);
56985 + }
56986 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
56987 +
56988 +#if (DPAA_VERSION >= 11)
56989 + {
56990 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56991 +
56992 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
56993 + (void**)&p_ParamsPage);
56994 + ASSERT_COND(p_ParamsPage);
56995 + WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
56996 + p_FmPort->savedBmiNia);
56997 + }
56998 +#endif /* (DPAA_VERSION >= 11) */
56999 +
57000 + /* Set post-bmi-fetch nia */
57001 + p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
57002 + p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
57003 + | NIA_ENG_FM_CTL);
57004 +
57005 + /* Set pre-bmi-fetch nia */
57006 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
57007 +#if (DPAA_VERSION >= 11)
57008 + fmPortGetSetCcParams.setCcParams.nia =
57009 + (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
57010 +#else
57011 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
57012 +#endif /* (DPAA_VERSION >= 11) */
57013 + if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
57014 + != E_OK)
57015 + {
57016 + DeletePcd(p_FmPort);
57017 + if (p_FmPort->h_ReassemblyTree)
57018 + {
57019 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57020 + p_FmPort->h_ReassemblyTree = NULL;
57021 + }
57022 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
57023 + RELEASE_LOCK(p_FmPort->lock);
57024 + RETURN_ERROR(MAJOR, err, NO_MSG);
57025 + }
57026 + }
57027 +
57028 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
57029 +
57030 + /* Set pop-to-next-step nia */
57031 +#if (DPAA_VERSION == 10)
57032 + if (p_FmPort->fmRevInfo.majorRev < 6)
57033 + {
57034 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
57035 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
57036 + }
57037 + else
57038 + {
57039 +#endif /* (DPAA_VERSION == 10) */
57040 + fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
57041 +#if (DPAA_VERSION == 10)
57042 + }
57043 +#endif /* (DPAA_VERSION == 10) */
57044 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
57045 + != E_OK)
57046 + {
57047 + DeletePcd(p_FmPort);
57048 + if (p_FmPort->h_ReassemblyTree)
57049 + {
57050 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57051 + p_FmPort->h_ReassemblyTree = NULL;
57052 + }RELEASE_LOCK(p_FmPort->lock);
57053 + RETURN_ERROR(MAJOR, err, NO_MSG);
57054 + }
57055 +
57056 + /* Set post-bmi-prepare-to-enq nia */
57057 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
57058 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
57059 + | NIA_ENG_FM_CTL);
57060 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
57061 + != E_OK)
57062 + {
57063 + DeletePcd(p_FmPort);
57064 + if (p_FmPort->h_ReassemblyTree)
57065 + {
57066 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57067 + p_FmPort->h_ReassemblyTree = NULL;
57068 + }RELEASE_LOCK(p_FmPort->lock);
57069 + RETURN_ERROR(MAJOR, err, NO_MSG);
57070 + }
57071 +
57072 + if ((p_FmPort->h_IpReassemblyManip)
57073 + || (p_FmPort->h_CapwapReassemblyManip))
57074 + {
57075 +#if (DPAA_VERSION == 10)
57076 + if (p_FmPort->fmRevInfo.majorRev < 6)
57077 + {
57078 + /* Overwrite post-bmi-prepare-to-enq nia */
57079 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
57080 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
57081 + fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
57082 + }
57083 + else
57084 + {
57085 +#endif /* (DPAA_VERSION == 10) */
57086 + /* Set the ORR bit (for order-restoration) */
57087 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
57088 + fmPortGetSetCcParams.setCcParams.nia =
57089 + fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
57090 +#if (DPAA_VERSION == 10)
57091 + }
57092 +#endif /* (DPAA_VERSION == 10) */
57093 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
57094 + != E_OK)
57095 + {
57096 + DeletePcd(p_FmPort);
57097 + if (p_FmPort->h_ReassemblyTree)
57098 + {
57099 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57100 + p_FmPort->h_ReassemblyTree = NULL;
57101 + }RELEASE_LOCK(p_FmPort->lock);
57102 + RETURN_ERROR(MAJOR, err, NO_MSG);
57103 + }
57104 + }
57105 + }
57106 + else
57107 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
57108 +
57109 +#if (DPAA_VERSION >= 11)
57110 + {
57111 + t_FmPcdCtrlParamsPage *p_ParamsPage;
57112 +
57113 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
57114 +
57115 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
57116 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
57117 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
57118 + | NIA_ENG_FM_CTL;
57119 + else
57120 + fmPortGetSetCcParams.setCcParams.nia =
57121 + NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
57122 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
57123 + != E_OK)
57124 + {
57125 + DeletePcd(p_FmPort);
57126 + if (p_FmPort->h_ReassemblyTree)
57127 + {
57128 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57129 + p_FmPort->h_ReassemblyTree = NULL;
57130 + }RELEASE_LOCK(p_FmPort->lock);
57131 + RETURN_ERROR(MAJOR, err, NO_MSG);
57132 + }
57133 +
57134 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
57135 + (void**)&p_ParamsPage);
57136 + ASSERT_COND(p_ParamsPage);
57137 +
57138 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
57139 + WRITE_UINT32(
57140 + p_ParamsPage->misc,
57141 + GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
57142 +
57143 + if ((p_FmPort->h_IpReassemblyManip)
57144 + || (p_FmPort->h_CapwapReassemblyManip))
57145 + {
57146 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
57147 + WRITE_UINT32(
57148 + p_ParamsPage->discardMask,
57149 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
57150 + else
57151 + WRITE_UINT32(
57152 + p_ParamsPage->discardMask,
57153 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
57154 + }
57155 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
57156 + if (p_FmPort->vspe)
57157 + WRITE_UINT32(
57158 + p_ParamsPage->misc,
57159 + GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
57160 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
57161 + }
57162 +#endif /* (DPAA_VERSION >= 11) */
57163 +
57164 + err = AttachPCD(h_FmPort);
57165 + if (err)
57166 + {
57167 + DeletePcd(p_FmPort);
57168 + if (p_FmPort->h_ReassemblyTree)
57169 + {
57170 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57171 + p_FmPort->h_ReassemblyTree = NULL;
57172 + }RELEASE_LOCK(p_FmPort->lock);
57173 + RETURN_ERROR(MAJOR, err, NO_MSG);
57174 + }
57175 +
57176 + RELEASE_LOCK(p_FmPort->lock);
57177 +
57178 + return err;
57179 +}
57180 +
57181 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
57182 +{
57183 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57184 + t_Error err = E_OK;
57185 +
57186 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
57187 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57188 +
57189 + if (p_FmPort->imEn)
57190 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
57191 + ("available for non-independant mode ports only"));
57192 +
57193 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57194 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57195 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57196 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
57197 + ("available for Rx and offline parsing ports only"));
57198 +
57199 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57200 + {
57201 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57202 + return ERROR_CODE(E_BUSY);
57203 + }
57204 +
57205 + err = DetachPCD(h_FmPort);
57206 + if (err)
57207 + {
57208 + RELEASE_LOCK(p_FmPort->lock);
57209 + RETURN_ERROR(MAJOR, err, NO_MSG);
57210 + }
57211 +
57212 + FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
57213 +
57214 + /* we do it anyway, instead of checking if included */
57215 + if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
57216 + {
57217 + FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
57218 + p_FmPort->hardwarePortId, FALSE);
57219 + p_FmPort->includeInPrsStatistics = FALSE;
57220 + }
57221 +
57222 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
57223 + {
57224 + RELEASE_LOCK(p_FmPort->lock);
57225 + DBG(TRACE, ("Try LockAll - BUSY"));
57226 + return ERROR_CODE(E_BUSY);
57227 + }
57228 +
57229 + err = DeletePcd(h_FmPort);
57230 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
57231 + if (err)
57232 + {
57233 + RELEASE_LOCK(p_FmPort->lock);
57234 + RETURN_ERROR(MAJOR, err, NO_MSG);
57235 + }
57236 +
57237 + if (p_FmPort->h_ReassemblyTree)
57238 + {
57239 + err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57240 + if (err)
57241 + {
57242 + RELEASE_LOCK(p_FmPort->lock);
57243 + RETURN_ERROR(MAJOR, err, NO_MSG);
57244 + }
57245 + p_FmPort->h_ReassemblyTree = NULL;
57246 + }RELEASE_LOCK(p_FmPort->lock);
57247 +
57248 + return err;
57249 +}
57250 +
57251 +t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
57252 + t_FmPcdPortSchemesParams *p_PortScheme)
57253 +{
57254 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57255 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
57256 + t_Error err = E_OK;
57257 + uint32_t tmpScmVec = 0;
57258 + int i;
57259 +
57260 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57261 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57262 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57263 + E_INVALID_STATE);
57264 +
57265 + schemeBind.netEnvId = p_FmPort->netEnvId;
57266 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
57267 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
57268 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
57269 + for (i = 0; i < schemeBind.numOfSchemes; i++)
57270 + {
57271 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
57272 + p_PortScheme->h_Schemes[i]);
57273 + /* build vector */
57274 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
57275 + }
57276 +
57277 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57278 + {
57279 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57280 + return ERROR_CODE(E_BUSY);
57281 + }
57282 +
57283 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
57284 + if (err == E_OK)
57285 + p_FmPort->schemesPerPortVector |= tmpScmVec;
57286 +
57287 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
57288 + if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
57289 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
57290 + (p_FmPort->fmRevInfo.majorRev < 6))
57291 + {
57292 + for (i=0; i<p_PortScheme->numOfSchemes; i++)
57293 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
57294 + }
57295 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
57296 +
57297 + RELEASE_LOCK(p_FmPort->lock);
57298 +
57299 + return err;
57300 +}
57301 +
57302 +t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
57303 + t_FmPcdPortSchemesParams *p_PortScheme)
57304 +{
57305 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57306 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
57307 + t_Error err = E_OK;
57308 + uint32_t tmpScmVec = 0;
57309 + int i;
57310 +
57311 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57312 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57313 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57314 + E_INVALID_STATE);
57315 +
57316 + schemeBind.netEnvId = p_FmPort->netEnvId;
57317 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
57318 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
57319 + for (i = 0; i < schemeBind.numOfSchemes; i++)
57320 + {
57321 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
57322 + p_PortScheme->h_Schemes[i]);
57323 + /* build vector */
57324 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
57325 + }
57326 +
57327 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57328 + {
57329 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57330 + return ERROR_CODE(E_BUSY);
57331 + }
57332 +
57333 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
57334 + if (err == E_OK)
57335 + p_FmPort->schemesPerPortVector &= ~tmpScmVec;
57336 + RELEASE_LOCK(p_FmPort->lock);
57337 +
57338 + return err;
57339 +}
57340 +
57341 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
57342 + t_FmPortCongestionGrps *p_CongestionGrps)
57343 +{
57344 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57345 + uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
57346 + uint8_t mod, index;
57347 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57348 + int err;
57349 +#if (DPAA_VERSION >= 11)
57350 + int j;
57351 +#endif /* (DPAA_VERSION >= 11) */
57352 +
57353 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57354 +
57355 + /* un-necessary check of the indexes; probably will be needed in the future when there
57356 + will be more CGs available ....
57357 + for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57358 + if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
57359 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
57360 + */
57361 +
57362 +#ifdef FM_NO_OP_OBSERVED_CGS
57363 + if ((p_FmPort->fmRevInfo.majorRev != 4) &&
57364 + (p_FmPort->fmRevInfo.majorRev < 6))
57365 + {
57366 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57367 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57368 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57369 + }
57370 + else
57371 +#endif /* FM_NO_OP_OBSERVED_CGS */
57372 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57373 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57374 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57375 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57376 + ("Available for Rx & OP ports only"));
57377 +
57378 + /* Prepare groups map array */
57379 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57380 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57381 + {
57382 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57383 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57384 + if (p_FmPort->fmRevInfo.majorRev != 4)
57385 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57386 + else
57387 + grpsMap[0] |= (uint32_t)(1 << mod);
57388 + }
57389 +
57390 + memset(&priorityTmpArray, 0,
57391 + FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
57392 +
57393 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57394 + {
57395 +#if (DPAA_VERSION >= 11)
57396 + for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
57397 + if (p_CongestionGrps->pfcPrioritiesEn[i][j])
57398 + priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
57399 + (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
57400 +#endif /* (DPAA_VERSION >= 11) */
57401 + }
57402 +
57403 +#if (DPAA_VERSION >= 11)
57404 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
57405 + {
57406 + err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
57407 + priorityTmpArray[i]);
57408 + if (err)
57409 + return err;
57410 + }
57411 +#endif /* (DPAA_VERSION >= 11) */
57412 +
57413 + err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
57414 + if (err != 0)
57415 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
57416 +
57417 + return E_OK;
57418 +}
57419 +
57420 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
57421 + t_FmPortCongestionGrps *p_CongestionGrps)
57422 +{
57423 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57424 + uint8_t mod, index;
57425 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57426 + int err;
57427 +
57428 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57429 +
57430 + {
57431 +#ifdef FM_NO_OP_OBSERVED_CGS
57432 + t_FmRevisionInfo revInfo;
57433 +
57434 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
57435 + if (revInfo.majorRev != 4)
57436 + {
57437 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57438 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57439 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57440 + }
57441 + else
57442 +#endif /* FM_NO_OP_OBSERVED_CGS */
57443 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57444 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57445 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57446 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57447 + ("Available for Rx & OP ports only"));
57448 + }
57449 +
57450 + /* Prepare groups map array */
57451 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57452 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57453 + {
57454 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57455 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57456 + if (p_FmPort->fmRevInfo.majorRev != 4)
57457 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57458 + else
57459 + grpsMap[0] |= (uint32_t)(1 << mod);
57460 + }
57461 +
57462 +#if (DPAA_VERSION >= 11)
57463 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57464 + {
57465 + t_Error err = FmSetCongestionGroupPFCpriority(
57466 + p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
57467 + 0);
57468 + if (err)
57469 + return err;
57470 + }
57471 +#endif /* (DPAA_VERSION >= 11) */
57472 +
57473 + err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
57474 + if (err != 0)
57475 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
57476 + ("fman_port_remove_congestion_grps"));
57477 + return E_OK;
57478 +}
57479 +
57480 +#if (DPAA_VERSION >= 11)
57481 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
57482 + uint32_t *p_Ipv4OptionsCount)
57483 +{
57484 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57485 +
57486 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57487 + SANITY_CHECK_RETURN_ERROR(
57488 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
57489 + E_INVALID_VALUE);
57490 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
57491 + SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
57492 +
57493 + *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
57494 +
57495 + return E_OK;
57496 +}
57497 +#endif /* (DPAA_VERSION >= 11) */
57498 +
57499 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
57500 + t_FmPortDsarTablesSizes *params)
57501 +{
57502 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57503 + p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
57504 + sizeof(struct t_FmPortDsarTablesSizes));
57505 + memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
57506 + sizeof(struct t_FmPortDsarTablesSizes));
57507 + return E_OK;
57508 +}
57509 +
57510 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
57511 +{
57512 + uint32_t *param_page;
57513 + t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
57514 + t_ArCommonDesc *ArCommonDescPtr;
57515 + uint32_t size = sizeof(t_ArCommonDesc);
57516 + // ARP
57517 + // should put here if (params->max_num_of_arp_entries)?
57518 + size = ROUND_UP(size,4);
57519 + size += sizeof(t_DsarArpDescriptor);
57520 + size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
57521 + size += sizeof(t_DsarArpStatistics);
57522 + //ICMPV4
57523 + size = ROUND_UP(size,4);
57524 + size += sizeof(t_DsarIcmpV4Descriptor);
57525 + size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
57526 + size += sizeof(t_DsarIcmpV4Statistics);
57527 + //ICMPV6
57528 + size = ROUND_UP(size,4);
57529 + size += sizeof(t_DsarIcmpV6Descriptor);
57530 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
57531 + size += sizeof(t_DsarIcmpV6Statistics);
57532 + //ND
57533 + size = ROUND_UP(size,4);
57534 + size += sizeof(t_DsarNdDescriptor);
57535 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
57536 + size += sizeof(t_DsarIcmpV6Statistics);
57537 + //SNMP
57538 + size = ROUND_UP(size,4);
57539 + size += sizeof(t_DsarSnmpDescriptor);
57540 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57541 + * params->maxNumOfSnmpIPV4Entries;
57542 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57543 + * params->maxNumOfSnmpIPV6Entries;
57544 + size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
57545 + size += params->maxNumOfSnmpOidChar;
57546 + size += sizeof(t_DsarIcmpV6Statistics);
57547 + //filters
57548 + size = ROUND_UP(size,4);
57549 + size += params->maxNumOfIpProtFiltering;
57550 + size = ROUND_UP(size,4);
57551 + size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
57552 + size = ROUND_UP(size,4);
57553 + size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
57554 +
57555 + // add here for more protocols
57556 +
57557 + // statistics
57558 + size = ROUND_UP(size,4);
57559 + size += sizeof(t_ArStatistics);
57560 +
57561 + ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
57562 +
57563 + param_page =
57564 + XX_PhysToVirt(
57565 + p_FmPort->fmMuramPhysBaseAddr
57566 + + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57567 + WRITE_UINT32(
57568 + *param_page,
57569 + (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
57570 + return E_OK;
57571 +}
57572 +
57573 +t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
57574 +{
57575 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57576 + return p_FmPort->deepSleepVars.autoResMaxSizes;
57577 +}
57578 +
57579 +struct arOffsets
57580 +{
57581 + uint32_t arp;
57582 + uint32_t nd;
57583 + uint32_t icmpv4;
57584 + uint32_t icmpv6;
57585 + uint32_t snmp;
57586 + uint32_t stats;
57587 + uint32_t filtIp;
57588 + uint32_t filtUdp;
57589 + uint32_t filtTcp;
57590 +};
57591 +
57592 +static uint32_t AR_ComputeOffsets(struct arOffsets* of,
57593 + struct t_FmPortDsarParams *params,
57594 + t_FmPort *p_FmPort)
57595 +{
57596 + uint32_t size = sizeof(t_ArCommonDesc);
57597 + // ARP
57598 + if (params->p_AutoResArpInfo)
57599 + {
57600 + size = ROUND_UP(size,4);
57601 + of->arp = size;
57602 + size += sizeof(t_DsarArpDescriptor);
57603 + size += sizeof(t_DsarArpBindingEntry)
57604 + * params->p_AutoResArpInfo->tableSize;
57605 + size += sizeof(t_DsarArpStatistics);
57606 + }
57607 + // ICMPV4
57608 + if (params->p_AutoResEchoIpv4Info)
57609 + {
57610 + size = ROUND_UP(size,4);
57611 + of->icmpv4 = size;
57612 + size += sizeof(t_DsarIcmpV4Descriptor);
57613 + size += sizeof(t_DsarIcmpV4BindingEntry)
57614 + * params->p_AutoResEchoIpv4Info->tableSize;
57615 + size += sizeof(t_DsarIcmpV4Statistics);
57616 + }
57617 + // ICMPV6
57618 + if (params->p_AutoResEchoIpv6Info)
57619 + {
57620 + size = ROUND_UP(size,4);
57621 + of->icmpv6 = size;
57622 + size += sizeof(t_DsarIcmpV6Descriptor);
57623 + size += sizeof(t_DsarIcmpV6BindingEntry)
57624 + * params->p_AutoResEchoIpv6Info->tableSize;
57625 + size += sizeof(t_DsarIcmpV6Statistics);
57626 + }
57627 + // ND
57628 + if (params->p_AutoResNdpInfo)
57629 + {
57630 + size = ROUND_UP(size,4);
57631 + of->nd = size;
57632 + size += sizeof(t_DsarNdDescriptor);
57633 + size += sizeof(t_DsarIcmpV6BindingEntry)
57634 + * (params->p_AutoResNdpInfo->tableSizeAssigned
57635 + + params->p_AutoResNdpInfo->tableSizeTmp);
57636 + size += sizeof(t_DsarIcmpV6Statistics);
57637 + }
57638 + // SNMP
57639 + if (params->p_AutoResSnmpInfo)
57640 + {
57641 + size = ROUND_UP(size,4);
57642 + of->snmp = size;
57643 + size += sizeof(t_DsarSnmpDescriptor);
57644 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57645 + * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
57646 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57647 + * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
57648 + size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
57649 + size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
57650 + size += sizeof(t_DsarIcmpV6Statistics);
57651 + }
57652 + //filters
57653 + size = ROUND_UP(size,4);
57654 + if (params->p_AutoResFilteringInfo)
57655 + {
57656 + of->filtIp = size;
57657 + size += params->p_AutoResFilteringInfo->ipProtTableSize;
57658 + size = ROUND_UP(size,4);
57659 + of->filtUdp = size;
57660 + size += params->p_AutoResFilteringInfo->udpPortsTableSize
57661 + * sizeof(t_PortTblEntry);
57662 + size = ROUND_UP(size,4);
57663 + of->filtTcp = size;
57664 + size += params->p_AutoResFilteringInfo->tcpPortsTableSize
57665 + * sizeof(t_PortTblEntry);
57666 + }
57667 + // add here for more protocols
57668 + // statistics
57669 + size = ROUND_UP(size,4);
57670 + of->stats = size;
57671 + size += sizeof(t_ArStatistics);
57672 + return size;
57673 +}
57674 +
57675 +uint32_t* ARDesc;
57676 +void PrsEnable(t_Handle p_FmPcd);
57677 +void PrsDisable(t_Handle p_FmPcd);
57678 +int PrsIsEnabled(t_Handle p_FmPcd);
57679 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
57680 +
57681 +static t_Error DsarCheckParams(t_FmPortDsarParams *params,
57682 + t_FmPortDsarTablesSizes *sizes)
57683 +{
57684 + bool macInit = FALSE;
57685 + uint8_t mac[6];
57686 + int i = 0;
57687 +
57688 + // check table sizes
57689 + if (params->p_AutoResArpInfo
57690 + && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
57691 + RETURN_ERROR(
57692 + MAJOR, E_INVALID_VALUE,
57693 + ("DSAR: Arp table size exceeds the configured maximum size."));
57694 + if (params->p_AutoResEchoIpv4Info
57695 + && sizes->maxNumOfEchoIpv4Entries
57696 + < params->p_AutoResEchoIpv4Info->tableSize)
57697 + RETURN_ERROR(
57698 + MAJOR,
57699 + E_INVALID_VALUE,
57700 + ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
57701 + if (params->p_AutoResNdpInfo
57702 + && sizes->maxNumOfNdpEntries
57703 + < params->p_AutoResNdpInfo->tableSizeAssigned
57704 + + params->p_AutoResNdpInfo->tableSizeTmp)
57705 + RETURN_ERROR(
57706 + MAJOR, E_INVALID_VALUE,
57707 + ("DSAR: NDP table size exceeds the configured maximum size."));
57708 + if (params->p_AutoResEchoIpv6Info
57709 + && sizes->maxNumOfEchoIpv6Entries
57710 + < params->p_AutoResEchoIpv6Info->tableSize)
57711 + RETURN_ERROR(
57712 + MAJOR,
57713 + E_INVALID_VALUE,
57714 + ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
57715 + if (params->p_AutoResSnmpInfo
57716 + && sizes->maxNumOfSnmpOidEntries
57717 + < params->p_AutoResSnmpInfo->oidsTblSize)
57718 + RETURN_ERROR(
57719 + MAJOR,
57720 + E_INVALID_VALUE,
57721 + ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
57722 + if (params->p_AutoResSnmpInfo
57723 + && sizes->maxNumOfSnmpIPV4Entries
57724 + < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
57725 + RETURN_ERROR(
57726 + MAJOR,
57727 + E_INVALID_VALUE,
57728 + ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
57729 + if (params->p_AutoResSnmpInfo
57730 + && sizes->maxNumOfSnmpIPV6Entries
57731 + < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
57732 + RETURN_ERROR(
57733 + MAJOR,
57734 + E_INVALID_VALUE,
57735 + ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
57736 + if (params->p_AutoResFilteringInfo)
57737 + {
57738 + if (sizes->maxNumOfIpProtFiltering
57739 + < params->p_AutoResFilteringInfo->ipProtTableSize)
57740 + RETURN_ERROR(
57741 + MAJOR,
57742 + E_INVALID_VALUE,
57743 + ("DSAR: ip filter table size exceeds the configured maximum size."));
57744 + if (sizes->maxNumOfTcpPortFiltering
57745 + < params->p_AutoResFilteringInfo->udpPortsTableSize)
57746 + RETURN_ERROR(
57747 + MAJOR,
57748 + E_INVALID_VALUE,
57749 + ("DSAR: udp filter table size exceeds the configured maximum size."));
57750 + if (sizes->maxNumOfUdpPortFiltering
57751 + < params->p_AutoResFilteringInfo->tcpPortsTableSize)
57752 + RETURN_ERROR(
57753 + MAJOR,
57754 + E_INVALID_VALUE,
57755 + ("DSAR: tcp filter table size exceeds the configured maximum size."));
57756 + }
57757 + /* check only 1 MAC address is configured (this is what ucode currently supports) */
57758 + if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
57759 + {
57760 + memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
57761 + i = 1;
57762 + macInit = TRUE;
57763 +
57764 + for (; i < params->p_AutoResArpInfo->tableSize; i++)
57765 + if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
57766 + RETURN_ERROR(
57767 + MAJOR, E_INVALID_VALUE,
57768 + ("DSAR: Only 1 mac address is currently supported."));
57769 + }
57770 + if (params->p_AutoResEchoIpv4Info
57771 + && params->p_AutoResEchoIpv4Info->tableSize)
57772 + {
57773 + i = 0;
57774 + if (!macInit)
57775 + {
57776 + memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
57777 + 6);
57778 + i = 1;
57779 + macInit = TRUE;
57780 + }
57781 + for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57782 + if (memcmp(mac,
57783 + params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
57784 + RETURN_ERROR(
57785 + MAJOR, E_INVALID_VALUE,
57786 + ("DSAR: Only 1 mac address is currently supported."));
57787 + }
57788 + if (params->p_AutoResEchoIpv6Info
57789 + && params->p_AutoResEchoIpv6Info->tableSize)
57790 + {
57791 + i = 0;
57792 + if (!macInit)
57793 + {
57794 + memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
57795 + 6);
57796 + i = 1;
57797 + macInit = TRUE;
57798 + }
57799 + for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57800 + if (memcmp(mac,
57801 + params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
57802 + RETURN_ERROR(
57803 + MAJOR, E_INVALID_VALUE,
57804 + ("DSAR: Only 1 mac address is currently supported."));
57805 + }
57806 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
57807 + {
57808 + i = 0;
57809 + if (!macInit)
57810 + {
57811 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
57812 + 6);
57813 + i = 1;
57814 + macInit = TRUE;
57815 + }
57816 + for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
57817 + if (memcmp(mac,
57818 + params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
57819 + 6))
57820 + RETURN_ERROR(
57821 + MAJOR, E_INVALID_VALUE,
57822 + ("DSAR: Only 1 mac address is currently supported."));
57823 + }
57824 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
57825 + {
57826 + i = 0;
57827 + if (!macInit)
57828 + {
57829 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
57830 + i = 1;
57831 + }
57832 + for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
57833 + if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
57834 + 6))
57835 + RETURN_ERROR(
57836 + MAJOR, E_INVALID_VALUE,
57837 + ("DSAR: Only 1 mac address is currently supported."));
57838 + }
57839 + return E_OK;
57840 +}
57841 +
57842 +static int GetBERLen(uint8_t* buf)
57843 +{
57844 + if (*buf & 0x80)
57845 + {
57846 + if ((*buf & 0x7F) == 1)
57847 + return buf[1];
57848 + else
57849 + return *(uint16_t*)&buf[1]; // assuming max len is 2
57850 + }
57851 + else
57852 + return buf[0];
57853 +}
57854 +#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
57855 +
57856 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
57857 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
57858 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
57859 +static int fm_soc_suspend(void)
57860 +{
57861 + uint32_t *fmclk, tmp32;
57862 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57863 + tmp32 = GET_UINT32(*fmclk);
57864 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
57865 + tmp32 = GET_UINT32(*fmclk);
57866 + iounmap(fmclk);
57867 + return 0;
57868 +}
57869 +
57870 +void fm_clk_down(void)
57871 +{
57872 + uint32_t *fmclk, tmp32;
57873 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57874 + tmp32 = GET_UINT32(*fmclk);
57875 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
57876 + tmp32 = GET_UINT32(*fmclk);
57877 + iounmap(fmclk);
57878 +}
57879 +
57880 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
57881 +{
57882 + int i, j;
57883 + t_Error err;
57884 + uint32_t nia;
57885 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57886 + t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
57887 + t_DsarArpDescriptor *ArpDescriptor;
57888 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
57889 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
57890 + t_DsarNdDescriptor* NDDescriptor;
57891 +
57892 + uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
57893 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57894 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
57895 + struct arOffsets* of;
57896 + uint8_t tmp = 0;
57897 + t_FmGetSetParams fmGetSetParams;
57898 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57899 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
57900 + fmGetSetParams.setParams.sleep = 1;
57901 +
57902 + err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
57903 + if (err != E_OK)
57904 + return err;
57905 +
57906 + p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
57907 + of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
57908 + IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
57909 +
57910 + // common
57911 + WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
57912 + nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
57913 + if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
57914 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
57915 + else
57916 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
57917 + WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
57918 +
57919 + // ARP
57920 + if (params->p_AutoResArpInfo)
57921 + {
57922 + t_DsarArpBindingEntry* arp_bindings;
57923 + ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
57924 + WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
57925 + arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
57926 + if (params->p_AutoResArpInfo->enableConflictDetection)
57927 + WRITE_UINT16(ArpDescriptor->control, 1);
57928 + else
57929 + WRITE_UINT16(ArpDescriptor->control, 0);
57930 + if (params->p_AutoResArpInfo->tableSize)
57931 + {
57932 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
57933 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57934 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57935 + WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
57936 +
57937 + for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
57938 + {
57939 + WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57940 + if (arp_entry[i].isVlan)
57941 + WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57942 + }
57943 + WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
57944 + }
57945 + WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
57946 + sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
57947 + }
57948 +
57949 + // ICMPV4
57950 + if (params->p_AutoResEchoIpv4Info)
57951 + {
57952 + t_DsarIcmpV4BindingEntry* icmpv4_bindings;
57953 + ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
57954 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
57955 + icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
57956 + WRITE_UINT16(ICMPV4Descriptor->control, 0);
57957 + if (params->p_AutoResEchoIpv4Info->tableSize)
57958 + {
57959 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
57960 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57961 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57962 + WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
57963 +
57964 + for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57965 + {
57966 + WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57967 + if (arp_entry[i].isVlan)
57968 + WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57969 + }
57970 + WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
57971 + }
57972 + WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
57973 + sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
57974 + }
57975 +
57976 + // ICMPV6
57977 + if (params->p_AutoResEchoIpv6Info)
57978 + {
57979 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57980 + ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
57981 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
57982 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
57983 + WRITE_UINT16(ICMPV6Descriptor->control, 0);
57984 + if (params->p_AutoResEchoIpv6Info->tableSize)
57985 + {
57986 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
57987 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
57988 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
57989 + WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
57990 +
57991 + for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57992 + {
57993 + for (j = 0; j < 4; j++)
57994 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57995 + if (ndp_entry[i].isVlan)
57996 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57997 + }
57998 + WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
57999 + }
58000 + WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
58001 + sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
58002 + }
58003 +
58004 + // ND
58005 + if (params->p_AutoResNdpInfo)
58006 + {
58007 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
58008 + NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
58009 + WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
58010 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
58011 + if (params->p_AutoResNdpInfo->enableConflictDetection)
58012 + WRITE_UINT16(NDDescriptor->control, 1);
58013 + else
58014 + WRITE_UINT16(NDDescriptor->control, 0);
58015 + if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
58016 + {
58017 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
58018 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
58019 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
58020 + WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
58021 + + params->p_AutoResNdpInfo->tableSizeTmp);
58022 +
58023 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
58024 + {
58025 + for (j = 0; j < 4; j++)
58026 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
58027 + if (ndp_entry[i].isVlan)
58028 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
58029 + }
58030 + ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
58031 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
58032 + {
58033 + for (j = 0; j < 4; j++)
58034 + WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
58035 + if (ndp_entry[i].isVlan)
58036 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
58037 + }
58038 + WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
58039 + }
58040 + WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
58041 + * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
58042 + - fmMuramVirtBaseAddr);
58043 + WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
58044 + }
58045 +
58046 + // SNMP
58047 + if (params->p_AutoResSnmpInfo)
58048 + {
58049 + t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
58050 + t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
58051 + t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
58052 + t_OidsTblEntry* snmpOid;
58053 + uint8_t *charPointer;
58054 + int len;
58055 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
58056 + WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
58057 + WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
58058 + WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
58059 + snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
58060 + if (snmpSrc->numOfIpv4Addresses)
58061 + {
58062 + t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
58063 + WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
58064 + for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
58065 + {
58066 + WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
58067 + if (snmpIpv4AddrSrc[i].isVlan)
58068 + WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
58069 + }
58070 + WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
58071 + }
58072 + snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
58073 + + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
58074 + if (snmpSrc->numOfIpv6Addresses)
58075 + {
58076 + t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
58077 + WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
58078 + for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
58079 + {
58080 + for (j = 0; j < 4; j++)
58081 + WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
58082 + if (snmpIpv6AddrSrc[i].isVlan)
58083 + WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
58084 + }
58085 + WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
58086 + }
58087 + snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
58088 + + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
58089 + charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
58090 + + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
58091 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
58092 + Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
58093 + WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
58094 + charPointer += len;
58095 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
58096 + Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
58097 + WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
58098 + charPointer += len;
58099 + WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
58100 + WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
58101 + for (i = 0; i < snmpSrc->oidsTblSize; i++)
58102 + {
58103 + WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
58104 + WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
58105 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
58106 + WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
58107 + charPointer += snmpSrc->p_OidsTbl[i].oidSize;
58108 + if (snmpSrc->p_OidsTbl[i].resSize <= 4)
58109 + WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
58110 + else
58111 + {
58112 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
58113 + WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
58114 + charPointer += snmpSrc->p_OidsTbl[i].resSize;
58115 + }
58116 + snmpOid++;
58117 + }
58118 + charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
58119 + WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
58120 + }
58121 +
58122 + // filtering
58123 + if (params->p_AutoResFilteringInfo)
58124 + {
58125 + if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
58126 + tmp |= IP_PROT_TBL_PASS_MASK;
58127 + if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
58128 + tmp |= UDP_PORT_TBL_PASS_MASK;
58129 + if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
58130 + tmp |= TCP_PORT_TBL_PASS_MASK;
58131 + WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
58132 + WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
58133 +
58134 + // ip filtering
58135 + if (params->p_AutoResFilteringInfo->ipProtTableSize)
58136 + {
58137 + uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
58138 + WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
58139 + for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
58140 + WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
58141 + WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
58142 + }
58143 +
58144 + // udp filtering
58145 + if (params->p_AutoResFilteringInfo->udpPortsTableSize)
58146 + {
58147 + t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
58148 + WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
58149 + for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
58150 + {
58151 + WRITE_UINT32(udp_tbl[i].Ports,
58152 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
58153 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
58154 + WRITE_UINT32(udp_tbl[i].PortsMask,
58155 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
58156 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
58157 + }
58158 + WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
58159 + }
58160 +
58161 + // tcp filtering
58162 + if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
58163 + {
58164 + t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
58165 + WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
58166 + for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
58167 + {
58168 + WRITE_UINT32(tcp_tbl[i].Ports,
58169 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
58170 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
58171 + WRITE_UINT32(tcp_tbl[i].PortsMask,
58172 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
58173 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
58174 + }
58175 + WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
58176 + }
58177 + }
58178 + // common stats
58179 + WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
58180 +
58181 + // get into Deep Sleep sequence:
58182 +
58183 + // Ensures that FMan do not enter the idle state. This is done by programing
58184 + // FMDPSLPCR[FM_STOP] to one.
58185 + fm_soc_suspend();
58186 +
58187 + ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
58188 + return E_OK;
58189 +
58190 +}
58191 +
58192 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
58193 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
58194 +{
58195 + t_FmGetSetParams fmGetSetParams;
58196 + t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
58197 + t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
58198 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
58199 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
58200 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58201 + fmGetSetParams.setParams.type = UPDATE_FM_CLD;
58202 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58203 +
58204 + /* Issue graceful stop to HC port */
58205 + FM_PORT_Disable(p_FmPortHc);
58206 +
58207 + // config tx port
58208 + p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
58209 + 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);
58210 + // ????
58211 + p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
58212 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
58213 + // Stage 7:echo
58214 + p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
58215 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
58216 + if (!PrsIsEnabled(h_FmPcd))
58217 + {
58218 + p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
58219 + PrsEnable(h_FmPcd);
58220 + }
58221 + else
58222 + p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
58223 +
58224 + p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
58225 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
58226 +
58227 + // save rcfg for restoring: accumulate mode is changed by ucode
58228 + p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
58229 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
58230 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58231 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
58232 + fmGetSetParams.setParams.sleep = 1;
58233 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58234 +
58235 +// ***** issue external request sync command
58236 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58237 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
58238 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58239 + // get
58240 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58241 + fmGetSetParams.getParams.type = GET_FMFP_EXTC;
58242 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58243 + if (fmGetSetParams.getParams.fmfp_extc != 0)
58244 + {
58245 + // clear
58246 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58247 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
58248 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58249 +}
58250 +
58251 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58252 + fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
58253 + do
58254 + {
58255 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58256 + } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
58257 + if (fmGetSetParams.getParams.fm_npi != 0)
58258 + XX_Print("FM: Sync did not finish\n");
58259 +
58260 + // check that all stoped
58261 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58262 + fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
58263 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58264 + while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
58265 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58266 + if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
58267 + XX_Print("FM: Sleeping\n");
58268 +// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
58269 +
58270 + return E_OK;
58271 +}
58272 +
58273 +EXPORT_SYMBOL(FM_PORT_EnterDsarFinal);
58274 +
58275 +void FM_PORT_Dsar_DumpRegs()
58276 +{
58277 + uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
58278 + DUMP_MEMORY(hh, 0x220);
58279 +}
58280 +
58281 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
58282 +{
58283 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58284 + t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
58285 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
58286 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
58287 + t_FmGetSetParams fmGetSetParams;
58288 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58289 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
58290 + fmGetSetParams.setParams.sleep = 0;
58291 + if (p_FmPort->deepSleepVars.autoResOffsets)
58292 + {
58293 + XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
58294 + p_FmPort->deepSleepVars.autoResOffsets = 0;
58295 + }
58296 +
58297 + if (p_FmPort->deepSleepVars.dsarEnabledParser)
58298 + PrsDisable(FmGetPcd(p_FmPort->h_Fm));
58299 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
58300 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
58301 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
58302 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58303 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
58304 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
58305 + FM_PORT_Enable(p_FmPortHc);
58306 +}
58307 +
58308 +bool FM_PORT_IsInDsar(t_Handle h_FmPort)
58309 +{
58310 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
58311 + return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
58312 +}
58313 +
58314 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
58315 +{
58316 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58317 + struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
58318 + uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
58319 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
58320 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
58321 + t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
58322 + t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58323 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
58324 + t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
58325 + t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
58326 + t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58327 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
58328 + t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
58329 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
58330 + t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58331 + stats->arpArCnt = arp_stats->arCnt;
58332 + stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
58333 + stats->ndpArCnt = nd_stats->arCnt;
58334 + stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
58335 + stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
58336 + stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
58337 + return E_OK;
58338 +}
58339 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
58340 new file mode 100644
58341 index 00000000..85986f55
58342 --- /dev/null
58343 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
58344 @@ -0,0 +1,999 @@
58345 +/*
58346 + * Copyright 2008-2012 Freescale Semiconductor Inc.
58347 + *
58348 + * Redistribution and use in source and binary forms, with or without
58349 + * modification, are permitted provided that the following conditions are met:
58350 + * * Redistributions of source code must retain the above copyright
58351 + * notice, this list of conditions and the following disclaimer.
58352 + * * Redistributions in binary form must reproduce the above copyright
58353 + * notice, this list of conditions and the following disclaimer in the
58354 + * documentation and/or other materials provided with the distribution.
58355 + * * Neither the name of Freescale Semiconductor nor the
58356 + * names of its contributors may be used to endorse or promote products
58357 + * derived from this software without specific prior written permission.
58358 + *
58359 + *
58360 + * ALTERNATIVELY, this software may be distributed under the terms of the
58361 + * GNU General Public License ("GPL") as published by the Free Software
58362 + * Foundation, either version 2 of that License or (at your option) any
58363 + * later version.
58364 + *
58365 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
58366 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
58367 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
58368 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
58369 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
58370 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58371 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58372 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58373 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58374 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58375 + */
58376 +
58377 +
58378 +/******************************************************************************
58379 + @File fm_port.h
58380 +
58381 + @Description FM Port internal structures and definitions.
58382 +*//***************************************************************************/
58383 +#ifndef __FM_PORT_H
58384 +#define __FM_PORT_H
58385 +
58386 +#include "error_ext.h"
58387 +#include "std_ext.h"
58388 +#include "fm_port_ext.h"
58389 +
58390 +#include "fm_common.h"
58391 +#include "fm_sp_common.h"
58392 +#include "fsl_fman_sp.h"
58393 +#include "fm_port_ext.h"
58394 +#include "fsl_fman_port.h"
58395 +
58396 +#define __ERR_MODULE__ MODULE_FM_PORT
58397 +
58398 +
58399 +#define MIN_EXT_BUF_SIZE 64
58400 +#define DATA_ALIGNMENT 64
58401 +#define MAX_LIODN_OFFSET 64
58402 +#define MAX_PORT_FIFO_SIZE MIN(BMI_MAX_FIFO_SIZE, 1024*BMI_FIFO_UNITS)
58403 +
58404 +/**************************************************************************//**
58405 + @Description Memory Map defines
58406 +*//***************************************************************************/
58407 +#define BMI_PORT_REGS_OFFSET 0
58408 +#define QMI_PORT_REGS_OFFSET 0x400
58409 +#define PRS_PORT_REGS_OFFSET 0x800
58410 +
58411 +/**************************************************************************//**
58412 + @Description defaults
58413 +*//***************************************************************************/
58414 +#define DEFAULT_PORT_deqHighPriority_1G FALSE
58415 +#define DEFAULT_PORT_deqHighPriority_10G TRUE
58416 +#define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1
58417 +#define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH
58418 +#define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH
58419 +#define DEFAULT_PORT_deqByteCnt_10G 0x1400
58420 +#define DEFAULT_PORT_deqByteCnt_1G 0x400
58421 +#define DEFAULT_PORT_bufferPrefixContent_privDataSize DEFAULT_FM_SP_bufferPrefixContent_privDataSize
58422 +#define DEFAULT_PORT_bufferPrefixContent_passPrsResult DEFAULT_FM_SP_bufferPrefixContent_passPrsResult
58423 +#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp
58424 +#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo
58425 +#define DEFAULT_PORT_bufferPrefixContent_dataAlign DEFAULT_FM_SP_bufferPrefixContent_dataAlign
58426 +#define DEFAULT_PORT_cheksumLastBytesIgnore 0
58427 +#define DEFAULT_PORT_cutBytesFromEnd 4
58428 +#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2
58429 +
58430 +#define DEFAULT_PORT_frmDiscardOverride FALSE
58431 +
58432 +#define DEFAULT_PORT_dmaSwapData (e_FmDmaSwapOption)DEFAULT_FMAN_SP_DMA_SWAP_DATA
58433 +#define DEFAULT_PORT_dmaIntContextCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR
58434 +#define DEFAULT_PORT_dmaHeaderCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR
58435 +#define DEFAULT_PORT_dmaScatterGatherCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR
58436 +#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE
58437 +
58438 +#define DEFAULT_PORT_noScatherGather DEFAULT_FMAN_SP_NO_SCATTER_GATHER
58439 +#define DEFAULT_PORT_forwardIntContextReuse FALSE
58440 +#define DEFAULT_PORT_BufMargins_startMargins 32
58441 +#define DEFAULT_PORT_BufMargins_endMargins 0
58442 +#define DEFAULT_PORT_syncReq TRUE
58443 +#define DEFAULT_PORT_syncReqForHc FALSE
58444 +#define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN
58445 +#define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD
58446 +/* #define DEFAULT_PORT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE */
58447 +/* #define DEFAULT_PORT_rateLimitBurstSizeHighGranularity FALSE */
58448 +#define DEFAULT_PORT_exception IM_EV_BSY
58449 +#define DEFAULT_PORT_maxFrameLength 9600
58450 +
58451 +#define DEFAULT_notSupported 0xff
58452 +
58453 +#if (DPAA_VERSION < 11)
58454 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58455 +#define DEFAULT_PORT_rxFifoThreshold (MAX_PORT_FIFO_SIZE*3/4)
58456 +
58457 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58458 +#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE)
58459 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1
58460 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58461 +
58462 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58463 +
58464 +/* Host command port MUST NOT be changed to more than 1 !!! */
58465 +#define DEFAULT_PORT_numOfTasks(type) \
58466 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58467 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 16 : \
58468 + ((((type) == e_FM_PORT_TYPE_RX) || \
58469 + ((type) == e_FM_PORT_TYPE_TX) || \
58470 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1))
58471 +
58472 +#define DEFAULT_PORT_extraNumOfTasks(type) \
58473 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58474 + (((type) == e_FM_PORT_TYPE_RX) ? 2 : 0))
58475 +
58476 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58477 + (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \
58478 + ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : 1 )
58479 +
58480 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) \
58481 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58482 + (((type) == e_FM_PORT_TYPE_RX) ? 1 : 0))
58483 +
58484 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58485 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58486 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 48 : \
58487 + ((type) == e_FM_PORT_TYPE_RX) ? 45 : \
58488 + ((type) == e_FM_PORT_TYPE_TX) ? 44 : 8)
58489 +
58490 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58491 +
58492 +#else /* (DPAA_VERSION < 11) */
58493 +/* Defaults are registers' reset values */
58494 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58495 +#define DEFAULT_PORT_rxFifoThreshold MAX_PORT_FIFO_SIZE
58496 +
58497 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58498 +#define DEFAULT_PORT_txFifoLowComfLevel (5 * KILOBYTE)
58499 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 2
58500 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58501 +
58502 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58503 +
58504 +#define DEFAULT_PORT_numOfTasks(type) \
58505 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58506 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 14 : \
58507 + (((type) == e_FM_PORT_TYPE_RX) || \
58508 + ((type) == e_FM_PORT_TYPE_TX)) ? 4 : \
58509 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? 6 : 1)
58510 +
58511 +#define DEFAULT_PORT_extraNumOfTasks(type) 0
58512 +
58513 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58514 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58515 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 12 : \
58516 + ((type) == e_FM_PORT_TYPE_RX) ? 2 : \
58517 + ((type) == e_FM_PORT_TYPE_TX) ? 3 : \
58518 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 2 : 4)
58519 +
58520 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) 0
58521 +
58522 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58523 + (uint32_t) (((type) == e_FM_PORT_TYPE_RX_10G) ? 96 : \
58524 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 64 : \
58525 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 10 : 50)
58526 +
58527 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58528 +
58529 +#endif /* (DPAA_VERSION < 11) */
58530 +
58531 +#define DEFAULT_PORT_txBdRingLength 16
58532 +#define DEFAULT_PORT_rxBdRingLength 128
58533 +#define DEFAULT_PORT_ImfwExtStructsMemId 0
58534 +#define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE
58535 +
58536 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58537 +
58538 +/**************************************************************************//**
58539 + @Collection PCD Engines
58540 +*//***************************************************************************/
58541 +typedef uint32_t fmPcdEngines_t; /**< options as defined below: */
58542 +
58543 +#define FM_PCD_NONE 0 /**< No PCD Engine indicated */
58544 +#define FM_PCD_PRS 0x80000000 /**< Parser indicated */
58545 +#define FM_PCD_KG 0x40000000 /**< Keygen indicated */
58546 +#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */
58547 +#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */
58548 +#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */
58549 +/* @} */
58550 +
58551 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8
58552 +#define FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256
58553 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58554 +
58555 +#define FM_OH_PORT_ID 0
58556 +
58557 +/***********************************************************************/
58558 +/* SW parser OFFLOAD labels (offsets) */
58559 +/***********************************************************************/
58560 +#if (DPAA_VERSION == 10)
58561 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x300
58562 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x325
58563 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x325
58564 +#else
58565 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x100
58566 +/* Will be used for:
58567 + * 1. identify fragments
58568 + * 2. udp-lite
58569 + */
58570 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x146
58571 +/* Will be used for:
58572 + * 1. will identify the fragmentable area
58573 + * 2. udp-lite
58574 + */
58575 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x261
58576 +#define OFFLOAD_SW_PATCH_CAPWAP_LABEL 0x38d
58577 +#endif /* (DPAA_VERSION == 10) */
58578 +
58579 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
58580 +#define UDP_LITE_SW_PATCH_LABEL 0x2E0
58581 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
58582 +
58583 +
58584 +/**************************************************************************//**
58585 + @Description Memory Mapped Registers
58586 +*//***************************************************************************/
58587 +
58588 +#if defined(__MWERKS__) && !defined(__GNUC__)
58589 +#pragma pack(push,1)
58590 +#endif /* defined(__MWERKS__) && ... */
58591 +
58592 +typedef struct
58593 +{
58594 + volatile uint32_t fmbm_rcfg; /**< Rx Configuration */
58595 + volatile uint32_t fmbm_rst; /**< Rx Status */
58596 + volatile uint32_t fmbm_rda; /**< Rx DMA attributes*/
58597 + volatile uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
58598 + volatile uint32_t fmbm_rfed; /**< Rx Frame End Data*/
58599 + volatile uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
58600 + volatile uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
58601 + volatile uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
58602 + volatile uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
58603 + volatile uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
58604 + volatile uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
58605 + volatile uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
58606 + volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */
58607 + volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
58608 + volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */
58609 + volatile uint32_t reserved1[0x01];/**< (0x03C) */
58610 + volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58611 + /**< Rx Parse Results Array Initialization*/
58612 + volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
58613 + volatile uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
58614 + volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
58615 + volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
58616 + volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
58617 + volatile uint32_t reserved2[0x02];/**< (0x074-0x078) */
58618 + volatile uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
58619 + volatile uint32_t reserved3[0x20];/**< (0x080 0x0FF) */
58620 + volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58621 + /**< Buffer Manager pool Information-*/
58622 + volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58623 + /**< Allocate Counter-*/
58624 + volatile uint32_t reserved4[0x08];
58625 + /**< 0x130/0x140 - 0x15F reserved -*/
58626 + volatile uint32_t fmbm_rcgm[FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32];
58627 + /**< Congestion Group Map*/
58628 + volatile uint32_t fmbm_rmpd; /**< BM Pool Depletion */
58629 + volatile uint32_t reserved5[0x1F];/**< (0x184 0x1FF) */
58630 + volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
58631 + volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
58632 + volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
58633 + volatile uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
58634 + volatile uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
58635 + volatile uint32_t fmbm_rfcd; /**< Rx Frame Discard Counter*/
58636 + volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
58637 + volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/
58638 + volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/
58639 + volatile uint32_t fmbm_rpec; /**< Rx RX Prepare to enqueue Counter-*/
58640 + volatile uint32_t reserved6[0x16];/**< (0x228 0x27F) */
58641 + volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/
58642 + volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
58643 + volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
58644 + volatile uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
58645 + volatile uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization Counter*/
58646 + volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
58647 + volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
58648 + volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
58649 + volatile uint32_t reserved7[0x18];/**< (0x2A0-0x2FF) */
58650 + volatile uint32_t fmbm_rdcfg[0x3];/**< Rx Debug-*/
58651 + volatile uint32_t fmbm_rgpr; /**< Rx General Purpose Register. */
58652 + volatile uint32_t reserved8[0x3a];/**< (0x310-0x3FF) */
58653 +} t_FmPortRxBmiRegs;
58654 +
58655 +typedef struct
58656 +{
58657 + volatile uint32_t fmbm_tcfg; /**< Tx Configuration */
58658 + volatile uint32_t fmbm_tst; /**< Tx Status */
58659 + volatile uint32_t fmbm_tda; /**< Tx DMA attributes */
58660 + volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
58661 + volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */
58662 + volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
58663 + volatile uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
58664 + volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
58665 + volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
58666 + volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */
58667 + volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
58668 + volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
58669 + volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
58670 + volatile uint32_t fmbm_tccb; /**< Tx Coarse Classification Base */
58671 + volatile uint32_t reserved0[0x0e];/**< (0x038-0x070) */
58672 + volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
58673 + volatile uint32_t fmbm_tpfcm[0x02];/**< Tx Priority based Flow Control (PFC) Mapping */
58674 + volatile uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
58675 + volatile uint32_t reserved2[0x60];/**< (0x080-0x200) */
58676 + volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */
58677 + volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */
58678 + volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
58679 + volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */
58680 + volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */
58681 + volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
58682 + volatile uint32_t reserved3[0x1A];/**< (0x218-0x280) */
58683 + volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/
58684 + volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
58685 + volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
58686 + volatile uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
58687 + volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/
58688 + volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
58689 + volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
58690 + volatile uint32_t reserved4[16]; /**< (0x29C-0x2FF) */
58691 + volatile uint32_t fmbm_tdcfg[0x3];/**< Tx Debug-*/
58692 + volatile uint32_t fmbm_tgpr; /**< O/H General Purpose Register */
58693 + volatile uint32_t reserved5[0x3a];/**< (0x310-0x3FF) */
58694 +} t_FmPortTxBmiRegs;
58695 +
58696 +typedef struct
58697 +{
58698 + volatile uint32_t fmbm_ocfg; /**< O/H Configuration */
58699 + volatile uint32_t fmbm_ost; /**< O/H Status */
58700 + volatile uint32_t fmbm_oda; /**< O/H DMA attributes */
58701 + volatile uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
58702 + volatile uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
58703 + volatile uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
58704 + volatile uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
58705 + volatile uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
58706 + volatile uint32_t fmbm_opso; /**< O/H Parse Start Offset */
58707 + volatile uint32_t fmbm_opp; /**< O/H Policer Profile */
58708 + volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */
58709 + volatile uint32_t fmbm_oim; /**< O/H Internal margins*/
58710 + volatile uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
58711 + volatile uint32_t fmbm_ofed; /**< O/H Frame End Data*/
58712 + volatile uint32_t reserved0[2]; /**< (0x038 - 0x03F) */
58713 + volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58714 + /**< O/H Parse Results Array Initialization */
58715 + volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
58716 + volatile uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
58717 + volatile uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
58718 + volatile uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
58719 + volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
58720 + volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
58721 + volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
58722 + volatile uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
58723 + volatile uint32_t reserved1[0x20];/**< (0x080 - 0x0FF) */
58724 + volatile uint32_t fmbm_oebmpi[2]; /**< Buffer Manager Observed Pool Information */
58725 + volatile uint32_t reserved2[0x16];/**< (0x108 - 0x15F) */
58726 + volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */
58727 + volatile uint32_t reserved3[0x7]; /**< (0x164 - 0x17F) */
58728 + volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
58729 + volatile uint32_t reserved4[0x1F];/**< (0x184 - 0x1FF) */
58730 + volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */
58731 + volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */
58732 + volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
58733 + volatile uint32_t fmbm_ofledc; /**< O/H Frames Length Error Discard Counter */
58734 + volatile uint32_t fmbm_ofufdc; /**< O/H Frames Unsupported Format Discard Counter */
58735 + volatile uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
58736 + volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */
58737 + volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */
58738 + volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
58739 + volatile uint32_t fmbm_oodc; /**< O/H Out of Buffers Discard Counter */
58740 + volatile uint32_t fmbm_opec; /**< O/H Prepare to enqueue Counter */
58741 + volatile uint32_t reserved5[0x15];/**< ( - 0x27F) */
58742 + volatile uint32_t fmbm_opc; /**< O/H Performance Counters */
58743 + volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
58744 + volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */
58745 + volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
58746 + volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
58747 + volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
58748 + volatile uint32_t reserved6[26]; /**< (0x298-0x2FF) */
58749 + volatile uint32_t fmbm_odcfg[0x3];/**< O/H Debug (only 1 in P1023) */
58750 + volatile uint32_t fmbm_ogpr; /**< O/H General Purpose Register. */
58751 + volatile uint32_t reserved7[0x3a];/**< (0x310 0x3FF) */
58752 +} t_FmPortOhBmiRegs;
58753 +
58754 +typedef union
58755 +{
58756 + t_FmPortRxBmiRegs rxPortBmiRegs;
58757 + t_FmPortTxBmiRegs txPortBmiRegs;
58758 + t_FmPortOhBmiRegs ohPortBmiRegs;
58759 +} u_FmPortBmiRegs;
58760 +
58761 +typedef struct
58762 +{
58763 + volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */
58764 + volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
58765 + volatile uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
58766 + volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */
58767 + volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */
58768 + volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
58769 +} t_FmPortNonRxQmiRegs;
58770 +
58771 +typedef struct
58772 +{
58773 + volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */
58774 + volatile uint32_t fmqm_pns; /**< PortID n Status Register */
58775 + volatile uint32_t fmqm_pnts; /**< PortID n Task Status Register */
58776 + volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */
58777 + volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
58778 + volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */
58779 + t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */
58780 +} t_FmPortQmiRegs;
58781 +
58782 +typedef struct
58783 +{
58784 + struct
58785 + {
58786 + volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */
58787 + volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */
58788 + } hdrs[FM_PCD_PRS_NUM_OF_HDRS];
58789 + volatile uint32_t reserved0[0xde];
58790 + volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */
58791 + volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */
58792 +} t_FmPortPrsRegs;
58793 +
58794 +/**************************************************************************//*
58795 + @Description Basic buffer descriptor (BD) structure
58796 +*//***************************************************************************/
58797 +typedef _Packed struct
58798 +{
58799 + volatile uint16_t status;
58800 + volatile uint16_t length;
58801 + volatile uint8_t reserved0[0x6];
58802 + volatile uint8_t reserved1[0x1];
58803 + volatile t_FmPhysAddr buff;
58804 +} _PackedType t_FmImBd;
58805 +
58806 +typedef _Packed struct
58807 +{
58808 + volatile uint16_t gen; /**< tbd */
58809 + volatile uint8_t reserved0[0x1];
58810 + volatile t_FmPhysAddr bdRingBase; /**< tbd */
58811 + volatile uint16_t bdRingSize; /**< tbd */
58812 + volatile uint16_t offsetIn; /**< tbd */
58813 + volatile uint16_t offsetOut; /**< tbd */
58814 + volatile uint8_t reserved1[0x12]; /**< 0x0e - 0x1f */
58815 +} _PackedType t_FmPortImQd;
58816 +
58817 +typedef _Packed struct
58818 +{
58819 + volatile uint32_t mode; /**< Mode register */
58820 + volatile uint32_t rxQdPtr; /**< tbd */
58821 + volatile uint32_t txQdPtr; /**< tbd */
58822 + volatile uint16_t mrblr; /**< tbd */
58823 + volatile uint16_t rxQdBsyCnt; /**< tbd */
58824 + volatile uint8_t reserved0[0x10]; /**< 0x10 - 0x1f */
58825 + t_FmPortImQd rxQd;
58826 + t_FmPortImQd txQd;
58827 + volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */
58828 +} _PackedType t_FmPortImPram;
58829 +
58830 +#if defined(__MWERKS__) && !defined(__GNUC__)
58831 +#pragma pack(pop)
58832 +#endif /* defined(__MWERKS__) && ... */
58833 +
58834 +
58835 +/**************************************************************************//**
58836 + @Description Registers bit fields
58837 +*//***************************************************************************/
58838 +
58839 +/**************************************************************************//**
58840 + @Description BMI defines
58841 +*//***************************************************************************/
58842 +#if (DPAA_VERSION >= 11)
58843 +#define BMI_SP_ID_MASK 0xff000000
58844 +#define BMI_SP_ID_SHIFT 24
58845 +#define BMI_SP_EN 0x01000000
58846 +#endif /* (DPAA_VERSION >= 11) */
58847 +
58848 +#define BMI_PORT_CFG_EN 0x80000000
58849 +#define BMI_PORT_CFG_EN_MACSEC 0x00800000
58850 +#define BMI_PORT_CFG_FDOVR 0x02000000
58851 +#define BMI_PORT_CFG_IM 0x01000000
58852 +#define BMI_PORT_CFG_AM 0x00000040
58853 +#define BMI_PORT_STATUS_BSY 0x80000000
58854 +#define BMI_COUNTERS_EN 0x80000000
58855 +
58856 +#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000
58857 +#define BMI_PORT_RFNE_FRWD_RPD 0x40000000
58858 +#define BMI_RFNE_FDCS_MASK 0xFF000000
58859 +#define BMI_RFNE_HXS_MASK 0x000000FF
58860 +
58861 +#define BMI_CMD_MR_LEAC 0x00200000
58862 +#define BMI_CMD_MR_SLEAC 0x00100000
58863 +#define BMI_CMD_MR_MA 0x00080000
58864 +#define BMI_CMD_MR_DEAS 0x00040000
58865 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
58866 + BMI_CMD_MR_SLEAC | \
58867 + BMI_CMD_MR_MA | \
58868 + BMI_CMD_MR_DEAS)
58869 +#define BMI_CMD_ATTR_ORDER 0x80000000
58870 +#define BMI_CMD_ATTR_SYNC 0x02000000
58871 +#define BMI_CMD_ATTR_MODE_MISS_ALLIGN_ADDR_EN 0x00080000
58872 +#define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00
58873 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000
58874 +#define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000
58875 +#define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00
58876 +
58877 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
58878 +#define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \
58879 + FM_PORT_FRM_ERR_PHYSICAL | \
58880 + FM_PORT_FRM_ERR_SIZE | \
58881 + FM_PORT_FRM_ERR_CLS_DISCARD | \
58882 + FM_PORT_FRM_ERR_EXTRACTION | \
58883 + FM_PORT_FRM_ERR_NO_SCHEME | \
58884 + FM_PORT_FRM_ERR_COLOR_RED | \
58885 + FM_PORT_FRM_ERR_COLOR_YELLOW | \
58886 + FM_PORT_FRM_ERR_ILL_PLCR | \
58887 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58888 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58889 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58890 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58891 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58892 + FM_PORT_FRM_ERR_IPRE | \
58893 + FM_PORT_FRM_ERR_IPR_NCSP | \
58894 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW))
58895 +
58896 +#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \
58897 + ~(FM_PORT_FRM_ERR_LENGTH | \
58898 + FM_PORT_FRM_ERR_NON_FM | \
58899 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT))
58900 +
58901 +#define BMI_RATE_LIMIT_EN 0x80000000
58902 +#define BMI_RATE_LIMIT_BURST_SIZE_GRAN 0x80000000
58903 +#define BMI_RATE_LIMIT_SCALE_BY_2 0x00000001
58904 +#define BMI_RATE_LIMIT_SCALE_BY_4 0x00000002
58905 +#define BMI_RATE_LIMIT_SCALE_BY_8 0x00000003
58906 +
58907 +#define BMI_RX_FIFO_THRESHOLD_BC 0x80000000
58908 +
58909 +#define BMI_PRS_RESULT_HIGH 0x00000000
58910 +#define BMI_PRS_RESULT_LOW 0xFFFFFFFF
58911 +
58912 +
58913 +#define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \
58914 + FM_PORT_FRM_ERR_PHYSICAL | \
58915 + FM_PORT_FRM_ERR_SIZE | \
58916 + FM_PORT_FRM_ERR_EXTRACTION | \
58917 + FM_PORT_FRM_ERR_NO_SCHEME | \
58918 + FM_PORT_FRM_ERR_ILL_PLCR | \
58919 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58920 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58921 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58922 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58923 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58924 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \
58925 + FM_PORT_FRM_ERR_IPRE)
58926 +
58927 +#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \
58928 + FM_PORT_FRM_ERR_LENGTH | \
58929 + FM_PORT_FRM_ERR_NON_FM | \
58930 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)
58931 +
58932 +
58933 +#define BMI_RX_FIFO_PRI_ELEVATION_MASK 0x03FF0000
58934 +#define BMI_RX_FIFO_THRESHOLD_MASK 0x000003FF
58935 +#define BMI_TX_FIFO_MIN_FILL_MASK 0x03FF0000
58936 +#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000F000
58937 +#define BMI_TX_LOW_COMF_MASK 0x000003FF
58938 +
58939 +/* shifts */
58940 +#define BMI_PORT_CFG_MS_SEL_SHIFT 16
58941 +#define BMI_DMA_ATTR_IC_CACHE_SHIFT FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT
58942 +#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT
58943 +#define BMI_DMA_ATTR_SG_CACHE_SHIFT FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT
58944 +
58945 +#define BMI_IM_FOF_SHIFT 28
58946 +#define BMI_PR_PORTID_SHIFT 24
58947 +
58948 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
58949 +#define BMI_RX_FIFO_THRESHOLD_SHIFT 0
58950 +
58951 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
58952 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
58953 +
58954 +#define BMI_IC_SIZE_SHIFT FMAN_SP_IC_SIZE_SHIFT
58955 +
58956 +#define BMI_INT_BUF_MARG_SHIFT 28
58957 +
58958 +#define BMI_EXT_BUF_MARG_END_SHIFT FMAN_SP_EXT_BUF_MARG_END_SHIFT
58959 +
58960 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
58961 +#define BMI_CMD_ATTR_COM_MODE_SHIFT 16
58962 +#define BMI_CMD_ATTR_MACCMD_SHIFT 8
58963 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE_SHIFT 15
58964 +#define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12
58965 +#define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8
58966 +
58967 +#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24
58968 +
58969 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
58970 +#define BMI_TX_LOW_COMF_SHIFT 0
58971 +
58972 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
58973 +#define BMI_PERFORMANCE_PORT_COMP_SHIFT 16
58974 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
58975 +#define BMI_PERFORMANCE_FIFO_COMP_SHIFT 0
58976 +
58977 +#define BMI_MAX_BURST_SHIFT 16
58978 +#define BMI_COUNT_RATE_UNIT_SHIFT 16
58979 +
58980 +/* sizes */
58981 +#define FRAME_END_DATA_SIZE 16
58982 +#define FRAME_OFFSET_UNITS 16
58983 +#define MIN_TX_INT_OFFSET 16
58984 +#define MAX_FRAME_OFFSET 64
58985 +#define MAX_FIFO_PIPELINE_DEPTH 8
58986 +#define MAX_PERFORMANCE_TASK_COMP 64
58987 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
58988 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
58989 +#define MAX_PERFORMANCE_DMA_COMP 16
58990 +#define MAX_NUM_OF_TASKS 64
58991 +#define MAX_NUM_OF_EXTRA_TASKS 8
58992 +#define MAX_NUM_OF_DMAS 16
58993 +#define MAX_NUM_OF_EXTRA_DMAS 8
58994 +#define MAX_BURST_SIZE 1024
58995 +#define MIN_NUM_OF_OP_DMAS 2
58996 +
58997 +
58998 +/**************************************************************************//**
58999 + @Description QMI defines
59000 +*//***************************************************************************/
59001 +/* masks */
59002 +#define QMI_PORT_CFG_EN 0x80000000
59003 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
59004 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
59005 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
59006 +
59007 +#define QMI_DEQ_CFG_PREFETCH_NO_TNUM 0x02000000
59008 +#define QMI_DEQ_CFG_PREFETCH_WAITING_TNUM 0
59009 +#define QMI_DEQ_CFG_PREFETCH_1_FRAME 0
59010 +#define QMI_DEQ_CFG_PREFETCH_3_FRAMES 0x01000000
59011 +
59012 +#define QMI_DEQ_CFG_PRI 0x80000000
59013 +#define QMI_DEQ_CFG_TYPE1 0x10000000
59014 +#define QMI_DEQ_CFG_TYPE2 0x20000000
59015 +#define QMI_DEQ_CFG_TYPE3 0x30000000
59016 +
59017 +#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f
59018 +#define QMI_DEQ_CFG_SUBPORTAL_SHIFT 20
59019 +
59020 +/**************************************************************************//**
59021 + @Description PARSER defines
59022 +*//***************************************************************************/
59023 +/* masks */
59024 +#define PRS_HDR_ERROR_DIS 0x00000800
59025 +#define PRS_HDR_SW_PRS_EN 0x00000400
59026 +#define PRS_CP_OFFSET_MASK 0x0000000F
59027 +#define PRS_TPID1_MASK 0xFFFF0000
59028 +#define PRS_TPID2_MASK 0x0000FFFF
59029 +#define PRS_TPID_DFLT 0x91009100
59030 +
59031 +#define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000
59032 +#define PRS_HDR_IPV6_ROUTE_HDR_EN 0x00008000
59033 +#define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000
59034 +#define PRS_HDR_UDP_PAD_REMOVAL 0x80000000
59035 +#define PRS_HDR_TCP_PAD_REMOVAL 0x80000000
59036 +#define PRS_CAC_STOP 0x00000001
59037 +#define PRS_CAC_ACTIVE 0x00000100
59038 +
59039 +/* shifts */
59040 +#define PRS_PCTPID_SHIFT 16
59041 +#define PRS_HDR_MPLS_NEXT_HDR_SHIFT 22
59042 +#define PRS_HDR_ETH_BC_SHIFT 28
59043 +#define PRS_HDR_ETH_MC_SHIFT 24
59044 +#define PRS_HDR_VLAN_STACKED_SHIFT 16
59045 +#define PRS_HDR_MPLS_STACKED_SHIFT 16
59046 +#define PRS_HDR_IPV4_1_BC_SHIFT 28
59047 +#define PRS_HDR_IPV4_1_MC_SHIFT 24
59048 +#define PRS_HDR_IPV4_2_UC_SHIFT 20
59049 +#define PRS_HDR_IPV4_2_MC_BC_SHIFT 16
59050 +#define PRS_HDR_IPV6_1_MC_SHIFT 24
59051 +#define PRS_HDR_IPV6_2_UC_SHIFT 20
59052 +#define PRS_HDR_IPV6_2_MC_SHIFT 16
59053 +
59054 +#define PRS_HDR_ETH_BC_MASK 0x0fffffff
59055 +#define PRS_HDR_ETH_MC_MASK 0xf0ffffff
59056 +#define PRS_HDR_VLAN_STACKED_MASK 0xfff0ffff
59057 +#define PRS_HDR_MPLS_STACKED_MASK 0xfff0ffff
59058 +#define PRS_HDR_IPV4_1_BC_MASK 0x0fffffff
59059 +#define PRS_HDR_IPV4_1_MC_MASK 0xf0ffffff
59060 +#define PRS_HDR_IPV4_2_UC_MASK 0xff0fffff
59061 +#define PRS_HDR_IPV4_2_MC_BC_MASK 0xfff0ffff
59062 +#define PRS_HDR_IPV6_1_MC_MASK 0xf0ffffff
59063 +#define PRS_HDR_IPV6_2_UC_MASK 0xff0fffff
59064 +#define PRS_HDR_IPV6_2_MC_MASK 0xfff0ffff
59065 +
59066 +/* others */
59067 +#define PRS_HDR_ENTRY_SIZE 8
59068 +#define DEFAULT_CLS_PLAN_VECTOR 0xFFFFFFFF
59069 +
59070 +#define IPSEC_SW_PATCH_START 0x20
59071 +#define SCTP_SW_PATCH_START 0x4D
59072 +#define DCCP_SW_PATCH_START 0x41
59073 +
59074 +/**************************************************************************//**
59075 + @Description IM defines
59076 +*//***************************************************************************/
59077 +#define BD_R_E 0x80000000
59078 +#define BD_L 0x08000000
59079 +
59080 +#define BD_RX_CRE 0x00080000
59081 +#define BD_RX_FTL 0x00040000
59082 +#define BD_RX_FTS 0x00020000
59083 +#define BD_RX_OV 0x00010000
59084 +
59085 +#define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV)
59086 +
59087 +#define FM_IM_SIZEOF_BD sizeof(t_FmImBd)
59088 +
59089 +#define BD_STATUS_MASK 0xffff0000
59090 +#define BD_LENGTH_MASK 0x0000ffff
59091 +
59092 +#define BD_STATUS_AND_LENGTH_SET(bd, val) WRITE_UINT32(*(volatile uint32_t*)(bd), (val))
59093 +
59094 +#define BD_STATUS_AND_LENGTH(bd) GET_UINT32(*(volatile uint32_t*)(bd))
59095 +
59096 +#define BD_GET(id) &p_FmPort->im.p_BdRing[id]
59097 +
59098 +#define IM_ILEGAL_BD_ID 0xffff
59099 +
59100 +/* others */
59101 +#define IM_PRAM_ALIGN 0x100
59102 +
59103 +/* masks */
59104 +#define IM_MODE_GBL 0x20000000
59105 +#define IM_MODE_BO_MASK 0x18000000
59106 +#define IM_MODE_BO_SHIFT 3
59107 +#define IM_MODE_GRC_STP 0x00800000
59108 +
59109 +#define IM_MODE_SET_BO(val) (uint32_t)((val << (31-IM_MODE_BO_SHIFT)) & IM_MODE_BO_MASK)
59110 +
59111 +#define IM_RXQD_BSYINTM 0x0008
59112 +#define IM_RXQD_RXFINTM 0x0010
59113 +#define IM_RXQD_FPMEVT_SEL_MASK 0x0003
59114 +
59115 +#define IM_EV_BSY 0x40000000
59116 +#define IM_EV_RX 0x80000000
59117 +
59118 +
59119 +/**************************************************************************//**
59120 + @Description Additional defines
59121 +*//***************************************************************************/
59122 +
59123 +typedef struct {
59124 + t_Handle h_FmMuram;
59125 + t_FmPortImPram *p_FmPortImPram;
59126 + uint8_t fwExtStructsMemId;
59127 + uint32_t fwExtStructsMemAttr;
59128 + uint16_t bdRingSize;
59129 + t_FmImBd *p_BdRing;
59130 + t_Handle *p_BdShadow;
59131 + uint16_t currBdId;
59132 + uint16_t firstBdOfFrameId;
59133 +
59134 + /* Rx port parameters */
59135 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
59136 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
59137 + t_BufferPoolInfo rxPool;
59138 + uint16_t mrblr;
59139 + uint16_t rxFrameAccumLength;
59140 + t_FmPortImRxStoreCallback *f_RxStore;
59141 +
59142 + /* Tx port parameters */
59143 + uint32_t txFirstBdStatus;
59144 + t_FmPortImTxConfCallback *f_TxConf;
59145 +} t_FmMacIm;
59146 +
59147 +
59148 +typedef struct {
59149 + struct fman_port_cfg dfltCfg;
59150 + uint32_t dfltFqid;
59151 + uint32_t confFqid;
59152 + uint32_t errFqid;
59153 + uintptr_t baseAddr;
59154 + uint8_t deqSubPortal;
59155 + bool deqHighPriority;
59156 + e_FmPortDeqType deqType;
59157 + e_FmPortDeqPrefetchOption deqPrefetchOption;
59158 + uint16_t deqByteCnt;
59159 + uint8_t cheksumLastBytesIgnore;
59160 + uint8_t cutBytesFromEnd;
59161 + t_FmBufPoolDepletion bufPoolDepletion;
59162 + uint8_t pipelineDepth;
59163 + uint16_t fifoLowComfLevel;
59164 + bool frmDiscardOverride;
59165 + bool enRateLimit;
59166 + t_FmPortRateLimit rateLimit;
59167 + e_FmPortDualRateLimiterScaleDown rateLimitDivider;
59168 + bool enBufPoolDepletion;
59169 + uint16_t liodnOffset;
59170 + uint16_t liodnBase;
59171 + t_FmExtPools extBufPools;
59172 + e_FmDmaSwapOption dmaSwapData;
59173 + e_FmDmaCacheOption dmaIntContextCacheAttr;
59174 + e_FmDmaCacheOption dmaHeaderCacheAttr;
59175 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
59176 + bool dmaReadOptimize;
59177 + bool dmaWriteOptimize;
59178 + uint32_t txFifoMinFillLevel;
59179 + uint32_t txFifoLowComfLevel;
59180 + uint32_t rxFifoPriElevationLevel;
59181 + uint32_t rxFifoThreshold;
59182 + t_FmSpBufMargins bufMargins;
59183 + t_FmSpIntContextDataCopy intContext;
59184 + bool syncReq;
59185 + e_FmPortColor color;
59186 + fmPortFrameErrSelect_t errorsToDiscard;
59187 + fmPortFrameErrSelect_t errorsToEnq;
59188 + bool forwardReuseIntContext;
59189 + t_FmBufferPrefixContent bufferPrefixContent;
59190 + t_FmBackupBmPools *p_BackupBmPools;
59191 + bool dontReleaseBuf;
59192 + bool setNumOfTasks;
59193 + bool setNumOfOpenDmas;
59194 + bool setSizeOfFifo;
59195 +#if (DPAA_VERSION >= 11)
59196 + bool noScatherGather;
59197 +#endif /* (DPAA_VERSION >= 11) */
59198 +
59199 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
59200 + bool bcbWorkaround;
59201 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
59202 +} t_FmPortDriverParam;
59203 +
59204 +
59205 +typedef struct t_FmPortRxPoolsParams
59206 +{
59207 + uint8_t numOfPools;
59208 + uint16_t secondLargestBufSize;
59209 + uint16_t largestBufSize;
59210 +} t_FmPortRxPoolsParams;
59211 +
59212 +typedef struct t_FmPortDsarVars {
59213 + t_Handle *autoResOffsets;
59214 + t_FmPortDsarTablesSizes *autoResMaxSizes;
59215 + uint32_t fmbm_tcfg;
59216 + uint32_t fmbm_tcmne;
59217 + uint32_t fmbm_rfne;
59218 + uint32_t fmbm_rfpne;
59219 + uint32_t fmbm_rcfg;
59220 + bool dsarEnabledParser;
59221 +} t_FmPortDsarVars;
59222 +typedef struct {
59223 + struct fman_port port;
59224 + t_Handle h_Fm;
59225 + t_Handle h_FmPcd;
59226 + t_Handle h_FmMuram;
59227 + t_FmRevisionInfo fmRevInfo;
59228 + uint8_t portId;
59229 + e_FmPortType portType;
59230 + int enabled;
59231 + char name[MODULE_NAME_SIZE];
59232 + uint8_t hardwarePortId;
59233 + uint16_t fmClkFreq;
59234 + t_FmPortQmiRegs *p_FmPortQmiRegs;
59235 + u_FmPortBmiRegs *p_FmPortBmiRegs;
59236 + t_FmPortPrsRegs *p_FmPortPrsRegs;
59237 + fmPcdEngines_t pcdEngines;
59238 + uint32_t savedBmiNia;
59239 + uint8_t netEnvId;
59240 + uint32_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
59241 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
59242 + uint8_t privateInfo;
59243 + uint32_t schemesPerPortVector;
59244 + bool useClsPlan;
59245 + uint8_t clsPlanGrpId;
59246 + t_Handle ccTreeId;
59247 + t_Handle completeArg;
59248 + void (*f_Complete)(t_Handle arg);
59249 + t_FmSpBufferOffsets bufferOffsets;
59250 + /* Independent-Mode parameters support */
59251 + bool imEn;
59252 + t_FmMacIm im;
59253 + volatile bool lock;
59254 + t_Handle h_Spinlock;
59255 + t_FmPortExceptionCallback *f_Exception;
59256 + t_Handle h_App;
59257 + uint8_t internalBufferOffset;
59258 + uint8_t fmanCtrlEventId;
59259 + uint32_t exceptions;
59260 + bool polling;
59261 + t_FmExtPools extBufPools;
59262 + uint32_t requiredAction;
59263 + uint32_t savedQmiPnen;
59264 + uint32_t savedBmiFene;
59265 + uint32_t savedBmiFpne;
59266 + uint32_t savedBmiCmne;
59267 + uint32_t savedBmiOfp;
59268 + uint32_t savedNonRxQmiRegsPndn;
59269 + uint32_t origNonRxQmiRegsPndn;
59270 + int savedPrsStartOffset;
59271 + bool includeInPrsStatistics;
59272 + uint16_t maxFrameLength;
59273 + t_FmFmanCtrl orFmanCtrl;
59274 + t_FmPortRsrc openDmas;
59275 + t_FmPortRsrc tasks;
59276 + t_FmPortRsrc fifoBufs;
59277 + t_FmPortRxPoolsParams rxPoolsParams;
59278 +// bool explicitUserSizeOfFifo;
59279 + t_Handle h_IpReassemblyManip;
59280 + t_Handle h_CapwapReassemblyManip;
59281 + t_Handle h_ReassemblyTree;
59282 + uint64_t fmMuramPhysBaseAddr;
59283 +#if (DPAA_VERSION >= 11)
59284 + bool vspe;
59285 + uint8_t dfltRelativeId;
59286 + e_FmPortGprFuncType gprFunc;
59287 + t_FmPcdCtrlParamsPage *p_ParamsPage;
59288 +#endif /* (DPAA_VERSION >= 11) */
59289 + t_FmPortDsarVars deepSleepVars;
59290 + t_FmPortDriverParam *p_FmPortDriverParam;
59291 +} t_FmPort;
59292 +
59293 +
59294 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams);
59295 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort);
59296 +
59297 +t_Error FmPortImInit(t_FmPort *p_FmPort);
59298 +void FmPortImFree(t_FmPort *p_FmPort);
59299 +
59300 +t_Error FmPortImEnable (t_FmPort *p_FmPort);
59301 +t_Error FmPortImDisable (t_FmPort *p_FmPort);
59302 +t_Error FmPortImRx (t_FmPort *p_FmPort);
59303 +
59304 +void FmPortSetMacsecLcv(t_Handle h_FmPort);
59305 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci);
59306 +
59307 +
59308 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas);
59309 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
59310 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
59311 +
59312 +static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd)
59313 +{
59314 + uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32);
59315 + physAddr |= GET_UINT32(p_Bd->buff.low);
59316 +
59317 + return (uint8_t *)f_PhysToVirt((physAddress_t)(physAddr));
59318 +}
59319 +
59320 +static __inline__ void SET_ADDR(volatile t_FmPhysAddr *fmPhysAddr, uint64_t value)
59321 +{
59322 + WRITE_UINT8(fmPhysAddr->high,(uint8_t)((value & 0x000000ff00000000LL) >> 32));
59323 + WRITE_UINT32(fmPhysAddr->low,(uint32_t)value);
59324 +}
59325 +
59326 +static __inline__ void BdBufferSet(t_VirtToPhys *f_VirtToPhys, t_FmImBd *p_Bd, uint8_t *p_Buffer)
59327 +{
59328 + uint64_t physAddr = (uint64_t)(f_VirtToPhys(p_Buffer));
59329 + SET_ADDR(&p_Bd->buff, physAddr);
59330 +}
59331 +
59332 +static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id)
59333 +{
59334 + if (id < p_FmPort->im.bdRingSize-1)
59335 + return (uint16_t)(id+1);
59336 + else
59337 + return 0;
59338 +}
59339 +
59340 +void FM_PORT_Dsar_DumpRegs(void);
59341 +
59342 +
59343 +#endif /* __FM_PORT_H */
59344 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
59345 new file mode 100755
59346 index 00000000..95619eff
59347 --- /dev/null
59348 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
59349 @@ -0,0 +1,494 @@
59350 +/*
59351 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59352 + *
59353 + * Redistribution and use in source and binary forms, with or without
59354 + * modification, are permitted provided that the following conditions are met:
59355 + * * Redistributions of source code must retain the above copyright
59356 + * notice, this list of conditions and the following disclaimer.
59357 + * * Redistributions in binary form must reproduce the above copyright
59358 + * notice, this list of conditions and the following disclaimer in the
59359 + * documentation and/or other materials provided with the distribution.
59360 + * * Neither the name of Freescale Semiconductor nor the
59361 + * names of its contributors may be used to endorse or promote products
59362 + * derived from this software without specific prior written permission.
59363 + *
59364 + *
59365 + * ALTERNATIVELY, this software may be distributed under the terms of the
59366 + * GNU General Public License ("GPL") as published by the Free Software
59367 + * Foundation, either version 2 of that License or (at your option) any
59368 + * later version.
59369 + *
59370 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59371 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59372 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59373 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59374 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59375 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59376 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59377 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59378 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59379 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59380 + */
59381 +
59382 +/**************************************************************************//**
59383 + @File fm_port_dsar.h
59384 +
59385 + @Description Deep Sleep Auto Response project - common module header file.
59386 +
59387 + Author - Eyal Harari
59388 +
59389 + @Cautions See the FMan Controller spec and design document for more information.
59390 +*//***************************************************************************/
59391 +
59392 +#ifndef __FM_PORT_DSAR_H_
59393 +#define __FM_PORT_DSAR_H_
59394 +
59395 +#define DSAR_GETSER_MASK 0xFF0000FF
59396 +
59397 +#if defined(__MWERKS__) && !defined(__GNUC__)
59398 +#pragma pack(push,1)
59399 +#endif /* defined(__MWERKS__) && ... */
59400 +
59401 +/**************************************************************************//**
59402 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59403 + Refer to the FMan Controller spec for more details.
59404 +*//***************************************************************************/
59405 +typedef _Packed struct
59406 +{
59407 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59408 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59409 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59410 + uint16_t reserved;
59411 +} _PackedType t_DsarArpBindingEntry;
59412 +
59413 +/**************************************************************************//**
59414 + @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor
59415 + Refer to the FMan Controller spec for more details.
59416 + 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter
59417 + 0x04 ECHO_CNT Echo counter
59418 + 0x08 CD_CNT Conflict Detection counter
59419 + 0x0C AR_CNT Auto-Response counter
59420 + 0x10 RATM_CNT Replies Addressed To Me counter
59421 + 0x14 UKOP_CNT Unknown Operation counter
59422 + 0x18 NMTP_CNT Not my TPA counter
59423 + 0x1C NMVLAN_CNT Not My VLAN counter
59424 +*//***************************************************************************/
59425 +typedef _Packed struct
59426 +{
59427 + uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */
59428 + uint32_t echoCnt; /**< Echo counter. */
59429 + uint32_t cdCnt; /**< Conflict Detection counter. */
59430 + uint32_t arCnt; /**< Auto-Response counter. */
59431 + uint32_t ratmCnt; /**< Replies Addressed To Me counter. */
59432 + uint32_t ukopCnt; /**< Unknown Operation counter. */
59433 + uint32_t nmtpCnt; /**< Not my TPA counter. */
59434 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59435 +} _PackedType t_DsarArpStatistics;
59436 +
59437 +
59438 +/**************************************************************************//**
59439 + @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor
59440 + 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN.
59441 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59442 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list.
59443 + 0x6 0-15
59444 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure.
59445 + 0xA 0-15
59446 + 0xC 0-15 Reserved Reserved. Must be cleared.
59447 + 0xE 015
59448 +
59449 +*//***************************************************************************/
59450 +typedef _Packed struct
59451 +{
59452 + uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */
59453 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59454 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59455 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59456 + uint32_t reserved1; /**< Reserved. */
59457 +} _PackedType t_DsarArpDescriptor;
59458 +
59459 +
59460 +/**************************************************************************//**
59461 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59462 + Refer to the FMan Controller spec for more details.
59463 +*//***************************************************************************/
59464 +typedef _Packed struct
59465 +{
59466 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59467 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59468 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59469 + uint16_t reserved;
59470 +} _PackedType t_DsarIcmpV4BindingEntry;
59471 +
59472 +/**************************************************************************//**
59473 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59474 + Refer to the FMan Controller spec for more details.
59475 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59476 + 0x04 NMVLAN_CNT Not My VLAN counter
59477 + 0x08 NMIP_CNT Not My IP counter
59478 + 0x0C AR_CNT Auto-Response counter
59479 + 0x10 CSERR_CNT Checksum Error counter
59480 + 0x14 Reserved Reserved
59481 + 0x18 Reserved Reserved
59482 + 0x1C Reserved Reserved
59483 +
59484 +*//***************************************************************************/
59485 +typedef _Packed struct
59486 +{
59487 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59488 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59489 + uint32_t nmIpCnt; /**< Not My IP counter */
59490 + uint32_t arCnt; /**< Auto-Response counter */
59491 + uint32_t cserrCnt; /**< Checksum Error counter */
59492 + uint32_t reserved0; /**< Reserved */
59493 + uint32_t reserved1; /**< Reserved */
59494 + uint32_t reserved2; /**< Reserved */
59495 +} _PackedType t_DsarIcmpV4Statistics;
59496 +
59497 +
59498 +
59499 +/**************************************************************************//**
59500 + @Description Deep Sleep Auto Response ICMPv4 Descriptor
59501 + 0x0 0-15 Control bits [0-15]
59502 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59503 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59504 + 0x6 0-15
59505 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59506 + 0xA 0-15
59507 + 0xC 0-15 Reserved Reserved. Must be cleared.
59508 + 0xE 015
59509 +
59510 +*//***************************************************************************/
59511 +typedef _Packed struct
59512 +{
59513 + uint16_t control; /** Control bits [0-15]. */
59514 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59515 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59516 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59517 + uint32_t reserved1; /**< Reserved. */
59518 +} _PackedType t_DsarIcmpV4Descriptor;
59519 +
59520 +/**************************************************************************//**
59521 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59522 + The 4 left-most bits (15:12) of the VlanId parameter are control flags.
59523 + Flags[3:1] (VlanId[15:13]): Reserved, should be cleared.
59524 + Flags[0] (VlanId[12]): Temporary address.
59525 + \95 0 - Assigned IP address.
59526 + \95 1- Temporary (tentative) IP address.
59527 + Refer to the FMan Controller spec for more details.
59528 +*//***************************************************************************/
59529 +typedef _Packed struct
59530 +{
59531 + uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */
59532 + uint16_t resFlags:4; /*!< reserved flags. should be cleared */
59533 + uint16_t vlanId:12; /*!< 12 bits VLAN ID. */
59534 + /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */
59535 + uint16_t reserved;
59536 +} _PackedType t_DsarIcmpV6BindingEntry;
59537 +
59538 +/**************************************************************************//**
59539 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59540 + Refer to the FMan Controller spec for more details.
59541 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59542 + 0x04 NMVLAN_CNT Not My VLAN counter
59543 + 0x08 NMIP_CNT Not My IP counter
59544 + 0x0C AR_CNT Auto-Response counter
59545 + 0x10 CSERR_CNT Checksum Error counter
59546 + 0x14 MCAST_CNT Multicast counter
59547 + 0x18 Reserved Reserved
59548 + 0x1C Reserved Reserved
59549 +
59550 +*//***************************************************************************/
59551 +typedef _Packed struct
59552 +{
59553 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59554 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59555 + uint32_t nmIpCnt; /**< Not My IP counter */
59556 + uint32_t arCnt; /**< Auto-Response counter */
59557 + uint32_t reserved1; /**< Reserved */
59558 + uint32_t reserved2; /**< Reserved */
59559 + uint32_t reserved3; /**< Reserved */
59560 + uint32_t reserved4; /**< Reserved */
59561 +} _PackedType t_DsarIcmpV6Statistics;
59562 +
59563 +/**************************************************************************//**
59564 + @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor
59565 + 0x00 INVAL_CNT Invalid Neighbor Discovery message counter
59566 + 0x04 NMVLAN_CNT Not My VLAN counter
59567 + 0x08 NMIP_CNT Not My IP counter
59568 + 0x0C AR_CNT Auto-Response counter
59569 + 0x10 CSERR_CNT Checksum Error counter
59570 + 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter
59571 + 0x18 NMMCAST_CNT Not My Multicast group counter
59572 + 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target
59573 + Address of a packet that its source IP address is a unicast address, but the ICMPv6
59574 + Source Link-layer Address option is omitted
59575 +*//***************************************************************************/
59576 +typedef _Packed struct
59577 +{
59578 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59579 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59580 + uint32_t nmIpCnt; /**< Not My IP counter */
59581 + uint32_t arCnt; /**< Auto-Response counter */
59582 + uint32_t reserved1; /**< Reserved */
59583 + uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */
59584 + uint32_t nmmcastCnt; /**< Not My Multicast group counter */
59585 + uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */
59586 +} _PackedType t_NdStatistics;
59587 +
59588 +/**************************************************************************//**
59589 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59590 + 0x0 0-15 Control bits [0-15]
59591 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59592 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59593 + 0x6 0-15
59594 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59595 + 0xA 0-15
59596 + 0xC 0-15 Reserved Reserved. Must be cleared.
59597 + 0xE 015
59598 +
59599 +*//***************************************************************************/
59600 +typedef _Packed struct
59601 +{
59602 + uint16_t control; /** Control bits [0-15]. */
59603 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59604 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59605 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59606 + uint32_t reserved1; /**< Reserved. */
59607 +} _PackedType t_DsarIcmpV6Descriptor;
59608 +
59609 +
59610 +/**************************************************************************//**
59611 + @Description Internet Control Message Protocol (ICMPv6) Echo message header
59612 + The fields names are taken from RFC 4443.
59613 +*//***************************************************************************/
59614 +/* 0 1 2 3 */
59615 +/* 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 */
59616 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59617 +/* | Type | Code | Checksum | */
59618 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59619 +/* | Identifier | Sequence Number | */
59620 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59621 +/* | Data ... */
59622 +/* +-+-+-+-+- */
59623 +typedef _Packed struct
59624 +{
59625 + uint8_t type;
59626 + uint8_t code;
59627 + uint16_t checksum;
59628 + uint16_t identifier;
59629 + uint16_t sequenceNumber;
59630 +} _PackedType t_IcmpV6EchoHdr;
59631 +
59632 +/**************************************************************************//**
59633 + @Description Internet Control Message Protocol (ICMPv6)
59634 + Neighbor Solicitation/Advertisement header
59635 + The fields names are taken from RFC 4861.
59636 + The R/S/O fields are valid for Neighbor Advertisement only
59637 +*//***************************************************************************/
59638 +/* 0 1 2 3
59639 + * 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
59640 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59641 + * | Type | Code | Checksum |
59642 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59643 + * |R|S|O| Reserved |
59644 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59645 + * | |
59646 + * + +
59647 + * | |
59648 + * + Target Address +
59649 + * | |
59650 + * + +
59651 + * | |
59652 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59653 + * | Options ...
59654 + * +-+-+-+-+-+-+-+-+-+-+-+-
59655 + *
59656 + * Options Format:
59657 + * 0 1 2 3
59658 + * 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
59659 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59660 + * | Type | Length | Link-Layer Address ... |
59661 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59662 + * | Link-Layer Address |
59663 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59664 +*/
59665 +typedef _Packed struct
59666 +{
59667 + uint8_t type;
59668 + uint8_t code;
59669 + uint16_t checksum;
59670 + uint32_t router:1;
59671 + uint32_t solicited:1;
59672 + uint32_t override:1;
59673 + uint32_t reserved:29;
59674 + uint32_t targetAddr[4];
59675 + uint8_t optionType;
59676 + uint8_t optionLength;
59677 + uint8_t linkLayerAddr[6];
59678 +} _PackedType t_IcmpV6NdHdr;
59679 +
59680 +/**************************************************************************//**
59681 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59682 + 0x0 0-15 Control bits [0-15]
59683 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59684 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59685 + 0x6 0-15
59686 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59687 + 0xA 0-15
59688 + 0xC 0-15 Reserved Reserved. Must be cleared.
59689 + 0xE 015
59690 +
59691 +*//***************************************************************************/
59692 +typedef _Packed struct
59693 +{
59694 + uint16_t control; /** Control bits [0-15]. */
59695 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59696 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59697 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59698 + uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */
59699 +} _PackedType t_DsarNdDescriptor;
59700 +
59701 +/**************************************************************************//**
59702 +@Description Deep Sleep Auto Response SNMP OIDs table entry
59703 +
59704 +*//***************************************************************************/
59705 +typedef struct {
59706 + uint16_t oidSize; /**< Size in octets of the OID. */
59707 + uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */
59708 + uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */
59709 + uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */
59710 + uint32_t reserved;
59711 +} t_OidsTblEntry;
59712 +
59713 +/**************************************************************************//**
59714 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
59715 + Refer to the FMan Controller spec for more details.
59716 +*//***************************************************************************/
59717 +typedef struct
59718 +{
59719 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59720 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59721 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59722 + uint16_t reserved;
59723 +} t_DsarSnmpIpv4AddrTblEntry;
59724 +
59725 +/**************************************************************************//**
59726 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
59727 + Refer to the FMan Controller spec for more details.
59728 +*//***************************************************************************/
59729 +#pragma pack(push,1)
59730 +typedef struct
59731 +{
59732 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
59733 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59734 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59735 + uint16_t reserved;
59736 +} t_DsarSnmpIpv6AddrTblEntry;
59737 +#pragma pack(pop)
59738 +
59739 +/**************************************************************************//**
59740 +@Description Deep Sleep Auto Response SNMP statistics table
59741 +
59742 +*//***************************************************************************/
59743 +typedef struct {
59744 + uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */
59745 + uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */
59746 + uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */
59747 + uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */
59748 + uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */
59749 +} t_DsarSnmpStatistics;
59750 +
59751 +/**************************************************************************//**
59752 + @Description Deep Sleep Auto Response SNMP Descriptor
59753 +
59754 +*//***************************************************************************/
59755 +typedef struct
59756 +{
59757 + uint16_t control; /**< Control bits [0-15]. */
59758 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
59759 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
59760 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
59761 + uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
59762 + uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
59763 + uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
59764 + uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
59765 + uint32_t p_OidsTbl; /**< Pointer to OIDs table. */
59766 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
59767 + uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */
59768 +} t_DsarSnmpDescriptor;
59769 +
59770 +/**************************************************************************//**
59771 +@Description Deep Sleep Auto Response (Common) Statistics
59772 +
59773 +*//***************************************************************************/
59774 +typedef _Packed struct {
59775 + uint32_t dsarDiscarded;
59776 + uint32_t dsarErrDiscarded;
59777 + uint32_t dsarFragDiscarded;
59778 + uint32_t dsarTunnelDiscarded;
59779 + uint32_t dsarArpDiscarded;
59780 + uint32_t dsarIpDiscarded;
59781 + uint32_t dsarTcpDiscarded;
59782 + uint32_t dsarUdpDiscarded;
59783 + uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */
59784 + uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */
59785 + uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */
59786 +} _PackedType t_ArStatistics;
59787 +
59788 +
59789 +/**************************************************************************//**
59790 +@Description Deep Sleep Auto Response TCP/UDP port filter table entry
59791 +
59792 +*//***************************************************************************/
59793 +typedef _Packed struct {
59794 + uint32_t Ports;
59795 + uint32_t PortsMask;
59796 +} _PackedType t_PortTblEntry;
59797 +
59798 +
59799 +
59800 +/**************************************************************************//**
59801 +@Description Deep Sleep Auto Response Common Parameters Descriptor
59802 +
59803 +*//***************************************************************************/
59804 +typedef _Packed struct {
59805 + uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */
59806 + uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */
59807 + uint16_t res1; /* 0x00 16-31 Reserved */
59808 + uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */
59809 + uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */
59810 + uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */
59811 + uint8_t res2; /* 0x10 0-7 Reserved */
59812 + uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */
59813 + uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */
59814 + uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */
59815 + uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */
59816 + uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */
59817 + uint8_t res3; /* 0x14 24-31 Reserved */
59818 + uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */
59819 + uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */
59820 + uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */
59821 + uint32_t res4; /* 0x24 Reserved */
59822 + uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */
59823 + uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */
59824 + uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */
59825 + uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */
59826 + uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */
59827 + uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */
59828 +} _PackedType t_ArCommonDesc;
59829 +
59830 +#if defined(__MWERKS__) && !defined(__GNUC__)
59831 +#pragma pack(pop)
59832 +#endif /* defined(__MWERKS__) && ... */
59833 +
59834 +/* t_ArCommonDesc.filterControl bits */
59835 +#define IP_PROT_TBL_PASS_MASK 0x08
59836 +#define UDP_PORT_TBL_PASS_MASK 0x04
59837 +#define TCP_PORT_TBL_PASS_MASK 0x02
59838 +
59839 +/* Offset of TCF flags within TCP packet */
59840 +#define TCP_FLAGS_OFFSET 12
59841 +
59842 +
59843 +#endif /* __FM_PORT_DSAR_H_ */
59844 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
59845 new file mode 100644
59846 index 00000000..8de8f5fd
59847 --- /dev/null
59848 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
59849 @@ -0,0 +1,753 @@
59850 +/*
59851 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59852 + *
59853 + * Redistribution and use in source and binary forms, with or without
59854 + * modification, are permitted provided that the following conditions are met:
59855 + * * Redistributions of source code must retain the above copyright
59856 + * notice, this list of conditions and the following disclaimer.
59857 + * * Redistributions in binary form must reproduce the above copyright
59858 + * notice, this list of conditions and the following disclaimer in the
59859 + * documentation and/or other materials provided with the distribution.
59860 + * * Neither the name of Freescale Semiconductor nor the
59861 + * names of its contributors may be used to endorse or promote products
59862 + * derived from this software without specific prior written permission.
59863 + *
59864 + *
59865 + * ALTERNATIVELY, this software may be distributed under the terms of the
59866 + * GNU General Public License ("GPL") as published by the Free Software
59867 + * Foundation, either version 2 of that License or (at your option) any
59868 + * later version.
59869 + *
59870 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59871 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59872 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59873 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59874 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59875 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59876 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59877 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59878 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59879 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59880 + */
59881 +
59882 +
59883 +/******************************************************************************
59884 + @File fm_port_im.c
59885 +
59886 + @Description FM Port Independent-Mode ...
59887 +*//***************************************************************************/
59888 +#include "std_ext.h"
59889 +#include "string_ext.h"
59890 +#include "error_ext.h"
59891 +#include "memcpy_ext.h"
59892 +#include "fm_muram_ext.h"
59893 +
59894 +#include "fm_port.h"
59895 +
59896 +
59897 +#define TX_CONF_STATUS_UNSENT 0x1
59898 +
59899 +
59900 +typedef enum e_TxConfType
59901 +{
59902 + e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */
59903 + ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */
59904 + ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */
59905 +} e_TxConfType;
59906 +
59907 +
59908 +static void ImException(t_Handle h_FmPort, uint32_t event)
59909 +{
59910 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59911 +
59912 + ASSERT_COND(((event & (IM_EV_RX | IM_EV_BSY)) && FmIsMaster(p_FmPort->h_Fm)) ||
59913 + !FmIsMaster(p_FmPort->h_Fm));
59914 +
59915 + if (event & IM_EV_RX)
59916 + FmPortImRx(p_FmPort);
59917 + if ((event & IM_EV_BSY) && p_FmPort->f_Exception)
59918 + p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY);
59919 +}
59920 +
59921 +
59922 +static t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType)
59923 +{
59924 + t_Error retVal = E_BUSY;
59925 + uint32_t bdStatus;
59926 + uint16_t savedStartBdId, confBdId;
59927 +
59928 + ASSERT_COND(p_FmPort);
59929 +
59930 + /*
59931 + if (confType==e_TX_CONF_TYPE_CHECK)
59932 + return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY);
59933 + */
59934 +
59935 + confBdId = savedStartBdId = p_FmPort->im.currBdId;
59936 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59937 +
59938 + /* If R bit is set, we don't enter, or we break.
59939 + we run till we get to R, or complete the loop */
59940 + while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK))
59941 + {
59942 + if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */
59943 + BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0);
59944 +
59945 + /* case 1: R bit is 0 and Length is set -> confirm! */
59946 + if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK))
59947 + {
59948 + if (p_FmPort->im.f_TxConf)
59949 + {
59950 + if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E))
59951 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59952 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59953 + TX_CONF_STATUS_UNSENT,
59954 + p_FmPort->im.p_BdShadow[confBdId]);
59955 + else
59956 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59957 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59958 + 0,
59959 + p_FmPort->im.p_BdShadow[confBdId]);
59960 + }
59961 + }
59962 + /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */
59963 +
59964 + confBdId = GetNextBdId(p_FmPort, confBdId);
59965 + if (confBdId == savedStartBdId)
59966 + retVal = E_OK;
59967 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59968 + }
59969 +
59970 + return retVal;
59971 +}
59972 +
59973 +t_Error FmPortImEnable(t_FmPort *p_FmPort)
59974 +{
59975 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59976 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP));
59977 + return E_OK;
59978 +}
59979 +
59980 +t_Error FmPortImDisable(t_FmPort *p_FmPort)
59981 +{
59982 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59983 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP));
59984 + return E_OK;
59985 +}
59986 +
59987 +t_Error FmPortImRx(t_FmPort *p_FmPort)
59988 +{
59989 + t_Handle h_CurrUserPriv, h_NewUserPriv;
59990 + uint32_t bdStatus;
59991 + volatile uint8_t buffPos;
59992 + uint16_t length;
59993 + uint16_t errors;
59994 + uint8_t *p_CurData, *p_Data;
59995 + uint32_t flags;
59996 +
59997 + ASSERT_COND(p_FmPort);
59998 +
59999 + flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock);
60000 + if (p_FmPort->lock)
60001 + {
60002 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
60003 + return E_OK;
60004 + }
60005 + p_FmPort->lock = TRUE;
60006 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
60007 +
60008 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60009 +
60010 + while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */
60011 + {
60012 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL)
60013 + {
60014 + p_FmPort->lock = FALSE;
60015 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
60016 + }
60017 +
60018 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
60019 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
60020 +
60021 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
60022 + h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId];
60023 + length = (uint16_t)((bdStatus & BD_L) ?
60024 + ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength):
60025 + (bdStatus & BD_LENGTH_MASK));
60026 + p_FmPort->im.rxFrameAccumLength += length;
60027 +
60028 + /* determine whether buffer is first, last, first and last (single */
60029 + /* buffer frame) or middle (not first and not last) */
60030 + buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ?
60031 + ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) :
60032 + ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF));
60033 +
60034 + if (bdStatus & BD_L)
60035 + {
60036 + p_FmPort->im.rxFrameAccumLength = 0;
60037 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60038 + }
60039 +
60040 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
60041 +
60042 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E);
60043 +
60044 + errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16);
60045 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv;
60046 +
60047 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60048 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4));
60049 + /* Pass the buffer if one of the conditions is true:
60050 + - There are no errors
60051 + - This is a part of a larger frame ( the application has already received some buffers ) */
60052 + if ((buffPos != SINGLE_BUF) || !errors)
60053 + {
60054 + if (p_FmPort->im.f_RxStore(p_FmPort->h_App,
60055 + p_CurData,
60056 + length,
60057 + errors,
60058 + buffPos,
60059 + h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE)
60060 + break;
60061 + }
60062 + else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
60063 + p_CurData,
60064 + h_CurrUserPriv))
60065 + {
60066 + p_FmPort->lock = FALSE;
60067 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer"));
60068 + }
60069 +
60070 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60071 + }
60072 + p_FmPort->lock = FALSE;
60073 + return E_OK;
60074 +}
60075 +
60076 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams)
60077 +{
60078 + ASSERT_COND(p_FmPort);
60079 +
60080 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60081 +
60082 + p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram;
60083 + p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset;
60084 + p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId;
60085 + p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes;
60086 +
60087 + p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId;
60088 + p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr;
60089 +
60090 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60091 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60092 + {
60093 + p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool;
60094 + p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf;
60095 + p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf;
60096 + p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize;
60097 + p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt;
60098 + if (!p_FmPort->im.rxPool.f_PhysToVirt)
60099 + p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt;
60100 + p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys;
60101 + if (!p_FmPort->im.rxPool.f_VirtToPhys)
60102 + p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys;
60103 + p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore;
60104 +
60105 + p_FmPort->im.mrblr = 0x8000;
60106 + while (p_FmPort->im.mrblr)
60107 + {
60108 + if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr)
60109 + break;
60110 + p_FmPort->im.mrblr >>= 1;
60111 + }
60112 + if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize)
60113 + DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr));
60114 + p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength;
60115 + p_FmPort->exceptions = DEFAULT_PORT_exception;
60116 + if (FmIsMaster(p_FmPort->h_Fm))
60117 + p_FmPort->polling = FALSE;
60118 + else
60119 + p_FmPort->polling = TRUE;
60120 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60121 + }
60122 + else
60123 + {
60124 + p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf;
60125 +
60126 + p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength;
60127 + }
60128 +}
60129 +
60130 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort)
60131 +{
60132 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) &&
60133 + (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
60134 + (p_FmPort->portType != e_FM_PORT_TYPE_TX) &&
60135 + (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
60136 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
60137 +
60138 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60139 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60140 + {
60141 + if (!POWER_OF_2(p_FmPort->im.mrblr))
60142 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!"));
60143 + if (p_FmPort->im.mrblr < 256)
60144 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!"));
60145 + if (p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK)
60146 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
60147 + }
60148 +
60149 + return E_OK;
60150 +}
60151 +
60152 +t_Error FmPortImInit(t_FmPort *p_FmPort)
60153 +{
60154 + t_FmImBd *p_Bd=NULL;
60155 + t_Handle h_BufContext;
60156 + uint64_t tmpPhysBase;
60157 + uint16_t log2Num;
60158 + uint8_t *p_Data/*, *p_Tmp*/;
60159 + int i;
60160 + t_Error err;
60161 + uint16_t tmpReg16;
60162 + uint32_t tmpReg32;
60163 +
60164 + ASSERT_COND(p_FmPort);
60165 +
60166 + p_FmPort->im.p_FmPortImPram =
60167 + (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN);
60168 + if (!p_FmPort->im.p_FmPortImPram)
60169 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!"));
60170 + WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram));
60171 +
60172 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60173 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60174 + {
60175 + p_FmPort->im.p_BdRing =
60176 + (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize),
60177 + p_FmPort->im.fwExtStructsMemId,
60178 + 4);
60179 + if (!p_FmPort->im.p_BdRing)
60180 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!"));
60181 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60182 +
60183 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60184 + if (!p_FmPort->im.p_BdShadow)
60185 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
60186 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60187 +
60188 + /* Initialize the Rx-BD ring */
60189 + for (i=0; i<p_FmPort->im.bdRingSize; i++)
60190 + {
60191 + p_Bd = BD_GET(i);
60192 + BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E);
60193 +
60194 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL)
60195 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
60196 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data);
60197 + p_FmPort->im.p_BdShadow[i] = h_BufContext;
60198 + }
60199 +
60200 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
60201 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
60202 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
60203 + else
60204 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
60205 +
60206 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr,
60207 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60208 + p_FmPort->fmMuramPhysBaseAddr + 0x20));
60209 +
60210 + LOG2((uint64_t)p_FmPort->im.mrblr, log2Num);
60211 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num);
60212 +
60213 + /* Initialize Rx QD */
60214 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
60215 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase);
60216 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60217 +
60218 + /* Update the IM PRAM address in the BMI */
60219 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid,
60220 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60221 + p_FmPort->fmMuramPhysBaseAddr));
60222 + if (!p_FmPort->polling || p_FmPort->exceptions)
60223 + {
60224 + /* Allocate, configure and register interrupts */
60225 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
60226 + if (err)
60227 + RETURN_ERROR(MAJOR, err, NO_MSG);
60228 +
60229 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
60230 + tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK);
60231 + tmpReg32 = 0;
60232 +
60233 + if (p_FmPort->exceptions & IM_EV_BSY)
60234 + {
60235 + tmpReg16 |= IM_RXQD_BSYINTM;
60236 + tmpReg32 |= IM_EV_BSY;
60237 + }
60238 + if (!p_FmPort->polling)
60239 + {
60240 + tmpReg16 |= IM_RXQD_RXFINTM;
60241 + tmpReg32 |= IM_EV_RX;
60242 + }
60243 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60244 +
60245 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort);
60246 +
60247 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60248 + }
60249 + else
60250 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60251 + }
60252 + else
60253 + {
60254 + p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4);
60255 + if (!p_FmPort->im.p_BdRing)
60256 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!"));
60257 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60258 +
60259 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60260 + if (!p_FmPort->im.p_BdShadow)
60261 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
60262 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60263 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60264 +
60265 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
60266 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
60267 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
60268 + else
60269 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
60270 +
60271 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr,
60272 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60273 + p_FmPort->fmMuramPhysBaseAddr + 0x40));
60274 +
60275 + /* Initialize Tx QD */
60276 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
60277 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase);
60278 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60279 +
60280 + /* Update the IM PRAM address in the BMI */
60281 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid,
60282 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60283 + p_FmPort->fmMuramPhysBaseAddr));
60284 + }
60285 +
60286 +
60287 + return E_OK;
60288 +}
60289 +
60290 +void FmPortImFree(t_FmPort *p_FmPort)
60291 +{
60292 + uint32_t bdStatus;
60293 + uint8_t *p_CurData;
60294 +
60295 + ASSERT_COND(p_FmPort);
60296 + ASSERT_COND(p_FmPort->im.p_FmPortImPram);
60297 +
60298 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60299 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60300 + {
60301 + if (!p_FmPort->polling || p_FmPort->exceptions)
60302 + {
60303 + /* Deallocate and unregister interrupts */
60304 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60305 +
60306 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60307 +
60308 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60309 +
60310 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60311 + }
60312 + /* Try first clean what has received */
60313 + FmPortImRx(p_FmPort);
60314 +
60315 + /* Now, get rid of the the empty buffer! */
60316 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60317 +
60318 + while (bdStatus & BD_R_E) /* while there is data in the Rx BD */
60319 + {
60320 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
60321 +
60322 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL);
60323 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0);
60324 +
60325 + p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
60326 + p_CurData,
60327 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60328 +
60329 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60330 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60331 + }
60332 + }
60333 + else
60334 + TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH);
60335 +
60336 + FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram);
60337 +
60338 + if (p_FmPort->im.p_BdShadow)
60339 + XX_Free(p_FmPort->im.p_BdShadow);
60340 +
60341 + if (p_FmPort->im.p_BdRing)
60342 + XX_FreeSmart(p_FmPort->im.p_BdRing);
60343 +}
60344 +
60345 +
60346 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal)
60347 +{
60348 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60349 +
60350 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60351 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60352 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60353 +
60354 + p_FmPort->im.mrblr = newVal;
60355 +
60356 + return E_OK;
60357 +}
60358 +
60359 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
60360 +{
60361 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60362 +
60363 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60364 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60365 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60366 +
60367 + p_FmPort->im.bdRingSize = newVal;
60368 +
60369 + return E_OK;
60370 +}
60371 +
60372 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
60373 +{
60374 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60375 +
60376 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60377 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60378 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60379 +
60380 + p_FmPort->im.bdRingSize = newVal;
60381 +
60382 + return E_OK;
60383 +}
60384 +
60385 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
60386 + uint8_t memId,
60387 + uint32_t memAttributes)
60388 +{
60389 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60390 +
60391 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60392 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60393 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60394 +
60395 + p_FmPort->im.fwExtStructsMemId = memId;
60396 + p_FmPort->im.fwExtStructsMemAttr = memAttributes;
60397 +
60398 + return E_OK;
60399 +}
60400 +
60401 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort)
60402 +{
60403 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60404 +
60405 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60406 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60407 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60408 +
60409 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
60410 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only"));
60411 +
60412 + if (!FmIsMaster(p_FmPort->h_Fm))
60413 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;"
60414 + "in guest-partitions, IM is always in polling!"));
60415 +
60416 + p_FmPort->polling = TRUE;
60417 +
60418 + return E_OK;
60419 +}
60420 +
60421 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable)
60422 +{
60423 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60424 + t_Error err;
60425 + uint16_t tmpReg16;
60426 + uint32_t tmpReg32;
60427 +
60428 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60429 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60430 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60431 +
60432 + if (exception == e_FM_PORT_EXCEPTION_IM_BUSY)
60433 + {
60434 + if (enable)
60435 + {
60436 + p_FmPort->exceptions |= IM_EV_BSY;
60437 + if (p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ)
60438 + {
60439 + /* Allocate, configure and register interrupts */
60440 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
60441 + if (err)
60442 + RETURN_ERROR(MAJOR, err, NO_MSG);
60443 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
60444 +
60445 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort);
60446 + tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM);
60447 + tmpReg32 = IM_EV_BSY;
60448 + }
60449 + else
60450 + {
60451 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM);
60452 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY;
60453 + }
60454 +
60455 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60456 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60457 + }
60458 + else
60459 + {
60460 + p_FmPort->exceptions &= ~IM_EV_BSY;
60461 + if (!p_FmPort->exceptions && p_FmPort->polling)
60462 + {
60463 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60464 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60465 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60466 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60467 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60468 + }
60469 + else
60470 + {
60471 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM);
60472 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60473 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY;
60474 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60475 + }
60476 + }
60477 + }
60478 + else
60479 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception."));
60480 +
60481 + return E_OK;
60482 +}
60483 +
60484 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
60485 + uint8_t *p_Data,
60486 + uint16_t length,
60487 + bool lastBuffer,
60488 + t_Handle h_BufContext)
60489 +{
60490 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60491 + uint16_t nextBdId;
60492 + uint32_t bdStatus, nextBdStatus;
60493 + bool firstBuffer;
60494 +
60495 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60496 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60497 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60498 +
60499 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60500 + nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60501 + nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId));
60502 +
60503 + if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E))
60504 + {
60505 + /* Confirm the current BD - BD is available */
60506 + if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf))
60507 + p_FmPort->im.f_TxConf (p_FmPort->h_App,
60508 + BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)),
60509 + 0,
60510 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60511 +
60512 + bdStatus = length;
60513 +
60514 + /* if this is the first BD of a frame */
60515 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
60516 + {
60517 + firstBuffer = TRUE;
60518 + p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E);
60519 +
60520 + if (!lastBuffer)
60521 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
60522 + }
60523 + else
60524 + firstBuffer = FALSE;
60525 +
60526 + BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
60527 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext;
60528 +
60529 + /* deal with last */
60530 + if (lastBuffer)
60531 + {
60532 + /* if single buffer frame */
60533 + if (firstBuffer)
60534 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L);
60535 + else
60536 + {
60537 + /* Set the last BD of the frame */
60538 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L));
60539 + /* Set the first BD of the frame */
60540 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus);
60541 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60542 + }
60543 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4));
60544 + }
60545 + else if (!firstBuffer) /* mid frame buffer */
60546 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E);
60547 +
60548 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60549 + }
60550 + else
60551 + {
60552 + /* Discard current frame. Return error. */
60553 + if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID)
60554 + {
60555 + /* Error: No free BD */
60556 + /* Response: Discard current frame. Return error. */
60557 + uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId;
60558 +
60559 + ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId);
60560 +
60561 + /* Since firstInFrame is not NULL, one buffer at least has already been
60562 + inserted into the BD ring. Using do-while covers the situation of a
60563 + frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented
60564 + prior to testing whether or not it's equal to TxBd). */
60565 + do
60566 + {
60567 + BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0);
60568 + /* Advance BD pointer */
60569 + cleanBdId = GetNextBdId(p_FmPort, cleanBdId);
60570 + } while (cleanBdId != p_FmPort->im.currBdId);
60571 +
60572 + p_FmPort->im.currBdId = cleanBdId;
60573 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60574 + }
60575 +
60576 + return ERROR_CODE(E_FULL);
60577 + }
60578 +
60579 + return E_OK;
60580 +}
60581 +
60582 +void FM_PORT_ImTxConf(t_Handle h_FmPort)
60583 +{
60584 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60585 +
60586 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
60587 + SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE);
60588 + SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60589 +
60590 + TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK);
60591 +}
60592 +
60593 +t_Error FM_PORT_ImRx(t_Handle h_FmPort)
60594 +{
60595 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60596 +
60597 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60598 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60599 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60600 +
60601 + return FmPortImRx(p_FmPort);
60602 +}
60603 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
60604 new file mode 100755
60605 index 00000000..60acbf34
60606 --- /dev/null
60607 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
60608 @@ -0,0 +1,1568 @@
60609 +/*
60610 + * Copyright 2008-2012 Freescale Semiconductor Inc.
60611 + *
60612 + * Redistribution and use in source and binary forms, with or without
60613 + * modification, are permitted provided that the following conditions are met:
60614 + * * Redistributions of source code must retain the above copyright
60615 + * notice, this list of conditions and the following disclaimer.
60616 + * * Redistributions in binary form must reproduce the above copyright
60617 + * notice, this list of conditions and the following disclaimer in the
60618 + * documentation and/or other materials provided with the distribution.
60619 + * * Neither the name of Freescale Semiconductor nor the
60620 + * names of its contributors may be used to endorse or promote products
60621 + * derived from this software without specific prior written permission.
60622 + *
60623 + *
60624 + * ALTERNATIVELY, this software may be distributed under the terms of the
60625 + * GNU General Public License ("GPL") as published by the Free Software
60626 + * Foundation, either version 2 of that License or (at your option) any
60627 + * later version.
60628 + *
60629 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
60630 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60631 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60632 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
60633 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60634 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60635 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
60636 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60637 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60638 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60639 + */
60640 +
60641 +
60642 +#include "common/general.h"
60643 +
60644 +#include "fman_common.h"
60645 +#include "fsl_fman_port.h"
60646 +
60647 +
60648 +/* problem Eyal: the following should not be here*/
60649 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
60650 +
60651 +static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg)
60652 +{
60653 + if (cfg->errata_A006675)
60654 + return NIA_ENG_FM_CTL |
60655 + NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME;
60656 + else
60657 + return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
60658 +}
60659 +
60660 +static int init_bmi_rx(struct fman_port *port,
60661 + struct fman_port_cfg *cfg,
60662 + struct fman_port_params *params)
60663 +{
60664 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60665 + uint32_t tmp;
60666 +
60667 + /* Rx Configuration register */
60668 + tmp = 0;
60669 + if (port->im_en)
60670 + tmp |= BMI_PORT_CFG_IM;
60671 + else if (cfg->discard_override)
60672 + tmp |= BMI_PORT_CFG_FDOVR;
60673 + iowrite32be(tmp, &regs->fmbm_rcfg);
60674 +
60675 + /* DMA attributes */
60676 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60677 + if (cfg->dma_ic_stash_on)
60678 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60679 + if (cfg->dma_header_stash_on)
60680 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60681 + if (cfg->dma_sg_stash_on)
60682 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60683 + if (cfg->dma_write_optimize)
60684 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60685 + iowrite32be(tmp, &regs->fmbm_rda);
60686 +
60687 + /* Rx FIFO parameters */
60688 + tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) <<
60689 + BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
60690 + tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1;
60691 + iowrite32be(tmp, &regs->fmbm_rfp);
60692 +
60693 + if (cfg->excessive_threshold_register)
60694 + /* always allow access to the extra resources */
60695 + iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
60696 +
60697 + /* Frame end data */
60698 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60699 + BMI_RX_FRAME_END_CS_IGNORE_SHIFT;
60700 + tmp |= (uint32_t)cfg->rx_cut_end_bytes <<
60701 + BMI_RX_FRAME_END_CUT_SHIFT;
60702 + if (cfg->errata_A006320)
60703 + tmp &= 0xffe0ffff;
60704 + iowrite32be(tmp, &regs->fmbm_rfed);
60705 +
60706 + /* Internal context parameters */
60707 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60708 + BMI_IC_TO_EXT_SHIFT;
60709 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60710 + BMI_IC_FROM_INT_SHIFT;
60711 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60712 + iowrite32be(tmp, &regs->fmbm_ricp);
60713 +
60714 + /* Internal buffer offset */
60715 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60716 + << BMI_INT_BUF_MARG_SHIFT;
60717 + iowrite32be(tmp, &regs->fmbm_rim);
60718 +
60719 + /* External buffer margins */
60720 + if (!port->im_en)
60721 + {
60722 + tmp = (uint32_t)cfg->ext_buf_start_margin <<
60723 + BMI_EXT_BUF_MARG_START_SHIFT;
60724 + tmp |= (uint32_t)cfg->ext_buf_end_margin;
60725 + if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather)
60726 + tmp |= BMI_SG_DISABLE;
60727 + iowrite32be(tmp, &regs->fmbm_rebm);
60728 + }
60729 +
60730 + /* Frame attributes */
60731 + tmp = BMI_CMD_RX_MR_DEF;
60732 + if (!port->im_en)
60733 + {
60734 + tmp |= BMI_CMD_ATTR_ORDER;
60735 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60736 + if (cfg->sync_req)
60737 + tmp |= BMI_CMD_ATTR_SYNC;
60738 + }
60739 + iowrite32be(tmp, &regs->fmbm_rfca);
60740 +
60741 + /* NIA */
60742 + if (port->im_en)
60743 + tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX;
60744 + else
60745 + {
60746 + tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
60747 + tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg);
60748 + }
60749 + iowrite32be(tmp, &regs->fmbm_rfne);
60750 +
60751 + /* Enqueue NIA */
60752 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
60753 +
60754 + /* Default/error queues */
60755 + if (!port->im_en)
60756 + {
60757 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_rfqid);
60758 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_refqid);
60759 + }
60760 +
60761 + /* Discard/error masks */
60762 + iowrite32be(params->discard_mask, &regs->fmbm_rfsdm);
60763 + iowrite32be(params->err_mask, &regs->fmbm_rfsem);
60764 +
60765 + /* Statistics counters */
60766 + tmp = 0;
60767 + if (cfg->stats_counters_enable)
60768 + tmp = BMI_COUNTERS_EN;
60769 + iowrite32be(tmp, &regs->fmbm_rstc);
60770 +
60771 + /* Performance counters */
60772 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60773 + tmp = 0;
60774 + if (cfg->perf_counters_enable)
60775 + tmp = BMI_COUNTERS_EN;
60776 + iowrite32be(tmp, &regs->fmbm_rpc);
60777 +
60778 + return 0;
60779 +}
60780 +
60781 +static int init_bmi_tx(struct fman_port *port,
60782 + struct fman_port_cfg *cfg,
60783 + struct fman_port_params *params)
60784 +{
60785 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60786 + uint32_t tmp;
60787 +
60788 + /* Tx Configuration register */
60789 + tmp = 0;
60790 + if (port->im_en)
60791 + tmp |= BMI_PORT_CFG_IM;
60792 + iowrite32be(tmp, &regs->fmbm_tcfg);
60793 +
60794 + /* DMA attributes */
60795 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60796 + if (cfg->dma_ic_stash_on)
60797 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60798 + if (cfg->dma_header_stash_on)
60799 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60800 + if (cfg->dma_sg_stash_on)
60801 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60802 + iowrite32be(tmp, &regs->fmbm_tda);
60803 +
60804 + /* Tx FIFO parameters */
60805 + tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) <<
60806 + BMI_TX_FIFO_MIN_FILL_SHIFT;
60807 + tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60808 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60809 + tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level /
60810 + FMAN_PORT_BMI_FIFO_UNITS - 1);
60811 + iowrite32be(tmp, &regs->fmbm_tfp);
60812 +
60813 + /* Frame end data */
60814 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60815 + BMI_FRAME_END_CS_IGNORE_SHIFT;
60816 + iowrite32be(tmp, &regs->fmbm_tfed);
60817 +
60818 + /* Internal context parameters */
60819 + if (!port->im_en)
60820 + {
60821 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60822 + BMI_IC_TO_EXT_SHIFT;
60823 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60824 + BMI_IC_FROM_INT_SHIFT;
60825 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60826 + iowrite32be(tmp, &regs->fmbm_ticp);
60827 + }
60828 + /* Frame attributes */
60829 + tmp = BMI_CMD_TX_MR_DEF;
60830 + if (port->im_en)
60831 + tmp |= BMI_CMD_MR_DEAS;
60832 + else
60833 + {
60834 + tmp |= BMI_CMD_ATTR_ORDER;
60835 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60836 + }
60837 + iowrite32be(tmp, &regs->fmbm_tfca);
60838 +
60839 + /* Dequeue NIA + enqueue NIA */
60840 + if (port->im_en)
60841 + {
60842 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfdne);
60843 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfene);
60844 + }
60845 + else
60846 + {
60847 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
60848 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
60849 + if (cfg->fmbm_tfne_has_features)
60850 + iowrite32be(!params->dflt_fqid ?
60851 + BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
60852 + NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
60853 + if (!params->dflt_fqid && params->dont_release_buf)
60854 + {
60855 + iowrite32be(0x00FFFFFF, &regs->fmbm_tcfqid);
60856 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, &regs->fmbm_tfene);
60857 + if (cfg->fmbm_tfne_has_features)
60858 + iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN, &regs->fmbm_tfne);
60859 + }
60860 + }
60861 +
60862 + /* Confirmation/error queues */
60863 + if (!port->im_en)
60864 + {
60865 + if (params->dflt_fqid || !params->dont_release_buf)
60866 + iowrite32be(params->dflt_fqid & 0x00FFFFFF, &regs->fmbm_tcfqid);
60867 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_tefqid);
60868 + }
60869 + /* Statistics counters */
60870 + tmp = 0;
60871 + if (cfg->stats_counters_enable)
60872 + tmp = BMI_COUNTERS_EN;
60873 + iowrite32be(tmp, &regs->fmbm_tstc);
60874 +
60875 + /* Performance counters */
60876 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60877 + tmp = 0;
60878 + if (cfg->perf_counters_enable)
60879 + tmp = BMI_COUNTERS_EN;
60880 + iowrite32be(tmp, &regs->fmbm_tpc);
60881 +
60882 + return 0;
60883 +}
60884 +
60885 +static int init_bmi_oh(struct fman_port *port,
60886 + struct fman_port_cfg *cfg,
60887 + struct fman_port_params *params)
60888 +{
60889 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60890 + uint32_t tmp;
60891 +
60892 + /* OP Configuration register */
60893 + tmp = 0;
60894 + if (cfg->discard_override)
60895 + tmp |= BMI_PORT_CFG_FDOVR;
60896 + iowrite32be(tmp, &regs->fmbm_ocfg);
60897 +
60898 + /* DMA attributes */
60899 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60900 + if (cfg->dma_ic_stash_on)
60901 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60902 + if (cfg->dma_header_stash_on)
60903 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60904 + if (cfg->dma_sg_stash_on)
60905 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60906 + if (cfg->dma_write_optimize)
60907 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60908 + iowrite32be(tmp, &regs->fmbm_oda);
60909 +
60910 + /* Tx FIFO parameters */
60911 + tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60912 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60913 + iowrite32be(tmp, &regs->fmbm_ofp);
60914 +
60915 + /* Internal context parameters */
60916 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60917 + BMI_IC_TO_EXT_SHIFT;
60918 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60919 + BMI_IC_FROM_INT_SHIFT;
60920 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60921 + iowrite32be(tmp, &regs->fmbm_oicp);
60922 +
60923 + /* Frame attributes */
60924 + tmp = BMI_CMD_OP_MR_DEF;
60925 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60926 + if (cfg->sync_req)
60927 + tmp |= BMI_CMD_ATTR_SYNC;
60928 + if (port->type == E_FMAN_PORT_TYPE_OP)
60929 + tmp |= BMI_CMD_ATTR_ORDER;
60930 + iowrite32be(tmp, &regs->fmbm_ofca);
60931 +
60932 + /* Internal buffer offset */
60933 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60934 + << BMI_INT_BUF_MARG_SHIFT;
60935 + iowrite32be(tmp, &regs->fmbm_oim);
60936 +
60937 + /* Dequeue NIA */
60938 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_ofdne);
60939 +
60940 + /* NIA and Enqueue NIA */
60941 + if (port->type == E_FMAN_PORT_TYPE_HC) {
60942 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC,
60943 + &regs->fmbm_ofne);
60944 + iowrite32be(NIA_ENG_QMI_ENQ, &regs->fmbm_ofene);
60945 + } else {
60946 + iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg),
60947 + &regs->fmbm_ofne);
60948 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR,
60949 + &regs->fmbm_ofene);
60950 + }
60951 +
60952 + /* Default/error queues */
60953 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_ofqid);
60954 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_oefqid);
60955 +
60956 + /* Discard/error masks */
60957 + if (port->type == E_FMAN_PORT_TYPE_OP) {
60958 + iowrite32be(params->discard_mask, &regs->fmbm_ofsdm);
60959 + iowrite32be(params->err_mask, &regs->fmbm_ofsem);
60960 + }
60961 +
60962 + /* Statistics counters */
60963 + tmp = 0;
60964 + if (cfg->stats_counters_enable)
60965 + tmp = BMI_COUNTERS_EN;
60966 + iowrite32be(tmp, &regs->fmbm_ostc);
60967 +
60968 + /* Performance counters */
60969 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60970 + tmp = 0;
60971 + if (cfg->perf_counters_enable)
60972 + tmp = BMI_COUNTERS_EN;
60973 + iowrite32be(tmp, &regs->fmbm_opc);
60974 +
60975 + return 0;
60976 +}
60977 +
60978 +static int init_qmi(struct fman_port *port,
60979 + struct fman_port_cfg *cfg,
60980 + struct fman_port_params *params)
60981 +{
60982 + struct fman_port_qmi_regs *regs = port->qmi_regs;
60983 + uint32_t tmp;
60984 +
60985 + tmp = 0;
60986 + if (cfg->queue_counters_enable)
60987 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
60988 + iowrite32be(tmp, &regs->fmqm_pnc);
60989 +
60990 + /* Rx port configuration */
60991 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
60992 + (port->type == E_FMAN_PORT_TYPE_RX_10G)) {
60993 + /* Enqueue NIA */
60994 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60995 + return 0;
60996 + }
60997 +
60998 + /* Continue with Tx and O/H port configuration */
60999 + if ((port->type == E_FMAN_PORT_TYPE_TX) ||
61000 + (port->type == E_FMAN_PORT_TYPE_TX_10G)) {
61001 + /* Enqueue NIA */
61002 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
61003 + &regs->fmqm_pnen);
61004 + /* Dequeue NIA */
61005 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
61006 + } else {
61007 + /* Enqueue NIA */
61008 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
61009 + /* Dequeue NIA */
61010 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, &regs->fmqm_pndn);
61011 + }
61012 +
61013 + /* Dequeue Configuration register */
61014 + tmp = 0;
61015 + if (cfg->deq_high_pri)
61016 + tmp |= QMI_DEQ_CFG_PRI;
61017 +
61018 + switch (cfg->deq_type) {
61019 + case E_FMAN_PORT_DEQ_BY_PRI:
61020 + tmp |= QMI_DEQ_CFG_TYPE1;
61021 + break;
61022 + case E_FMAN_PORT_DEQ_ACTIVE_FQ:
61023 + tmp |= QMI_DEQ_CFG_TYPE2;
61024 + break;
61025 + case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
61026 + tmp |= QMI_DEQ_CFG_TYPE3;
61027 + break;
61028 + default:
61029 + return -EINVAL;
61030 + }
61031 +
61032 + if (cfg->qmi_deq_options_support) {
61033 + if ((port->type == E_FMAN_PORT_TYPE_HC) &&
61034 + (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH))
61035 + return -EINVAL;
61036 +
61037 + switch (cfg->deq_prefetch_opt) {
61038 + case E_FMAN_PORT_DEQ_NO_PREFETCH:
61039 + break;
61040 + case E_FMAN_PORT_DEQ_PART_PREFETCH:
61041 + tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
61042 + break;
61043 + case E_FMAN_PORT_DEQ_FULL_PREFETCH:
61044 + tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
61045 + break;
61046 + default:
61047 + return -EINVAL;
61048 + }
61049 + }
61050 + tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) <<
61051 + QMI_DEQ_CFG_SP_SHIFT;
61052 + tmp |= cfg->deq_byte_cnt;
61053 + iowrite32be(tmp, &regs->fmqm_pndc);
61054 +
61055 + return 0;
61056 +}
61057 +
61058 +static void get_rx_stats_reg(struct fman_port *port,
61059 + enum fman_port_stats_counters counter,
61060 + uint32_t **stats_reg)
61061 +{
61062 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
61063 +
61064 + switch (counter) {
61065 + case E_FMAN_PORT_STATS_CNT_FRAME:
61066 + *stats_reg = &regs->fmbm_rfrc;
61067 + break;
61068 + case E_FMAN_PORT_STATS_CNT_DISCARD:
61069 + *stats_reg = &regs->fmbm_rfdc;
61070 + break;
61071 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
61072 + *stats_reg = &regs->fmbm_rbdc;
61073 + break;
61074 + case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME:
61075 + *stats_reg = &regs->fmbm_rfbc;
61076 + break;
61077 + case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME:
61078 + *stats_reg = &regs->fmbm_rlfc;
61079 + break;
61080 + case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF:
61081 + *stats_reg = &regs->fmbm_rodc;
61082 + break;
61083 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
61084 + *stats_reg = &regs->fmbm_rffc;
61085 + break;
61086 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
61087 + *stats_reg = &regs->fmbm_rfldec;
61088 + break;
61089 + default:
61090 + *stats_reg = NULL;
61091 + }
61092 +}
61093 +
61094 +static void get_tx_stats_reg(struct fman_port *port,
61095 + enum fman_port_stats_counters counter,
61096 + uint32_t **stats_reg)
61097 +{
61098 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
61099 +
61100 + switch (counter) {
61101 + case E_FMAN_PORT_STATS_CNT_FRAME:
61102 + *stats_reg = &regs->fmbm_tfrc;
61103 + break;
61104 + case E_FMAN_PORT_STATS_CNT_DISCARD:
61105 + *stats_reg = &regs->fmbm_tfdc;
61106 + break;
61107 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
61108 + *stats_reg = &regs->fmbm_tbdc;
61109 + break;
61110 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
61111 + *stats_reg = &regs->fmbm_tfledc;
61112 + break;
61113 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
61114 + *stats_reg = &regs->fmbm_tfufdc;
61115 + break;
61116 + default:
61117 + *stats_reg = NULL;
61118 + }
61119 +}
61120 +
61121 +static void get_oh_stats_reg(struct fman_port *port,
61122 + enum fman_port_stats_counters counter,
61123 + uint32_t **stats_reg)
61124 +{
61125 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
61126 +
61127 + switch (counter) {
61128 + case E_FMAN_PORT_STATS_CNT_FRAME:
61129 + *stats_reg = &regs->fmbm_ofrc;
61130 + break;
61131 + case E_FMAN_PORT_STATS_CNT_DISCARD:
61132 + *stats_reg = &regs->fmbm_ofdc;
61133 + break;
61134 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
61135 + *stats_reg = &regs->fmbm_obdc;
61136 + break;
61137 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
61138 + *stats_reg = &regs->fmbm_offc;
61139 + break;
61140 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
61141 + *stats_reg = &regs->fmbm_ofldec;
61142 + break;
61143 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
61144 + *stats_reg = &regs->fmbm_ofledc;
61145 + break;
61146 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
61147 + *stats_reg = &regs->fmbm_ofufdc;
61148 + break;
61149 + case E_FMAN_PORT_STATS_CNT_WRED_DISCARD:
61150 + *stats_reg = &regs->fmbm_ofwdc;
61151 + break;
61152 + default:
61153 + *stats_reg = NULL;
61154 + }
61155 +}
61156 +
61157 +static void get_rx_perf_reg(struct fman_port *port,
61158 + enum fman_port_perf_counters counter,
61159 + uint32_t **perf_reg)
61160 +{
61161 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
61162 +
61163 + switch (counter) {
61164 + case E_FMAN_PORT_PERF_CNT_CYCLE:
61165 + *perf_reg = &regs->fmbm_rccn;
61166 + break;
61167 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
61168 + *perf_reg = &regs->fmbm_rtuc;
61169 + break;
61170 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
61171 + *perf_reg = &regs->fmbm_rrquc;
61172 + break;
61173 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
61174 + *perf_reg = &regs->fmbm_rduc;
61175 + break;
61176 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
61177 + *perf_reg = &regs->fmbm_rfuc;
61178 + break;
61179 + case E_FMAN_PORT_PERF_CNT_RX_PAUSE:
61180 + *perf_reg = &regs->fmbm_rpac;
61181 + break;
61182 + default:
61183 + *perf_reg = NULL;
61184 + }
61185 +}
61186 +
61187 +static void get_tx_perf_reg(struct fman_port *port,
61188 + enum fman_port_perf_counters counter,
61189 + uint32_t **perf_reg)
61190 +{
61191 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
61192 +
61193 + switch (counter) {
61194 + case E_FMAN_PORT_PERF_CNT_CYCLE:
61195 + *perf_reg = &regs->fmbm_tccn;
61196 + break;
61197 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
61198 + *perf_reg = &regs->fmbm_ttuc;
61199 + break;
61200 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
61201 + *perf_reg = &regs->fmbm_ttcquc;
61202 + break;
61203 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
61204 + *perf_reg = &regs->fmbm_tduc;
61205 + break;
61206 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
61207 + *perf_reg = &regs->fmbm_tfuc;
61208 + break;
61209 + default:
61210 + *perf_reg = NULL;
61211 + }
61212 +}
61213 +
61214 +static void get_oh_perf_reg(struct fman_port *port,
61215 + enum fman_port_perf_counters counter,
61216 + uint32_t **perf_reg)
61217 +{
61218 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
61219 +
61220 + switch (counter) {
61221 + case E_FMAN_PORT_PERF_CNT_CYCLE:
61222 + *perf_reg = &regs->fmbm_occn;
61223 + break;
61224 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
61225 + *perf_reg = &regs->fmbm_otuc;
61226 + break;
61227 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
61228 + *perf_reg = &regs->fmbm_oduc;
61229 + break;
61230 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
61231 + *perf_reg = &regs->fmbm_ofuc;
61232 + break;
61233 + default:
61234 + *perf_reg = NULL;
61235 + }
61236 +}
61237 +
61238 +static void get_qmi_counter_reg(struct fman_port *port,
61239 + enum fman_port_qmi_counters counter,
61240 + uint32_t **queue_reg)
61241 +{
61242 + struct fman_port_qmi_regs *regs = port->qmi_regs;
61243 +
61244 + switch (counter) {
61245 + case E_FMAN_PORT_ENQ_TOTAL:
61246 + *queue_reg = &regs->fmqm_pnetfc;
61247 + break;
61248 + case E_FMAN_PORT_DEQ_TOTAL:
61249 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61250 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61251 + /* Counter not available for Rx ports */
61252 + *queue_reg = NULL;
61253 + else
61254 + *queue_reg = &regs->fmqm_pndtfc;
61255 + break;
61256 + case E_FMAN_PORT_DEQ_FROM_DFLT:
61257 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61258 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61259 + /* Counter not available for Rx ports */
61260 + *queue_reg = NULL;
61261 + else
61262 + *queue_reg = &regs->fmqm_pndfdc;
61263 + break;
61264 + case E_FMAN_PORT_DEQ_CONFIRM:
61265 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61266 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61267 + /* Counter not available for Rx ports */
61268 + *queue_reg = NULL;
61269 + else
61270 + *queue_reg = &regs->fmqm_pndcc;
61271 + break;
61272 + default:
61273 + *queue_reg = NULL;
61274 + }
61275 +}
61276 +
61277 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type)
61278 +{
61279 + cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP;
61280 + cfg->dma_ic_stash_on = FALSE;
61281 + cfg->dma_header_stash_on = FALSE;
61282 + cfg->dma_sg_stash_on = FALSE;
61283 + cfg->dma_write_optimize = TRUE;
61284 + cfg->color = E_FMAN_PORT_COLOR_GREEN;
61285 + cfg->discard_override = FALSE;
61286 + cfg->checksum_bytes_ignore = 0;
61287 + cfg->rx_cut_end_bytes = 4;
61288 + cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
61289 + cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
61290 + cfg->rx_fd_bits = 0;
61291 + cfg->ic_ext_offset = 0;
61292 + cfg->ic_int_offset = 0;
61293 + cfg->ic_size = 0;
61294 + cfg->int_buf_start_margin = 0;
61295 + cfg->ext_buf_start_margin = 0;
61296 + cfg->ext_buf_end_margin = 0;
61297 + cfg->tx_fifo_min_level = 0;
61298 + cfg->tx_fifo_low_comf_level = (5 * KILOBYTE);
61299 + cfg->stats_counters_enable = TRUE;
61300 + cfg->perf_counters_enable = TRUE;
61301 + cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI;
61302 +
61303 + if (type == E_FMAN_PORT_TYPE_HC) {
61304 + cfg->sync_req = FALSE;
61305 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH;
61306 + } else {
61307 + cfg->sync_req = TRUE;
61308 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH;
61309 + }
61310 +
61311 + if (type == E_FMAN_PORT_TYPE_TX_10G) {
61312 + cfg->tx_fifo_deq_pipeline_depth = 4;
61313 + cfg->deq_high_pri = TRUE;
61314 + cfg->deq_byte_cnt = 0x1400;
61315 + } else {
61316 + if ((type == E_FMAN_PORT_TYPE_HC) ||
61317 + (type == E_FMAN_PORT_TYPE_OP))
61318 + cfg->tx_fifo_deq_pipeline_depth = 2;
61319 + else
61320 + cfg->tx_fifo_deq_pipeline_depth = 1;
61321 +
61322 + cfg->deq_high_pri = FALSE;
61323 + cfg->deq_byte_cnt = 0x400;
61324 + }
61325 + cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
61326 +}
61327 +
61328 +static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid)
61329 +{
61330 + uint32_t *bp_reg, tmp;
61331 + uint8_t i, id;
61332 +
61333 + /* Find the pool */
61334 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61335 + for (i = 0;
61336 + (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM));
61337 + i++) {
61338 + tmp = ioread32be(&bp_reg[i]);
61339 + id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >>
61340 + BMI_EXT_BUF_POOL_ID_SHIFT);
61341 +
61342 + if (id == bpid)
61343 + break;
61344 + }
61345 +
61346 + return i;
61347 +}
61348 +
61349 +int fman_port_init(struct fman_port *port,
61350 + struct fman_port_cfg *cfg,
61351 + struct fman_port_params *params)
61352 +{
61353 + int err;
61354 +
61355 + /* Init BMI registers */
61356 + switch (port->type) {
61357 + case E_FMAN_PORT_TYPE_RX:
61358 + case E_FMAN_PORT_TYPE_RX_10G:
61359 + err = init_bmi_rx(port, cfg, params);
61360 + break;
61361 + case E_FMAN_PORT_TYPE_TX:
61362 + case E_FMAN_PORT_TYPE_TX_10G:
61363 + err = init_bmi_tx(port, cfg, params);
61364 + break;
61365 + case E_FMAN_PORT_TYPE_OP:
61366 + case E_FMAN_PORT_TYPE_HC:
61367 + err = init_bmi_oh(port, cfg, params);
61368 + break;
61369 + default:
61370 + return -EINVAL;
61371 + }
61372 +
61373 + if (err)
61374 + return err;
61375 +
61376 + /* Init QMI registers */
61377 + if (!port->im_en)
61378 + {
61379 + err = init_qmi(port, cfg, params);
61380 + return err;
61381 + }
61382 + return 0;
61383 +}
61384 +
61385 +int fman_port_enable(struct fman_port *port)
61386 +{
61387 + uint32_t *bmi_cfg_reg, tmp;
61388 + bool rx_port;
61389 +
61390 + switch (port->type) {
61391 + case E_FMAN_PORT_TYPE_RX:
61392 + case E_FMAN_PORT_TYPE_RX_10G:
61393 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61394 + rx_port = TRUE;
61395 + break;
61396 + case E_FMAN_PORT_TYPE_TX:
61397 + case E_FMAN_PORT_TYPE_TX_10G:
61398 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61399 + rx_port = FALSE;
61400 + break;
61401 + case E_FMAN_PORT_TYPE_OP:
61402 + case E_FMAN_PORT_TYPE_HC:
61403 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61404 + rx_port = FALSE;
61405 + break;
61406 + default:
61407 + return -EINVAL;
61408 + }
61409 +
61410 + /* Enable QMI */
61411 + if (!rx_port) {
61412 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
61413 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61414 + }
61415 +
61416 + /* Enable BMI */
61417 + tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
61418 + iowrite32be(tmp, bmi_cfg_reg);
61419 +
61420 + return 0;
61421 +}
61422 +
61423 +int fman_port_disable(const struct fman_port *port)
61424 +{
61425 + uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp;
61426 + bool rx_port, failure = FALSE;
61427 + int count;
61428 +
61429 + switch (port->type) {
61430 + case E_FMAN_PORT_TYPE_RX:
61431 + case E_FMAN_PORT_TYPE_RX_10G:
61432 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61433 + bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
61434 + rx_port = TRUE;
61435 + break;
61436 + case E_FMAN_PORT_TYPE_TX:
61437 + case E_FMAN_PORT_TYPE_TX_10G:
61438 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61439 + bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
61440 + rx_port = FALSE;
61441 + break;
61442 + case E_FMAN_PORT_TYPE_OP:
61443 + case E_FMAN_PORT_TYPE_HC:
61444 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61445 + bmi_status_reg = &port->bmi_regs->oh.fmbm_ost;
61446 + rx_port = FALSE;
61447 + break;
61448 + default:
61449 + return -EINVAL;
61450 + }
61451 +
61452 + /* Disable QMI */
61453 + if (!rx_port) {
61454 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
61455 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61456 +
61457 + /* Wait for QMI to finish FD handling */
61458 + count = 100;
61459 + do {
61460 + udelay(10);
61461 + tmp = ioread32be(&port->qmi_regs->fmqm_pns);
61462 + } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
61463 +
61464 + if (count == 0)
61465 + {
61466 + /* Timeout */
61467 + failure = TRUE;
61468 + }
61469 + }
61470 +
61471 + /* Disable BMI */
61472 + tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
61473 + iowrite32be(tmp, bmi_cfg_reg);
61474 +
61475 + /* Wait for graceful stop end */
61476 + count = 500;
61477 + do {
61478 + udelay(10);
61479 + tmp = ioread32be(bmi_status_reg);
61480 + } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
61481 +
61482 + if (count == 0)
61483 + {
61484 + /* Timeout */
61485 + failure = TRUE;
61486 + }
61487 +
61488 + if (failure)
61489 + return -EBUSY;
61490 +
61491 + return 0;
61492 +}
61493 +
61494 +int fman_port_set_bpools(const struct fman_port *port,
61495 + const struct fman_port_bpools *bp)
61496 +{
61497 + uint32_t tmp, *bp_reg, *bp_depl_reg;
61498 + uint8_t i, max_bp_num;
61499 + bool grp_depl_used = FALSE, rx_port;
61500 +
61501 + switch (port->type) {
61502 + case E_FMAN_PORT_TYPE_RX:
61503 + case E_FMAN_PORT_TYPE_RX_10G:
61504 + max_bp_num = port->ext_pools_num;
61505 + rx_port = TRUE;
61506 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61507 + bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
61508 + break;
61509 + case E_FMAN_PORT_TYPE_OP:
61510 + if (port->fm_rev_maj != 4)
61511 + return -EINVAL;
61512 + max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM;
61513 + rx_port = FALSE;
61514 + bp_reg = port->bmi_regs->oh.fmbm_oebmpi;
61515 + bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd;
61516 + break;
61517 + default:
61518 + return -EINVAL;
61519 + }
61520 +
61521 + if (rx_port) {
61522 + /* Check buffers are provided in ascending order */
61523 + for (i = 0;
61524 + (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1));
61525 + i++) {
61526 + if (bp->bpool[i].size > bp->bpool[i+1].size)
61527 + return -EINVAL;
61528 + }
61529 + }
61530 +
61531 + /* Set up external buffers pools */
61532 + for (i = 0; i < bp->count; i++) {
61533 + tmp = BMI_EXT_BUF_POOL_VALID;
61534 + tmp |= ((uint32_t)bp->bpool[i].bpid <<
61535 + BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
61536 +
61537 + if (rx_port) {
61538 + if (bp->counters_enable)
61539 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61540 +
61541 + if (bp->bpool[i].is_backup)
61542 + tmp |= BMI_EXT_BUF_POOL_BACKUP;
61543 +
61544 + tmp |= (uint32_t)bp->bpool[i].size;
61545 + }
61546 +
61547 + iowrite32be(tmp, &bp_reg[i]);
61548 + }
61549 +
61550 + /* Clear unused pools */
61551 + for (i = bp->count; i < max_bp_num; i++)
61552 + iowrite32be(0, &bp_reg[i]);
61553 +
61554 + /* Pools depletion */
61555 + tmp = 0;
61556 + for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
61557 + if (bp->bpool[i].grp_bp_depleted) {
61558 + grp_depl_used = TRUE;
61559 + tmp |= 0x80000000 >> i;
61560 + }
61561 +
61562 + if (bp->bpool[i].single_bp_depleted)
61563 + tmp |= 0x80 >> i;
61564 +
61565 + if (bp->bpool[i].pfc_priorities_en)
61566 + tmp |= 0x0100 << i;
61567 + }
61568 +
61569 + if (grp_depl_used)
61570 + tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) <<
61571 + BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
61572 +
61573 + iowrite32be(tmp, bp_depl_reg);
61574 + return 0;
61575 +}
61576 +
61577 +int fman_port_set_rate_limiter(struct fman_port *port,
61578 + struct fman_port_rate_limiter *rate_limiter)
61579 +{
61580 + uint32_t *rate_limit_reg, *rate_limit_scale_reg;
61581 + uint32_t granularity, tmp;
61582 + uint8_t usec_bit, factor;
61583 +
61584 + switch (port->type) {
61585 + case E_FMAN_PORT_TYPE_TX:
61586 + case E_FMAN_PORT_TYPE_TX_10G:
61587 + rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt;
61588 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61589 + granularity = BMI_RATE_LIMIT_GRAN_TX;
61590 + break;
61591 + case E_FMAN_PORT_TYPE_OP:
61592 + rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt;
61593 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61594 + granularity = BMI_RATE_LIMIT_GRAN_OP;
61595 + break;
61596 + default:
61597 + return -EINVAL;
61598 + }
61599 +
61600 + /* Factor is per 1 usec count */
61601 + factor = 1;
61602 + usec_bit = rate_limiter->count_1micro_bit;
61603 +
61604 + /* If rate limit is too small for an 1usec factor, adjust timestamp
61605 + * scale and multiply the factor */
61606 + while (rate_limiter->rate < (granularity / factor)) {
61607 + if (usec_bit == 31)
61608 + /* Can't configure rate limiter - rate is too small */
61609 + return -EINVAL;
61610 +
61611 + usec_bit++;
61612 + factor <<= 1;
61613 + }
61614 +
61615 + /* Figure out register value. The "while" above quarantees that
61616 + * (rate_limiter->rate * factor / granularity) >= 1 */
61617 + tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1);
61618 +
61619 + /* Check rate limit isn't too large */
61620 + if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS)
61621 + return -EINVAL;
61622 +
61623 + /* Check burst size is in allowed range */
61624 + if ((rate_limiter->burst_size == 0) ||
61625 + (rate_limiter->burst_size >
61626 + BMI_RATE_LIMIT_MAX_BURST_SIZE))
61627 + return -EINVAL;
61628 +
61629 + tmp |= (uint32_t)(rate_limiter->burst_size - 1) <<
61630 + BMI_RATE_LIMIT_MAX_BURST_SHIFT;
61631 +
61632 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61633 + (port->fm_rev_maj == 4)) {
61634 + if (rate_limiter->high_burst_size_gran)
61635 + tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN;
61636 + }
61637 +
61638 + iowrite32be(tmp, rate_limit_reg);
61639 +
61640 + /* Set up rate limiter scale register */
61641 + tmp = BMI_RATE_LIMIT_SCALE_EN;
61642 + tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT;
61643 +
61644 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61645 + (port->fm_rev_maj == 4))
61646 + tmp |= rate_limiter->rate_factor;
61647 +
61648 + iowrite32be(tmp, rate_limit_scale_reg);
61649 +
61650 + return 0;
61651 +}
61652 +
61653 +int fman_port_delete_rate_limiter(struct fman_port *port)
61654 +{
61655 + uint32_t *rate_limit_scale_reg;
61656 +
61657 + switch (port->type) {
61658 + case E_FMAN_PORT_TYPE_TX:
61659 + case E_FMAN_PORT_TYPE_TX_10G:
61660 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61661 + break;
61662 + case E_FMAN_PORT_TYPE_OP:
61663 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61664 + break;
61665 + default:
61666 + return -EINVAL;
61667 + }
61668 +
61669 + iowrite32be(0, rate_limit_scale_reg);
61670 + return 0;
61671 +}
61672 +
61673 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask)
61674 +{
61675 + uint32_t *err_mask_reg;
61676 +
61677 + /* Obtain register address */
61678 + switch (port->type) {
61679 + case E_FMAN_PORT_TYPE_RX:
61680 + case E_FMAN_PORT_TYPE_RX_10G:
61681 + err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem;
61682 + break;
61683 + case E_FMAN_PORT_TYPE_OP:
61684 + err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem;
61685 + break;
61686 + default:
61687 + return -EINVAL;
61688 + }
61689 +
61690 + iowrite32be(err_mask, err_mask_reg);
61691 + return 0;
61692 +}
61693 +
61694 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask)
61695 +{
61696 + uint32_t *discard_mask_reg;
61697 +
61698 + /* Obtain register address */
61699 + switch (port->type) {
61700 + case E_FMAN_PORT_TYPE_RX:
61701 + case E_FMAN_PORT_TYPE_RX_10G:
61702 + discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm;
61703 + break;
61704 + case E_FMAN_PORT_TYPE_OP:
61705 + discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm;
61706 + break;
61707 + default:
61708 + return -EINVAL;
61709 + }
61710 +
61711 + iowrite32be(discard_mask, discard_mask_reg);
61712 + return 0;
61713 +}
61714 +
61715 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
61716 + uint8_t rx_fd_bits,
61717 + bool add)
61718 +{
61719 + uint32_t tmp;
61720 +
61721 + switch (port->type) {
61722 + case E_FMAN_PORT_TYPE_RX:
61723 + case E_FMAN_PORT_TYPE_RX_10G:
61724 + break;
61725 + default:
61726 + return -EINVAL;
61727 + }
61728 +
61729 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne);
61730 +
61731 + if (add)
61732 + tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
61733 + else
61734 + tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT);
61735 +
61736 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne);
61737 + return 0;
61738 +}
61739 +
61740 +int fman_port_set_perf_cnt_params(struct fman_port *port,
61741 + struct fman_port_perf_cnt_params *params)
61742 +{
61743 + uint32_t *pcp_reg, tmp;
61744 +
61745 + /* Obtain register address and check parameters are in range */
61746 + switch (port->type) {
61747 + case E_FMAN_PORT_TYPE_RX:
61748 + case E_FMAN_PORT_TYPE_RX_10G:
61749 + pcp_reg = &port->bmi_regs->rx.fmbm_rpcp;
61750 + if ((params->queue_val == 0) ||
61751 + (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP))
61752 + return -EINVAL;
61753 + break;
61754 + case E_FMAN_PORT_TYPE_TX:
61755 + case E_FMAN_PORT_TYPE_TX_10G:
61756 + pcp_reg = &port->bmi_regs->tx.fmbm_tpcp;
61757 + if ((params->queue_val == 0) ||
61758 + (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP))
61759 + return -EINVAL;
61760 + break;
61761 + case E_FMAN_PORT_TYPE_OP:
61762 + case E_FMAN_PORT_TYPE_HC:
61763 + pcp_reg = &port->bmi_regs->oh.fmbm_opcp;
61764 + if (params->queue_val != 0)
61765 + return -EINVAL;
61766 + break;
61767 + default:
61768 + return -EINVAL;
61769 + }
61770 +
61771 + if ((params->task_val == 0) ||
61772 + (params->task_val > MAX_PERFORMANCE_TASK_COMP))
61773 + return -EINVAL;
61774 + if ((params->dma_val == 0) ||
61775 + (params->dma_val > MAX_PERFORMANCE_DMA_COMP))
61776 + return -EINVAL;
61777 + if ((params->fifo_val == 0) ||
61778 + ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) >
61779 + MAX_PERFORMANCE_FIFO_COMP))
61780 + return -EINVAL;
61781 + tmp = (uint32_t)(params->task_val - 1) <<
61782 + BMI_PERFORMANCE_TASK_COMP_SHIFT;
61783 + tmp |= (uint32_t)(params->dma_val - 1) <<
61784 + BMI_PERFORMANCE_DMA_COMP_SHIFT;
61785 + tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1);
61786 +
61787 + switch (port->type) {
61788 + case E_FMAN_PORT_TYPE_RX:
61789 + case E_FMAN_PORT_TYPE_RX_10G:
61790 + case E_FMAN_PORT_TYPE_TX:
61791 + case E_FMAN_PORT_TYPE_TX_10G:
61792 + tmp |= (uint32_t)(params->queue_val - 1) <<
61793 + BMI_PERFORMANCE_QUEUE_COMP_SHIFT;
61794 + break;
61795 + default:
61796 + break;
61797 + }
61798 +
61799 +
61800 + iowrite32be(tmp, pcp_reg);
61801 + return 0;
61802 +}
61803 +
61804 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable)
61805 +{
61806 + uint32_t *stats_reg, tmp;
61807 +
61808 + switch (port->type) {
61809 + case E_FMAN_PORT_TYPE_RX:
61810 + case E_FMAN_PORT_TYPE_RX_10G:
61811 + stats_reg = &port->bmi_regs->rx.fmbm_rstc;
61812 + break;
61813 + case E_FMAN_PORT_TYPE_TX:
61814 + case E_FMAN_PORT_TYPE_TX_10G:
61815 + stats_reg = &port->bmi_regs->tx.fmbm_tstc;
61816 + break;
61817 + case E_FMAN_PORT_TYPE_OP:
61818 + case E_FMAN_PORT_TYPE_HC:
61819 + stats_reg = &port->bmi_regs->oh.fmbm_ostc;
61820 + break;
61821 + default:
61822 + return -EINVAL;
61823 + }
61824 +
61825 + tmp = ioread32be(stats_reg);
61826 +
61827 + if (enable)
61828 + tmp |= BMI_COUNTERS_EN;
61829 + else
61830 + tmp &= ~BMI_COUNTERS_EN;
61831 +
61832 + iowrite32be(tmp, stats_reg);
61833 + return 0;
61834 +}
61835 +
61836 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable)
61837 +{
61838 + uint32_t *stats_reg, tmp;
61839 +
61840 + switch (port->type) {
61841 + case E_FMAN_PORT_TYPE_RX:
61842 + case E_FMAN_PORT_TYPE_RX_10G:
61843 + stats_reg = &port->bmi_regs->rx.fmbm_rpc;
61844 + break;
61845 + case E_FMAN_PORT_TYPE_TX:
61846 + case E_FMAN_PORT_TYPE_TX_10G:
61847 + stats_reg = &port->bmi_regs->tx.fmbm_tpc;
61848 + break;
61849 + case E_FMAN_PORT_TYPE_OP:
61850 + case E_FMAN_PORT_TYPE_HC:
61851 + stats_reg = &port->bmi_regs->oh.fmbm_opc;
61852 + break;
61853 + default:
61854 + return -EINVAL;
61855 + }
61856 +
61857 + tmp = ioread32be(stats_reg);
61858 +
61859 + if (enable)
61860 + tmp |= BMI_COUNTERS_EN;
61861 + else
61862 + tmp &= ~BMI_COUNTERS_EN;
61863 +
61864 + iowrite32be(tmp, stats_reg);
61865 + return 0;
61866 +}
61867 +
61868 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable)
61869 +{
61870 + uint32_t tmp;
61871 +
61872 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc);
61873 +
61874 + if (enable)
61875 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
61876 + else
61877 + tmp &= ~QMI_PORT_CFG_EN_COUNTERS;
61878 +
61879 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61880 + return 0;
61881 +}
61882 +
61883 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
61884 + uint8_t bpid,
61885 + bool enable)
61886 +{
61887 + uint8_t index;
61888 + uint32_t tmp;
61889 +
61890 + switch (port->type) {
61891 + case E_FMAN_PORT_TYPE_RX:
61892 + case E_FMAN_PORT_TYPE_RX_10G:
61893 + break;
61894 + default:
61895 + return -EINVAL;
61896 + }
61897 +
61898 + /* Find the pool */
61899 + index = fman_port_find_bpool(port, bpid);
61900 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61901 + /* Not found */
61902 + return -EINVAL;
61903 +
61904 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]);
61905 +
61906 + if (enable)
61907 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61908 + else
61909 + tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER;
61910 +
61911 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]);
61912 + return 0;
61913 +}
61914 +
61915 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
61916 + enum fman_port_stats_counters counter)
61917 +{
61918 + uint32_t *stats_reg, ret_val;
61919 +
61920 + switch (port->type) {
61921 + case E_FMAN_PORT_TYPE_RX:
61922 + case E_FMAN_PORT_TYPE_RX_10G:
61923 + get_rx_stats_reg(port, counter, &stats_reg);
61924 + break;
61925 + case E_FMAN_PORT_TYPE_TX:
61926 + case E_FMAN_PORT_TYPE_TX_10G:
61927 + get_tx_stats_reg(port, counter, &stats_reg);
61928 + break;
61929 + case E_FMAN_PORT_TYPE_OP:
61930 + case E_FMAN_PORT_TYPE_HC:
61931 + get_oh_stats_reg(port, counter, &stats_reg);
61932 + break;
61933 + default:
61934 + stats_reg = NULL;
61935 + }
61936 +
61937 + if (stats_reg == NULL)
61938 + return 0;
61939 +
61940 + ret_val = ioread32be(stats_reg);
61941 + return ret_val;
61942 +}
61943 +
61944 +void fman_port_set_stats_counter(struct fman_port *port,
61945 + enum fman_port_stats_counters counter,
61946 + uint32_t value)
61947 +{
61948 + uint32_t *stats_reg;
61949 +
61950 + switch (port->type) {
61951 + case E_FMAN_PORT_TYPE_RX:
61952 + case E_FMAN_PORT_TYPE_RX_10G:
61953 + get_rx_stats_reg(port, counter, &stats_reg);
61954 + break;
61955 + case E_FMAN_PORT_TYPE_TX:
61956 + case E_FMAN_PORT_TYPE_TX_10G:
61957 + get_tx_stats_reg(port, counter, &stats_reg);
61958 + break;
61959 + case E_FMAN_PORT_TYPE_OP:
61960 + case E_FMAN_PORT_TYPE_HC:
61961 + get_oh_stats_reg(port, counter, &stats_reg);
61962 + break;
61963 + default:
61964 + stats_reg = NULL;
61965 + }
61966 +
61967 + if (stats_reg == NULL)
61968 + return;
61969 +
61970 + iowrite32be(value, stats_reg);
61971 +}
61972 +
61973 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
61974 + enum fman_port_perf_counters counter)
61975 +{
61976 + uint32_t *perf_reg, ret_val;
61977 +
61978 + switch (port->type) {
61979 + case E_FMAN_PORT_TYPE_RX:
61980 + case E_FMAN_PORT_TYPE_RX_10G:
61981 + get_rx_perf_reg(port, counter, &perf_reg);
61982 + break;
61983 + case E_FMAN_PORT_TYPE_TX:
61984 + case E_FMAN_PORT_TYPE_TX_10G:
61985 + get_tx_perf_reg(port, counter, &perf_reg);
61986 + break;
61987 + case E_FMAN_PORT_TYPE_OP:
61988 + case E_FMAN_PORT_TYPE_HC:
61989 + get_oh_perf_reg(port, counter, &perf_reg);
61990 + break;
61991 + default:
61992 + perf_reg = NULL;
61993 + }
61994 +
61995 + if (perf_reg == NULL)
61996 + return 0;
61997 +
61998 + ret_val = ioread32be(perf_reg);
61999 + return ret_val;
62000 +}
62001 +
62002 +void fman_port_set_perf_counter(struct fman_port *port,
62003 + enum fman_port_perf_counters counter,
62004 + uint32_t value)
62005 +{
62006 + uint32_t *perf_reg;
62007 +
62008 + switch (port->type) {
62009 + case E_FMAN_PORT_TYPE_RX:
62010 + case E_FMAN_PORT_TYPE_RX_10G:
62011 + get_rx_perf_reg(port, counter, &perf_reg);
62012 + break;
62013 + case E_FMAN_PORT_TYPE_TX:
62014 + case E_FMAN_PORT_TYPE_TX_10G:
62015 + get_tx_perf_reg(port, counter, &perf_reg);
62016 + break;
62017 + case E_FMAN_PORT_TYPE_OP:
62018 + case E_FMAN_PORT_TYPE_HC:
62019 + get_oh_perf_reg(port, counter, &perf_reg);
62020 + break;
62021 + default:
62022 + perf_reg = NULL;
62023 + }
62024 +
62025 + if (perf_reg == NULL)
62026 + return;
62027 +
62028 + iowrite32be(value, perf_reg);
62029 +}
62030 +
62031 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
62032 + enum fman_port_qmi_counters counter)
62033 +{
62034 + uint32_t *queue_reg, ret_val;
62035 +
62036 + get_qmi_counter_reg(port, counter, &queue_reg);
62037 +
62038 + if (queue_reg == NULL)
62039 + return 0;
62040 +
62041 + ret_val = ioread32be(queue_reg);
62042 + return ret_val;
62043 +}
62044 +
62045 +void fman_port_set_qmi_counter(struct fman_port *port,
62046 + enum fman_port_qmi_counters counter,
62047 + uint32_t value)
62048 +{
62049 + uint32_t *queue_reg;
62050 +
62051 + get_qmi_counter_reg(port, counter, &queue_reg);
62052 +
62053 + if (queue_reg == NULL)
62054 + return;
62055 +
62056 + iowrite32be(value, queue_reg);
62057 +}
62058 +
62059 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid)
62060 +{
62061 + uint8_t index;
62062 + uint32_t ret_val;
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 0;
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 0;
62077 +
62078 + ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]);
62079 + return ret_val;
62080 +}
62081 +
62082 +void fman_port_set_bpool_counter(struct fman_port *port,
62083 + uint8_t bpid,
62084 + uint32_t value)
62085 +{
62086 + uint8_t index;
62087 +
62088 + switch (port->type) {
62089 + case E_FMAN_PORT_TYPE_RX:
62090 + case E_FMAN_PORT_TYPE_RX_10G:
62091 + break;
62092 + default:
62093 + return;
62094 + }
62095 +
62096 + /* Find the pool */
62097 + index = fman_port_find_bpool(port, bpid);
62098 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
62099 + /* Not found */
62100 + return;
62101 +
62102 + iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]);
62103 +}
62104 +
62105 +int fman_port_add_congestion_grps(struct fman_port *port,
62106 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
62107 +{
62108 + int i;
62109 + uint32_t tmp, *grp_map_reg;
62110 + uint8_t max_grp_map_num;
62111 +
62112 + switch (port->type) {
62113 + case E_FMAN_PORT_TYPE_RX:
62114 + case E_FMAN_PORT_TYPE_RX_10G:
62115 + if (port->fm_rev_maj == 4)
62116 + max_grp_map_num = 1;
62117 + else
62118 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
62119 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
62120 + break;
62121 + case E_FMAN_PORT_TYPE_OP:
62122 + max_grp_map_num = 1;
62123 + if (port->fm_rev_maj != 4)
62124 + return -EINVAL;
62125 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
62126 + break;
62127 + default:
62128 + return -EINVAL;
62129 + }
62130 +
62131 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
62132 + if (grps_map[i] == 0)
62133 + continue;
62134 + tmp = ioread32be(&grp_map_reg[i]);
62135 + tmp |= grps_map[i];
62136 + iowrite32be(tmp, &grp_map_reg[i]);
62137 + }
62138 +
62139 + return 0;
62140 +}
62141 +
62142 +int fman_port_remove_congestion_grps(struct fman_port *port,
62143 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
62144 +{
62145 + int i;
62146 + uint32_t tmp, *grp_map_reg;
62147 + uint8_t max_grp_map_num;
62148 +
62149 + switch (port->type) {
62150 + case E_FMAN_PORT_TYPE_RX:
62151 + case E_FMAN_PORT_TYPE_RX_10G:
62152 + if (port->fm_rev_maj == 4)
62153 + max_grp_map_num = 1;
62154 + else
62155 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
62156 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
62157 + break;
62158 + case E_FMAN_PORT_TYPE_OP:
62159 + max_grp_map_num = 1;
62160 + if (port->fm_rev_maj != 4)
62161 + return -EINVAL;
62162 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
62163 + break;
62164 + default:
62165 + return -EINVAL;
62166 + }
62167 +
62168 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
62169 + if (grps_map[i] == 0)
62170 + continue;
62171 + tmp = ioread32be(&grp_map_reg[i]);
62172 + tmp &= ~grps_map[i];
62173 + iowrite32be(tmp, &grp_map_reg[i]);
62174 + }
62175 + return 0;
62176 +}
62177 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
62178 new file mode 100644
62179 index 00000000..d2c21d34
62180 --- /dev/null
62181 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
62182 @@ -0,0 +1,15 @@
62183 +#
62184 +# Makefile for the Freescale Ethernet controllers
62185 +#
62186 +ccflags-y += -DVERSION=\"\"
62187 +#
62188 +#Include netcomm SW specific definitions
62189 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
62190 +
62191 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
62192 +
62193 +ccflags-y += -I$(NCSW_FM_INC)
62194 +
62195 +obj-y += fsl-ncsw-RTC.o
62196 +
62197 +fsl-ncsw-RTC-objs := fm_rtc.o fman_rtc.o
62198 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
62199 new file mode 100644
62200 index 00000000..99de427b
62201 --- /dev/null
62202 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
62203 @@ -0,0 +1,692 @@
62204 +/*
62205 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62206 + *
62207 + * Redistribution and use in source and binary forms, with or without
62208 + * modification, are permitted provided that the following conditions are met:
62209 + * * Redistributions of source code must retain the above copyright
62210 + * notice, this list of conditions and the following disclaimer.
62211 + * * Redistributions in binary form must reproduce the above copyright
62212 + * notice, this list of conditions and the following disclaimer in the
62213 + * documentation and/or other materials provided with the distribution.
62214 + * * Neither the name of Freescale Semiconductor nor the
62215 + * names of its contributors may be used to endorse or promote products
62216 + * derived from this software without specific prior written permission.
62217 + *
62218 + *
62219 + * ALTERNATIVELY, this software may be distributed under the terms of the
62220 + * GNU General Public License ("GPL") as published by the Free Software
62221 + * Foundation, either version 2 of that License or (at your option) any
62222 + * later version.
62223 + *
62224 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62225 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62226 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62227 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62228 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62229 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62230 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62231 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62232 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62233 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62234 + */
62235 +
62236 +
62237 +/******************************************************************************
62238 + @File fm_rtc.c
62239 +
62240 + @Description FM RTC driver implementation.
62241 +
62242 + @Cautions None
62243 +*//***************************************************************************/
62244 +#include <linux/math64.h>
62245 +#include "error_ext.h"
62246 +#include "debug_ext.h"
62247 +#include "string_ext.h"
62248 +#include "part_ext.h"
62249 +#include "xx_ext.h"
62250 +#include "ncsw_ext.h"
62251 +
62252 +#include "fm_rtc.h"
62253 +#include "fm_common.h"
62254 +
62255 +
62256 +
62257 +/*****************************************************************************/
62258 +static t_Error CheckInitParameters(t_FmRtc *p_Rtc)
62259 +{
62260 + struct rtc_cfg *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62261 + int i;
62262 +
62263 + if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) &&
62264 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) &&
62265 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR))
62266 + RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined"));
62267 +
62268 + if (p_Rtc->outputClockDivisor == 0)
62269 + {
62270 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
62271 + ("Divisor for output clock (should be positive)"));
62272 + }
62273 +
62274 + for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
62275 + {
62276 + if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) &&
62277 + (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH))
62278 + {
62279 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i));
62280 + }
62281 + }
62282 + for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
62283 + {
62284 + if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) &&
62285 + (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE))
62286 + {
62287 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i));
62288 + }
62289 + }
62290 +
62291 + return E_OK;
62292 +}
62293 +
62294 +/*****************************************************************************/
62295 +static void RtcExceptions(t_Handle h_FmRtc)
62296 +{
62297 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62298 + struct rtc_regs *p_MemMap;
62299 + register uint32_t events;
62300 +
62301 + ASSERT_COND(p_Rtc);
62302 + p_MemMap = p_Rtc->p_MemMap;
62303 +
62304 + events = fman_rtc_check_and_clear_event(p_MemMap);
62305 + if (events & FMAN_RTC_TMR_TEVENT_ALM1)
62306 + {
62307 + if (p_Rtc->alarmParams[0].clearOnExpiration)
62308 + {
62309 + fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0);
62310 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1);
62311 + }
62312 + ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback);
62313 + p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0);
62314 + }
62315 + if (events & FMAN_RTC_TMR_TEVENT_ALM2)
62316 + {
62317 + if (p_Rtc->alarmParams[1].clearOnExpiration)
62318 + {
62319 + fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0);
62320 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2);
62321 + }
62322 + ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback);
62323 + p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1);
62324 + }
62325 + if (events & FMAN_RTC_TMR_TEVENT_PP1)
62326 + {
62327 + ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback);
62328 + p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0);
62329 + }
62330 + if (events & FMAN_RTC_TMR_TEVENT_PP2)
62331 + {
62332 + ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback);
62333 + p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1);
62334 + }
62335 + if (events & FMAN_RTC_TMR_TEVENT_ETS1)
62336 + {
62337 + ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback);
62338 + p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0);
62339 + }
62340 + if (events & FMAN_RTC_TMR_TEVENT_ETS2)
62341 + {
62342 + ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback);
62343 + p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1);
62344 + }
62345 +}
62346 +
62347 +
62348 +/*****************************************************************************/
62349 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam)
62350 +{
62351 + t_FmRtc *p_Rtc;
62352 +
62353 + SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL);
62354 +
62355 + /* Allocate memory for the FM RTC driver parameters */
62356 + p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc));
62357 + if (!p_Rtc)
62358 + {
62359 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure"));
62360 + return NULL;
62361 + }
62362 +
62363 + memset(p_Rtc, 0, sizeof(t_FmRtc));
62364 +
62365 + /* Allocate memory for the FM RTC driver parameters */
62366 + p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg));
62367 + if (!p_Rtc->p_RtcDriverParam)
62368 + {
62369 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters"));
62370 + XX_Free(p_Rtc);
62371 + return NULL;
62372 + }
62373 +
62374 + memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg));
62375 +
62376 + /* Store RTC configuration parameters */
62377 + p_Rtc->h_Fm = p_FmRtcParam->h_Fm;
62378 +
62379 + /* Set default RTC configuration parameters */
62380 + fman_rtc_defconfig(p_Rtc->p_RtcDriverParam);
62381 +
62382 + p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR;
62383 + p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS;
62384 + p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */
62385 +
62386 +
62387 + /* Store RTC parameters in the RTC control structure */
62388 + p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress);
62389 + p_Rtc->h_App = p_FmRtcParam->h_App;
62390 +
62391 + return p_Rtc;
62392 +}
62393 +
62394 +/*****************************************************************************/
62395 +t_Error FM_RTC_Init(t_Handle h_FmRtc)
62396 +{
62397 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62398 + struct rtc_cfg *p_RtcDriverParam;
62399 + struct rtc_regs *p_MemMap;
62400 + uint32_t freqCompensation = 0;
62401 + uint64_t tmpDouble;
62402 + bool init_freq_comp = FALSE;
62403 +
62404 + p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62405 + p_MemMap = p_Rtc->p_MemMap;
62406 +
62407 + if (CheckInitParameters(p_Rtc)!=E_OK)
62408 + RETURN_ERROR(MAJOR, E_CONFLICT,
62409 + ("Init Parameters are not Valid"));
62410 +
62411 + /* TODO check that no timestamping MACs are working in this stage. */
62412 +
62413 + /* find source clock frequency in Mhz */
62414 + if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM)
62415 + p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq;
62416 + else
62417 + p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm));
62418 +
62419 + /* if timer in Master mode Initialize TMR_CTRL */
62420 + /* We want the counter (TMR_CNT) to count in nano-seconds */
62421 + if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass)
62422 + p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz);
62423 + else
62424 + {
62425 + /* Initialize TMR_ADD with the initial frequency compensation value:
62426 + freqCompensation = (2^32 / frequency ratio) */
62427 + /* frequency ratio = sorce clock/rtc clock =
62428 + * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */
62429 + init_freq_comp = TRUE;
62430 + freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
62431 + p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
62432 + }
62433 +
62434 + /* check the legality of the relation between source and destination clocks */
62435 + /* should be larger than 1.0001 */
62436 + tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz;
62437 + if ((tmpDouble) <= 10001)
62438 + RETURN_ERROR(MAJOR, E_CONFLICT,
62439 + ("Invalid relation between source and destination clocks. Should be larger than 1.0001"));
62440 +
62441 + fman_rtc_init(p_RtcDriverParam,
62442 + p_MemMap,
62443 + FM_RTC_NUM_OF_ALARMS,
62444 + FM_RTC_NUM_OF_PERIODIC_PULSES,
62445 + FM_RTC_NUM_OF_EXT_TRIGGERS,
62446 + init_freq_comp,
62447 + freqCompensation,
62448 + p_Rtc->outputClockDivisor);
62449 +
62450 + /* Register the FM RTC interrupt */
62451 + FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc);
62452 +
62453 + /* Free parameters structures */
62454 + XX_Free(p_Rtc->p_RtcDriverParam);
62455 + p_Rtc->p_RtcDriverParam = NULL;
62456 +
62457 + return E_OK;
62458 +}
62459 +
62460 +/*****************************************************************************/
62461 +t_Error FM_RTC_Free(t_Handle h_FmRtc)
62462 +{
62463 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62464 +
62465 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62466 +
62467 + if (p_Rtc->p_RtcDriverParam)
62468 + {
62469 + XX_Free(p_Rtc->p_RtcDriverParam);
62470 + }
62471 + else
62472 + {
62473 + FM_RTC_Disable(h_FmRtc);
62474 + }
62475 +
62476 + /* Unregister FM RTC interrupt */
62477 + FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL);
62478 + XX_Free(p_Rtc);
62479 +
62480 + return E_OK;
62481 +}
62482 +
62483 +/*****************************************************************************/
62484 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
62485 + e_FmSrcClk srcClk,
62486 + uint32_t freqInMhz)
62487 +{
62488 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62489 +
62490 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62491 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62492 +
62493 + p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk;
62494 + if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
62495 + p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz;
62496 +
62497 + return E_OK;
62498 +}
62499 +
62500 +/*****************************************************************************/
62501 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period)
62502 +{
62503 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62504 +
62505 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62506 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62507 +
62508 + p_Rtc->clockPeriodNanoSec = period;
62509 +
62510 + return E_OK;
62511 +}
62512 +
62513 +/*****************************************************************************/
62514 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled)
62515 +{
62516 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62517 +
62518 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62519 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62520 +
62521 + p_Rtc->p_RtcDriverParam->bypass = enabled;
62522 +
62523 + return E_OK;
62524 +}
62525 +
62526 +/*****************************************************************************/
62527 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted)
62528 +{
62529 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62530 +
62531 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62532 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62533 +
62534 + p_Rtc->p_RtcDriverParam->invert_input_clk_phase = inverted;
62535 +
62536 + return E_OK;
62537 +}
62538 +
62539 +/*****************************************************************************/
62540 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted)
62541 +{
62542 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62543 +
62544 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62545 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62546 +
62547 + p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted;
62548 +
62549 + return E_OK;
62550 +}
62551 +
62552 +/*****************************************************************************/
62553 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor)
62554 +{
62555 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62556 +
62557 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62558 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62559 +
62560 + p_Rtc->outputClockDivisor = divisor;
62561 +
62562 + return E_OK;
62563 +}
62564 +
62565 +/*****************************************************************************/
62566 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable)
62567 +{
62568 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62569 +
62570 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62571 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62572 +
62573 + p_Rtc->p_RtcDriverParam->pulse_realign = enable;
62574 +
62575 + return E_OK;
62576 +}
62577 +
62578 +/*****************************************************************************/
62579 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
62580 + uint8_t alarmId,
62581 + e_FmRtcAlarmPolarity alarmPolarity)
62582 +{
62583 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62584 +
62585 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62586 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62587 +
62588 + if (alarmId >= FM_RTC_NUM_OF_ALARMS)
62589 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62590 +
62591 + p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] =
62592 + (enum fman_rtc_alarm_polarity)alarmPolarity;
62593 +
62594 + return E_OK;
62595 +}
62596 +
62597 +/*****************************************************************************/
62598 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
62599 + uint8_t triggerId,
62600 + e_FmRtcTriggerPolarity triggerPolarity)
62601 +{
62602 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62603 +
62604 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62605 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62606 +
62607 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62608 + {
62609 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62610 + }
62611 +
62612 + p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] =
62613 + (enum fman_rtc_trigger_polarity)triggerPolarity;
62614 +
62615 + return E_OK;
62616 +}
62617 +
62618 +/*****************************************************************************/
62619 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock)
62620 +{
62621 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62622 +
62623 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62624 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62625 +
62626 + fman_rtc_enable(p_Rtc->p_MemMap, resetClock);
62627 + return E_OK;
62628 +}
62629 +
62630 +/*****************************************************************************/
62631 +t_Error FM_RTC_Disable(t_Handle h_FmRtc)
62632 +{
62633 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62634 +
62635 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62636 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62637 +
62638 + /* TODO A check must be added here, that no timestamping MAC's
62639 + * are working in this stage. */
62640 + fman_rtc_disable(p_Rtc->p_MemMap);
62641 +
62642 + return E_OK;
62643 +}
62644 +
62645 +/*****************************************************************************/
62646 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset)
62647 +{
62648 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62649 +
62650 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62651 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62652 +
62653 + fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset);
62654 + return E_OK;
62655 +}
62656 +
62657 +/*****************************************************************************/
62658 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams)
62659 +{
62660 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62661 + uint64_t tmpAlarm;
62662 + bool enable = FALSE;
62663 +
62664 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62665 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62666 +
62667 + if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS)
62668 + {
62669 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62670 + }
62671 +
62672 + if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec)
62673 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62674 + ("Alarm time must be equal or larger than RTC period - %d nanoseconds",
62675 + p_Rtc->clockPeriodNanoSec));
62676 + tmpAlarm = p_FmRtcAlarmParams->alarmTime;
62677 + if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec))
62678 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62679 + ("Alarm time must be a multiple of RTC period - %d nanoseconds",
62680 + p_Rtc->clockPeriodNanoSec));
62681 +
62682 + if (p_FmRtcAlarmParams->f_AlarmCallback)
62683 + {
62684 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback;
62685 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration;
62686 + enable = TRUE;
62687 + }
62688 +
62689 + fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable);
62690 +
62691 + return E_OK;
62692 +}
62693 +
62694 +/*****************************************************************************/
62695 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams)
62696 +{
62697 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62698 + bool enable = FALSE;
62699 + uint64_t tmpFiper;
62700 +
62701 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62702 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62703 +
62704 + if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62705 + {
62706 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62707 + }
62708 + if (fman_rtc_is_enabled(p_Rtc->p_MemMap))
62709 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled."));
62710 + if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec)
62711 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62712 + ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds",
62713 + p_Rtc->clockPeriodNanoSec));
62714 + tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod;
62715 + if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec))
62716 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62717 + ("Periodic pulse must be a multiple of RTC period - %d nanoseconds",
62718 + p_Rtc->clockPeriodNanoSec));
62719 + if (tmpFiper & 0xffffffff00000000LL)
62720 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62721 + ("Periodic pulse/RTC Period must be smaller than 4294967296",
62722 + p_Rtc->clockPeriodNanoSec));
62723 +
62724 + if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback)
62725 + {
62726 + p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback =
62727 + p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback;
62728 + enable = TRUE;
62729 + }
62730 + fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable);
62731 + return E_OK;
62732 +}
62733 +
62734 +/*****************************************************************************/
62735 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId)
62736 +{
62737 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62738 +
62739 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62740 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62741 +
62742 + if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62743 + {
62744 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62745 + }
62746 +
62747 + p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL;
62748 + fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId);
62749 +
62750 + return E_OK;
62751 +}
62752 +
62753 +/*****************************************************************************/
62754 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams)
62755 +{
62756 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62757 + bool enable = FALSE;
62758 +
62759 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62760 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62761 +
62762 + if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62763 + {
62764 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62765 + }
62766 +
62767 + if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback)
62768 + {
62769 + p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback;
62770 + enable = TRUE;
62771 + }
62772 +
62773 + fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput);
62774 + return E_OK;
62775 +}
62776 +
62777 +/*****************************************************************************/
62778 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId)
62779 +{
62780 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62781 +
62782 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62783 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62784 +
62785 + if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62786 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62787 +
62788 + p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL;
62789 +
62790 + fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId);
62791 +
62792 + return E_OK;
62793 +}
62794 +
62795 +/*****************************************************************************/
62796 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
62797 + uint8_t triggerId,
62798 + uint64_t *p_TimeStamp)
62799 +{
62800 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62801 +
62802 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62803 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62804 +
62805 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62806 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62807 +
62808 + *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec;
62809 +
62810 + return E_OK;
62811 +}
62812 +
62813 +/*****************************************************************************/
62814 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts)
62815 +{
62816 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62817 +
62818 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62819 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62820 +
62821 + *p_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec;
62822 +
62823 + return E_OK;
62824 +}
62825 +
62826 +/*****************************************************************************/
62827 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts)
62828 +{
62829 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62830 +
62831 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62832 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62833 +
62834 + do_div(ts, p_Rtc->clockPeriodNanoSec);
62835 + fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts);
62836 +
62837 + return E_OK;
62838 +}
62839 +
62840 +/*****************************************************************************/
62841 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation)
62842 +{
62843 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62844 +
62845 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62846 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62847 +
62848 + *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap);
62849 +
62850 + return E_OK;
62851 +}
62852 +
62853 +/*****************************************************************************/
62854 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation)
62855 +{
62856 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62857 +
62858 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62859 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62860 +
62861 + /* set the new freqCompensation */
62862 + fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation);
62863 +
62864 + return E_OK;
62865 +}
62866 +
62867 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
62868 +/*****************************************************************************/
62869 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events)
62870 +{
62871 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62872 +
62873 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62874 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62875 +
62876 + /* enable interrupt */
62877 + fman_rtc_enable_interupt(p_Rtc->p_MemMap, events);
62878 +
62879 + return E_OK;
62880 +}
62881 +
62882 +/*****************************************************************************/
62883 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events)
62884 +{
62885 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62886 +
62887 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62888 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62889 +
62890 + /* disable interrupt */
62891 + fman_rtc_disable_interupt(p_Rtc->p_MemMap, events);
62892 +
62893 + return E_OK;
62894 +}
62895 +#endif
62896 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
62897 new file mode 100644
62898 index 00000000..843ca008
62899 --- /dev/null
62900 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
62901 @@ -0,0 +1,96 @@
62902 +/*
62903 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62904 + *
62905 + * Redistribution and use in source and binary forms, with or without
62906 + * modification, are permitted provided that the following conditions are met:
62907 + * * Redistributions of source code must retain the above copyright
62908 + * notice, this list of conditions and the following disclaimer.
62909 + * * Redistributions in binary form must reproduce the above copyright
62910 + * notice, this list of conditions and the following disclaimer in the
62911 + * documentation and/or other materials provided with the distribution.
62912 + * * Neither the name of Freescale Semiconductor nor the
62913 + * names of its contributors may be used to endorse or promote products
62914 + * derived from this software without specific prior written permission.
62915 + *
62916 + *
62917 + * ALTERNATIVELY, this software may be distributed under the terms of the
62918 + * GNU General Public License ("GPL") as published by the Free Software
62919 + * Foundation, either version 2 of that License or (at your option) any
62920 + * later version.
62921 + *
62922 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62923 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62924 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62925 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62926 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62927 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62928 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62929 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62930 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62931 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62932 + */
62933 +
62934 +
62935 +/******************************************************************************
62936 + @File fm_rtc.h
62937 +
62938 + @Description Memory map and internal definitions for FM RTC IEEE1588 Timer driver.
62939 +
62940 + @Cautions None
62941 +*//***************************************************************************/
62942 +
62943 +#ifndef __FM_RTC_H__
62944 +#define __FM_RTC_H__
62945 +
62946 +#include "std_ext.h"
62947 +#include "fm_rtc_ext.h"
62948 +
62949 +
62950 +#define __ERR_MODULE__ MODULE_FM_RTC
62951 +
62952 +/* General definitions */
62953 +
62954 +#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32))
62955 +#define DEFAULT_OUTPUT_CLOCK_DIVISOR 0x00000002
62956 +#define DEFAULT_BYPASS FALSE
62957 +#define DEFAULT_CLOCK_PERIOD 1000
62958 +
62959 +
62960 +
62961 +typedef struct t_FmRtcAlarm
62962 +{
62963 + t_FmRtcExceptionsCallback *f_AlarmCallback;
62964 + bool clearOnExpiration;
62965 +} t_FmRtcAlarm;
62966 +
62967 +typedef struct t_FmRtcPeriodicPulse
62968 +{
62969 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback;
62970 +} t_FmRtcPeriodicPulse;
62971 +
62972 +typedef struct t_FmRtcExternalTrigger
62973 +{
62974 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback;
62975 +} t_FmRtcExternalTrigger;
62976 +
62977 +
62978 +/**************************************************************************//**
62979 + @Description RTC FM driver control structure.
62980 +*//***************************************************************************/
62981 +typedef struct t_FmRtc
62982 +{
62983 + t_Part *p_Part; /**< Pointer to the integration device */
62984 + t_Handle h_Fm;
62985 + t_Handle h_App; /**< Application handle */
62986 + struct rtc_regs *p_MemMap;
62987 + uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */
62988 + uint32_t srcClkFreqMhz;
62989 + uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */
62990 + t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS];
62991 + t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES];
62992 + t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS];
62993 + struct rtc_cfg *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */
62994 +} t_FmRtc;
62995 +
62996 +
62997 +#endif /* __FM_RTC_H__ */
62998 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
62999 new file mode 100755
63000 index 00000000..acdf507e
63001 --- /dev/null
63002 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
63003 @@ -0,0 +1,334 @@
63004 +/*
63005 + * Copyright 2008-2013 Freescale Semiconductor Inc.
63006 + *
63007 + * Redistribution and use in source and binary forms, with or without
63008 + * modification, are permitted provided that the following conditions are met:
63009 + * * Redistributions of source code must retain the above copyright
63010 + * notice, this list of conditions and the following disclaimer.
63011 + * * Redistributions in binary form must reproduce the above copyright
63012 + * notice, this list of conditions and the following disclaimer in the
63013 + * documentation and/or other materials provided with the distribution.
63014 + * * Neither the name of Freescale Semiconductor nor the
63015 + * names of its contributors may be used to endorse or promote products
63016 + * derived from this software without specific prior written permission.
63017 + *
63018 + *
63019 + * ALTERNATIVELY, this software may be distributed under the terms of the
63020 + * GNU General Public License ("GPL") as published by the Free Software
63021 + * Foundation, either version 2 of that License or (at your option) any
63022 + * later version.
63023 + *
63024 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63025 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63026 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63027 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63028 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63029 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63030 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63031 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63032 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63033 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63034 + */
63035 +
63036 +#include "fsl_fman_rtc.h"
63037 +
63038 +void fman_rtc_defconfig(struct rtc_cfg *cfg)
63039 +{
63040 + int i;
63041 + cfg->src_clk = DEFAULT_SRC_CLOCK;
63042 + cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE;
63043 + cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE;
63044 + cfg->pulse_realign = DEFAULT_PULSE_REALIGN;
63045 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++)
63046 + cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY;
63047 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++)
63048 + cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY;
63049 +}
63050 +
63051 +uint32_t fman_rtc_get_events(struct rtc_regs *regs)
63052 +{
63053 + return ioread32be(&regs->tmr_tevent);
63054 +}
63055 +
63056 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask)
63057 +{
63058 + return ioread32be(&regs->tmr_tevent) & ev_mask;
63059 +}
63060 +
63061 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs)
63062 +{
63063 + return ioread32be(&regs->tmr_temask);
63064 +}
63065 +
63066 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask)
63067 +{
63068 + iowrite32be(mask, &regs->tmr_temask);
63069 +}
63070 +
63071 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events)
63072 +{
63073 + iowrite32be(events, &regs->tmr_tevent);
63074 +}
63075 +
63076 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs)
63077 +{
63078 + uint32_t event;
63079 +
63080 + event = ioread32be(&regs->tmr_tevent);
63081 + event &= ioread32be(&regs->tmr_temask);
63082 +
63083 + if (event)
63084 + iowrite32be(event, &regs->tmr_tevent);
63085 + return event;
63086 +}
63087 +
63088 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs)
63089 +{
63090 + return ioread32be(&regs->tmr_add);
63091 +}
63092 +
63093 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val)
63094 +{
63095 + iowrite32be(val, &regs->tmr_add);
63096 +}
63097 +
63098 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events)
63099 +{
63100 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events);
63101 +}
63102 +
63103 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events)
63104 +{
63105 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events);
63106 +}
63107 +
63108 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val)
63109 +{
63110 + iowrite32be(val, &regs->tmr_alarm[index].tmr_alarm_l);
63111 +}
63112 +
63113 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val)
63114 +{
63115 + iowrite32be(val, &regs->tmr_fiper[index]);
63116 +}
63117 +
63118 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val)
63119 +{
63120 + iowrite32be((uint32_t)val, &regs->tmr_alarm[index].tmr_alarm_l);
63121 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_alarm[index].tmr_alarm_h);
63122 +}
63123 +
63124 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val)
63125 +{
63126 + iowrite32be((uint32_t)val, &regs->tmr_off_l);
63127 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_off_h);
63128 +}
63129 +
63130 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id)
63131 +{
63132 + uint64_t time;
63133 + /* TMR_CNT_L must be read first to get an accurate value */
63134 + time = (uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_l);
63135 + time |= ((uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_h)
63136 + << 32);
63137 +
63138 + return time;
63139 +}
63140 +
63141 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs)
63142 +{
63143 + return ioread32be(&regs->tmr_ctrl);
63144 +}
63145 +
63146 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val)
63147 +{
63148 + iowrite32be(val, &regs->tmr_ctrl);
63149 +}
63150 +
63151 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs)
63152 +{
63153 + fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR);
63154 + udelay(10);
63155 + fman_rtc_set_timer_ctrl(regs, 0);
63156 +}
63157 +
63158 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
63159 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
63160 + uint32_t freq_compensation, uint32_t output_clock_divisor)
63161 +{
63162 + uint32_t tmr_ctrl;
63163 + int i;
63164 +
63165 + fman_rtc_timers_soft_reset(regs);
63166 +
63167 + /* Set the source clock */
63168 + switch (cfg->src_clk) {
63169 + case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM:
63170 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK;
63171 + break;
63172 + case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR:
63173 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK;
63174 + break;
63175 + default:
63176 + /* Use a clock from the External TMR reference clock.*/
63177 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK;
63178 + break;
63179 + }
63180 +
63181 + /* whatever period the user picked, the timestamp will advance in '1'
63182 + * every time the period passed. */
63183 + tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) &
63184 + FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK);
63185 +
63186 + if (cfg->invert_input_clk_phase)
63187 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH;
63188 + if (cfg->invert_output_clk_phase)
63189 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH;
63190 +
63191 + for (i = 0; i < num_alarms; i++) {
63192 + if (cfg->alarm_polarity[i] ==
63193 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW)
63194 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i);
63195 + }
63196 +
63197 + for (i = 0; i < num_ext_triggers; i++)
63198 + if (cfg->trigger_polarity[i] ==
63199 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE)
63200 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i);
63201 +
63202 + if (!cfg->timer_slave_mode && cfg->bypass)
63203 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP;
63204 +
63205 + fman_rtc_set_timer_ctrl(regs, tmr_ctrl);
63206 + if (init_freq_comp)
63207 + fman_rtc_set_frequency_compensation(regs, freq_compensation);
63208 +
63209 + /* Clear TMR_ALARM registers */
63210 + for (i = 0; i < num_alarms; i++)
63211 + fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL);
63212 +
63213 + /* Clear TMR_TEVENT */
63214 + fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL);
63215 +
63216 + /* Initialize TMR_TEMASK */
63217 + fman_rtc_set_interrupt_mask(regs, 0);
63218 +
63219 + /* Clear TMR_FIPER registers */
63220 + for (i = 0; i < num_fipers; i++)
63221 + fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF);
63222 +
63223 + /* Initialize TMR_PRSC */
63224 + iowrite32be(output_clock_divisor, &regs->tmr_prsc);
63225 +
63226 + /* Clear TMR_OFF */
63227 + fman_rtc_set_timer_offset(regs, 0);
63228 +}
63229 +
63230 +bool fman_rtc_is_enabled(struct rtc_regs *regs)
63231 +{
63232 + return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE);
63233 +}
63234 +
63235 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock)
63236 +{
63237 + uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs);
63238 +
63239 + /* TODO check that no timestamping MACs are working in this stage. */
63240 + if (reset_clock) {
63241 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR));
63242 +
63243 + udelay(10);
63244 + /* Clear TMR_OFF */
63245 + fman_rtc_set_timer_offset(regs, 0);
63246 + }
63247 +
63248 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE));
63249 +}
63250 +
63251 +void fman_rtc_disable(struct rtc_regs *regs)
63252 +{
63253 + fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs)
63254 + & ~(FMAN_RTC_TMR_CTRL_TE)));
63255 +}
63256 +
63257 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id)
63258 +{
63259 + uint32_t tmp_reg;
63260 + if (id == 0)
63261 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP1;
63262 + else
63263 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP2;
63264 + fman_rtc_disable_interupt(regs, tmp_reg);
63265 +
63266 + tmp_reg = fman_rtc_get_timer_ctrl(regs);
63267 + if (tmp_reg & FMAN_RTC_TMR_CTRL_FS)
63268 + fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS);
63269 +
63270 + fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF);
63271 +}
63272 +
63273 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id)
63274 +{
63275 + uint32_t tmpReg, tmp_ctrl;
63276 +
63277 + if (id == 0)
63278 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
63279 + else
63280 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
63281 + fman_rtc_disable_interupt(regs, tmpReg);
63282 +
63283 + if (id == 0)
63284 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
63285 + else
63286 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
63287 + tmp_ctrl = fman_rtc_get_timer_ctrl(regs);
63288 + if (tmp_ctrl & tmpReg)
63289 + fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg);
63290 +}
63291 +
63292 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable)
63293 +{
63294 + uint32_t tmpReg;
63295 + fman_rtc_set_timer_alarm(regs, id, val);
63296 + if (enable) {
63297 + if (id == 0)
63298 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM1;
63299 + else
63300 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM2;
63301 + fman_rtc_enable_interupt(regs, tmpReg);
63302 + }
63303 +}
63304 +
63305 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
63306 + bool enable)
63307 +{
63308 + uint32_t tmpReg;
63309 + fman_rtc_set_timer_fiper(regs, id, val);
63310 + if (enable) {
63311 + if (id == 0)
63312 + tmpReg = FMAN_RTC_TMR_TEVENT_PP1;
63313 + else
63314 + tmpReg = FMAN_RTC_TMR_TEVENT_PP2;
63315 + fman_rtc_enable_interupt(regs, tmpReg);
63316 + }
63317 +}
63318 +
63319 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
63320 + bool use_pulse_as_input)
63321 +{
63322 + uint32_t tmpReg;
63323 + if (enable) {
63324 + if (id == 0)
63325 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
63326 + else
63327 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
63328 + fman_rtc_enable_interupt(regs, tmpReg);
63329 + }
63330 + if (use_pulse_as_input) {
63331 + if (id == 0)
63332 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
63333 + else
63334 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
63335 + fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg);
63336 + }
63337 +}
63338 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
63339 new file mode 100644
63340 index 00000000..fae50ce4
63341 --- /dev/null
63342 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
63343 @@ -0,0 +1,15 @@
63344 +#
63345 +# Makefile for the Freescale Ethernet controllers
63346 +#
63347 +ccflags-y += -DVERSION=\"\"
63348 +#
63349 +#Include netcomm SW specific definitions
63350 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
63351 +
63352 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
63353 +
63354 +ccflags-y += -I$(NCSW_FM_INC)
63355 +
63356 +obj-y += fsl-ncsw-sp.o
63357 +
63358 +fsl-ncsw-sp-objs := fm_sp.o fman_sp.o
63359 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
63360 new file mode 100644
63361 index 00000000..0994f34d
63362 --- /dev/null
63363 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
63364 @@ -0,0 +1,757 @@
63365 +/*
63366 + * Copyright 2008-2012 Freescale Semiconductor Inc.
63367 + *
63368 + * Redistribution and use in source and binary forms, with or without
63369 + * modification, are permitted provided that the following conditions are met:
63370 + * * Redistributions of source code must retain the above copyright
63371 + * notice, this list of conditions and the following disclaimer.
63372 + * * Redistributions in binary form must reproduce the above copyright
63373 + * notice, this list of conditions and the following disclaimer in the
63374 + * documentation and/or other materials provided with the distribution.
63375 + * * Neither the name of Freescale Semiconductor nor the
63376 + * names of its contributors may be used to endorse or promote products
63377 + * derived from this software without specific prior written permission.
63378 + *
63379 + *
63380 + * ALTERNATIVELY, this software may be distributed under the terms of the
63381 + * GNU General Public License ("GPL") as published by the Free Software
63382 + * Foundation, either version 2 of that License or (at your option) any
63383 + * later version.
63384 + *
63385 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63386 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63387 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63388 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63389 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63390 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63391 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63392 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63393 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63394 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63395 + */
63396 +
63397 +
63398 +/******************************************************************************
63399 + @File fm_sp.c
63400 +
63401 + @Description FM PCD Storage profile ...
63402 +*//***************************************************************************/
63403 +
63404 +#include "std_ext.h"
63405 +#include "error_ext.h"
63406 +#include "string_ext.h"
63407 +#include "debug_ext.h"
63408 +#include "net_ext.h"
63409 +
63410 +#include "fm_vsp_ext.h"
63411 +#include "fm_sp.h"
63412 +#include "fm_common.h"
63413 +#include "fsl_fman_sp.h"
63414 +
63415 +
63416 +#if (DPAA_VERSION >= 11)
63417 +static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry)
63418 +{
63419 + t_Error err = E_OK;
63420 +
63421 + if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK)
63422 + RETURN_ERROR(MAJOR, err, NO_MSG);
63423 + if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK)
63424 + RETURN_ERROR(MAJOR, err, NO_MSG);
63425 + return err;
63426 +
63427 +}
63428 +
63429 +static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry)
63430 +{
63431 + t_Error err = E_OK;
63432 +
63433 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63434 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63435 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE);
63436 +
63437 + if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools,
63438 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools,
63439 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK)
63440 +
63441 + RETURN_ERROR(MAJOR, err, NO_MSG);
63442 +
63443 + if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK)
63444 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
63445 +
63446 + err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm,
63447 + p_FmVspEntry->portType,
63448 + p_FmVspEntry->portId,
63449 + p_FmVspEntry->relativeProfileId);
63450 +
63451 + return err;
63452 +}
63453 +#endif /* (DPAA_VERSION >= 11) */
63454 +
63455 +
63456 +/*****************************************************************************/
63457 +/* Inter-module API routines */
63458 +/*****************************************************************************/
63459 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools,
63460 + uint8_t *orderedArray,
63461 + uint16_t *sizesArray)
63462 +{
63463 + uint16_t bufSize = 0;
63464 + int i=0, j=0, k=0;
63465 +
63466 + /* First we copy the external buffers pools information to an ordered local array */
63467 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63468 + {
63469 + /* get pool size */
63470 + bufSize = p_FmExtPools->extBufPool[i].size;
63471 +
63472 + /* keep sizes in an array according to poolId for direct access */
63473 + sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize;
63474 +
63475 + /* save poolId in an ordered array according to size */
63476 + for (j=0;j<=i;j++)
63477 + {
63478 + /* this is the next free place in the array */
63479 + if (j==i)
63480 + orderedArray[i] = p_FmExtPools->extBufPool[i].id;
63481 + else
63482 + {
63483 + /* find the right place for this poolId */
63484 + if (bufSize < sizesArray[orderedArray[j]])
63485 + {
63486 + /* move the poolIds one place ahead to make room for this poolId */
63487 + for (k=i;k>j;k--)
63488 + orderedArray[k] = orderedArray[k-1];
63489 +
63490 + /* now k==j, this is the place for the new size */
63491 + orderedArray[k] = p_FmExtPools->extBufPool[i].id;
63492 + break;
63493 + }
63494 + }
63495 + }
63496 + }
63497 +}
63498 +
63499 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
63500 + t_FmBackupBmPools *p_FmBackupBmPools,
63501 + t_FmBufPoolDepletion *p_FmBufPoolDepletion)
63502 +{
63503 +
63504 + int i = 0, j = 0;
63505 + bool found;
63506 + uint8_t count = 0;
63507 +
63508 + if (p_FmExtPools)
63509 + {
63510 + if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS)
63511 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS));
63512 +
63513 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63514 + {
63515 + if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS)
63516 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS));
63517 + if (!p_FmExtPools->extBufPool[i].size)
63518 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i));
63519 + }
63520 + }
63521 + if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion))
63522 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools"));
63523 +
63524 + /* backup BM pools indication is valid only for some chip derivatives
63525 + (limited by the config routine) */
63526 + if (p_FmBackupBmPools)
63527 + {
63528 + if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed)
63529 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed"));
63530 + found = FALSE;
63531 + for (i = 0;i<p_FmBackupBmPools->numOfBackupPools;i++)
63532 + {
63533 +
63534 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63535 + {
63536 + if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id)
63537 + {
63538 + found = TRUE;
63539 + break;
63540 + }
63541 + }
63542 + if (!found)
63543 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id"));
63544 + else
63545 + found = FALSE;
63546 + }
63547 + }
63548 +
63549 + /* up to extBufPools.numOfPoolsUsed pools may be defined */
63550 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable)
63551 + {
63552 + if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed))
63553 + 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));
63554 +
63555 + if (!p_FmBufPoolDepletion->numOfPools)
63556 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE"));
63557 +
63558 + found = FALSE;
63559 + count = 0;
63560 + /* for each pool that is in poolsToConsider, check if it is defined
63561 + in extBufPool */
63562 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63563 + {
63564 + if (p_FmBufPoolDepletion->poolsToConsider[i])
63565 + {
63566 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63567 + {
63568 + if (i == p_FmExtPools->extBufPool[j].id)
63569 + {
63570 + found = TRUE;
63571 + count++;
63572 + break;
63573 + }
63574 + }
63575 + if (!found)
63576 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63577 + else
63578 + found = FALSE;
63579 + }
63580 + }
63581 + /* check that the number of pools that we have checked is equal to the number announced by the user */
63582 + if (count != p_FmBufPoolDepletion->numOfPools)
63583 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined."));
63584 + }
63585 +
63586 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable)
63587 + {
63588 + /* calculate vector for number of pools depletion */
63589 + found = FALSE;
63590 + count = 0;
63591 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63592 + {
63593 + if (p_FmBufPoolDepletion->poolsToConsiderForSingleMode[i])
63594 + {
63595 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63596 + {
63597 + if (i == p_FmExtPools->extBufPool[j].id)
63598 + {
63599 + found = TRUE;
63600 + count++;
63601 + break;
63602 + }
63603 + }
63604 + if (!found)
63605 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63606 + else
63607 + found = FALSE;
63608 + }
63609 + }
63610 + if (!count)
63611 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion."));
63612 + }
63613 +
63614 + return E_OK;
63615 +}
63616 +
63617 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy)
63618 +{
63619 + /* Check that divisible by 16 and not larger than 240 */
63620 + if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET)
63621 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET));
63622 + if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS)
63623 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS));
63624 +
63625 + /* check that ic size+ic internal offset, does not exceed ic block size */
63626 + if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE)
63627 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE));
63628 + /* Check that divisible by 16 and not larger than 256 */
63629 + if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS)
63630 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS));
63631 +
63632 + /* Check that divisible by 16 and not larger than 4K */
63633 + if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET)
63634 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET));
63635 + if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS)
63636 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS));
63637 +
63638 + return E_OK;
63639 +}
63640 +
63641 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins)
63642 +{
63643 + /* Check the margin definition */
63644 + if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET)
63645 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63646 + if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET)
63647 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63648 +
63649 + return E_OK;
63650 +}
63651 +
63652 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy,
63653 + t_FmBufferPrefixContent *p_BufferPrefixContent,
63654 + t_FmSpBufMargins *p_FmSpBufMargins,
63655 + t_FmSpBufferOffsets *p_FmSpBufferOffsets,
63656 + uint8_t *internalBufferOffset)
63657 +{
63658 + uint32_t tmp;
63659 +
63660 + SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE);
63661 + ASSERT_COND(p_FmSpIntContextDataCopy);
63662 + ASSERT_COND(p_BufferPrefixContent);
63663 + ASSERT_COND(p_FmSpBufMargins);
63664 + ASSERT_COND(p_FmSpBufferOffsets);
63665 +
63666 + /* Align start of internal context data to 16 byte */
63667 + p_FmSpIntContextDataCopy->extBufOffset =
63668 + (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ?
63669 + ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) :
63670 + p_BufferPrefixContent->privDataSize);
63671 +
63672 + /* Translate margin and intContext params to FM parameters */
63673 + /* Initialize with illegal value. Later we'll set legal values. */
63674 + p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE;
63675 + p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE;
63676 + p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE;
63677 + p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE;
63678 +
63679 + /* Internally the driver supports 4 options
63680 + 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll
63681 + relate to it as 1).
63682 + 2. All IC context (from AD) not including debug.*/
63683 +
63684 + /* This 'if' covers option 2. We copy from beginning of context. */
63685 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63686 + {
63687 + p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */
63688 + /* Start copying data after 16 bytes (FD) from the beginning of the internal context */
63689 + p_FmSpIntContextDataCopy->intContextOffset = 16;
63690 +
63691 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63692 + p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset;
63693 + if (p_BufferPrefixContent->passPrsResult)
63694 + p_FmSpBufferOffsets->prsResultOffset =
63695 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16);
63696 + if (p_BufferPrefixContent->passTimeStamp)
63697 + p_FmSpBufferOffsets->timeStampOffset =
63698 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48);
63699 + if (p_BufferPrefixContent->passHashResult)
63700 + p_FmSpBufferOffsets->hashResultOffset =
63701 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56);
63702 + }
63703 + else
63704 + {
63705 + /* This case covers the options under 1 */
63706 + /* Copy size must be in 16-byte granularity. */
63707 + p_FmSpIntContextDataCopy->size =
63708 + (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) +
63709 + ((p_BufferPrefixContent->passTimeStamp ||
63710 + p_BufferPrefixContent->passHashResult) ? 16 : 0));
63711 +
63712 + /* Align start of internal context data to 16 byte */
63713 + p_FmSpIntContextDataCopy->intContextOffset =
63714 + (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 :
63715 + ((p_BufferPrefixContent->passTimeStamp ||
63716 + p_BufferPrefixContent->passHashResult) ? 64 : 0));
63717 +
63718 + if (p_BufferPrefixContent->passPrsResult)
63719 + p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset;
63720 + if (p_BufferPrefixContent->passTimeStamp)
63721 + p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ?
63722 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) :
63723 + p_FmSpIntContextDataCopy->extBufOffset;
63724 + if (p_BufferPrefixContent->passHashResult)
63725 + /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */
63726 + p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ?
63727 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) :
63728 + p_FmSpIntContextDataCopy->extBufOffset + 8;
63729 + }
63730 +
63731 + if (p_FmSpIntContextDataCopy->size)
63732 + p_FmSpBufMargins->startMargins =
63733 + (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset +
63734 + p_FmSpIntContextDataCopy->size);
63735 + else
63736 + /* No Internal Context passing, STartMargin is immediately after privateInfo */
63737 + p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize;
63738 +
63739 + /* save extra space for manip in both external and internal buffers */
63740 + if (p_BufferPrefixContent->manipExtraSpace)
63741 + {
63742 + uint8_t extraSpace;
63743 +#ifdef FM_CAPWAP_SUPPORT
63744 + if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256)
63745 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
63746 + ("p_BufferPrefixContent->manipExtraSpace should be less than %d",
63747 + 256-CAPWAP_FRAG_EXTRA_SPACE));
63748 + extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE);
63749 +#else
63750 + extraSpace = p_BufferPrefixContent->manipExtraSpace;
63751 +#endif /* FM_CAPWAP_SUPPORT */
63752 + p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins;
63753 + p_FmSpBufMargins->startMargins += extraSpace;
63754 + *internalBufferOffset = extraSpace;
63755 + }
63756 +
63757 + /* align data start */
63758 + tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign);
63759 + if (tmp)
63760 + p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp);
63761 + p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins;
63762 +
63763 + return E_OK;
63764 +}
63765 +/*********************** End of inter-module routines ************************/
63766 +
63767 +
63768 +#if (DPAA_VERSION >= 11)
63769 +/*****************************************************************************/
63770 +/* API routines */
63771 +/*****************************************************************************/
63772 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams)
63773 +{
63774 + t_FmVspEntry *p_FmVspEntry = NULL;
63775 + struct fm_storage_profile_params fm_vsp_params;
63776 +
63777 + p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry));
63778 + if (!p_FmVspEntry)
63779 + {
63780 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63781 + return NULL;
63782 + }
63783 + memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry));
63784 +
63785 + p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams));
63786 + if (!p_FmVspEntry->p_FmVspEntryDriverParams)
63787 + {
63788 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63789 + XX_Free(p_FmVspEntry);
63790 + return NULL;
63791 + }
63792 + memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams));
63793 + fman_vsp_defconfig(&fm_vsp_params);
63794 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr;
63795 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr;
63796 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr;
63797 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data;
63798 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize;
63799 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather;
63800 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize;
63801 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult;
63802 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63803 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo
63804 + = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63805 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63806 + p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset;
63807 +
63808 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools));
63809 + p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm;
63810 + p_FmVspEntry->portType = p_FmVspParams->portParams.portType;
63811 + p_FmVspEntry->portId = p_FmVspParams->portParams.portId;
63812 +
63813 + p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId;
63814 +
63815 + return p_FmVspEntry;
63816 +}
63817 +
63818 +t_Error FM_VSP_Init(t_Handle h_FmVsp)
63819 +{
63820 +
63821 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63822 + struct fm_storage_profile_params fm_vsp_params;
63823 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
63824 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
63825 + t_Error err;
63826 + uint16_t absoluteProfileId = 0;
63827 + int i = 0;
63828 +
63829 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63830 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE);
63831 +
63832 + CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams);
63833 +
63834 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
63835 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
63836 +
63837 + err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext,
63838 + &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent,
63839 + &p_FmVspEntry->bufMargins,
63840 + &p_FmVspEntry->bufferOffsets,
63841 + &p_FmVspEntry->internalBufferOffset);
63842 + if (err != E_OK)
63843 + RETURN_ERROR(MAJOR, err, NO_MSG);
63844 +
63845 +
63846 + err = CheckParamsGeneratedInternally(p_FmVspEntry);
63847 + if (err != E_OK)
63848 + RETURN_ERROR(MAJOR, err, NO_MSG);
63849 +
63850 +
63851 + p_FmVspEntry->p_FmSpRegsBase =
63852 + (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm);
63853 + if (!p_FmVspEntry->p_FmSpRegsBase)
63854 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase"));
63855 +
63856 + /* order external buffer pools in ascending order of buffer pools sizes */
63857 + FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools,
63858 + orderedArray,
63859 + sizesArray);
63860 +
63861 + p_FmVspEntry->extBufPools.numOfPoolsUsed =
63862 + p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed;
63863 + for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++)
63864 + {
63865 + p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i];
63866 + p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]];
63867 + }
63868 +
63869 + /* on user responsibility to fill it according requirement */
63870 + memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params));
63871 + fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData;
63872 + fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr;
63873 + fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr;
63874 + fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr;
63875 + fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize;
63876 + fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset;
63877 + fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather;
63878 +
63879 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63880 + {
63881 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE;
63882 + fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable;
63883 + fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools;
63884 + fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider;
63885 + fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable;
63886 + fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode;
63887 + fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE;
63888 + fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn;
63889 + }
63890 + else
63891 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE;
63892 +
63893 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
63894 + {
63895 + fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools;
63896 + fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds;
63897 + }
63898 + else
63899 + fm_vsp_params.backup_pools.num_backup_pools = 0;
63900 +
63901 + fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed;
63902 + fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool;
63903 + fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins;
63904 + fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext;
63905 +
63906 + /* no check on err - it was checked earlier */
63907 + FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm,
63908 + p_FmVspEntry->portType,
63909 + p_FmVspEntry->portId,
63910 + p_FmVspEntry->relativeProfileId,
63911 + &absoluteProfileId);
63912 +
63913 + ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase);
63914 + ASSERT_COND(fm_vsp_params.int_context);
63915 + ASSERT_COND(fm_vsp_params.buf_margins);
63916 + ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES));
63917 +
63918 + /* Set all registers related to VSP */
63919 + 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);
63920 +
63921 + p_FmVspEntry->absoluteSpId = absoluteProfileId;
63922 +
63923 + if (p_FmVspEntry->p_FmVspEntryDriverParams)
63924 + XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams);
63925 + p_FmVspEntry->p_FmVspEntryDriverParams = NULL;
63926 +
63927 + return E_OK;
63928 +}
63929 +
63930 +t_Error FM_VSP_Free(t_Handle h_FmVsp)
63931 +{
63932 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63933 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63934 + XX_Free(p_FmVspEntry);
63935 + return E_OK;
63936 +}
63937 +
63938 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
63939 +{
63940 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63941 +
63942 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63943 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63944 +
63945 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
63946 + /* if dataAlign was not initialized by user, we return to driver's default */
63947 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign)
63948 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63949 +
63950 + return E_OK;
63951 +}
63952 +
63953 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData)
63954 +{
63955 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63956 +
63957 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63958 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63959 +
63960 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData;
63961 +
63962 + return E_OK;
63963 +}
63964 +
63965 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr)
63966 +{
63967 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63968 +
63969 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63970 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63971 +
63972 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr;
63973 +
63974 + return E_OK;
63975 +}
63976 +
63977 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr)
63978 +{
63979 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63980 +
63981 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63982 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63983 +
63984 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr;
63985 +
63986 + return E_OK;
63987 +}
63988 +
63989 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr)
63990 +{
63991 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63992 +
63993 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63994 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63995 +
63996 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr;
63997 +
63998 + return E_OK;
63999 +}
64000 +
64001 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize)
64002 +{
64003 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64004 +
64005 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
64006 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
64007 +
64008 +
64009 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize;
64010 +
64011 + return E_OK;
64012 +}
64013 +
64014 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather)
64015 +{
64016 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64017 +
64018 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
64019 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
64020 +
64021 +
64022 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather;
64023 +
64024 + return E_OK;
64025 +}
64026 +
64027 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion)
64028 +{
64029 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64030 +
64031 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
64032 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
64033 + SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE);
64034 +
64035 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion));
64036 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
64037 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed"));
64038 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion));
64039 +
64040 + return E_OK;
64041 +}
64042 +
64043 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools)
64044 +{
64045 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64046 +
64047 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
64048 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
64049 + SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE);
64050 +
64051 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
64052 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
64053 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
64054 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools));
64055 +
64056 + return E_OK;
64057 +}
64058 +
64059 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp)
64060 +{
64061 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64062 +
64063 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0);
64064 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0);
64065 +
64066 + return p_FmVspEntry->bufferOffsets.dataOffset;
64067 +}
64068 +
64069 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data)
64070 +{
64071 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64072 +
64073 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
64074 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
64075 +
64076 + if (p_FmVspEntry->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
64077 + return NULL;
64078 +
64079 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset);
64080 +}
64081 +
64082 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data)
64083 +{
64084 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64085 +
64086 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
64087 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
64088 +
64089 + if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
64090 + return NULL;
64091 +
64092 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset);
64093 +}
64094 +
64095 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data)
64096 +{
64097 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64098 +
64099 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
64100 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
64101 +
64102 + if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
64103 + return NULL;
64104 +
64105 + return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset);
64106 +}
64107 +
64108 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data)
64109 +{
64110 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64111 +
64112 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
64113 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
64114 +
64115 + if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
64116 + return NULL;
64117 +
64118 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset);
64119 +}
64120 +
64121 +#endif /* (DPAA_VERSION >= 11) */
64122 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
64123 new file mode 100644
64124 index 00000000..9c171d85
64125 --- /dev/null
64126 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
64127 @@ -0,0 +1,85 @@
64128 +/*
64129 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64130 + *
64131 + * Redistribution and use in source and binary forms, with or without
64132 + * modification, are permitted provided that the following conditions are met:
64133 + * * Redistributions of source code must retain the above copyright
64134 + * notice, this list of conditions and the following disclaimer.
64135 + * * Redistributions in binary form must reproduce the above copyright
64136 + * notice, this list of conditions and the following disclaimer in the
64137 + * documentation and/or other materials provided with the distribution.
64138 + * * Neither the name of Freescale Semiconductor nor the
64139 + * names of its contributors may be used to endorse or promote products
64140 + * derived from this software without specific prior written permission.
64141 + *
64142 + *
64143 + * ALTERNATIVELY, this software may be distributed under the terms of the
64144 + * GNU General Public License ("GPL") as published by the Free Software
64145 + * Foundation, either version 2 of that License or (at your option) any
64146 + * later version.
64147 + *
64148 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64149 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64150 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64151 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64152 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64153 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64154 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64155 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64156 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64157 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64158 + */
64159 +
64160 +
64161 +/******************************************************************************
64162 + @File fm_sp.h
64163 +
64164 + @Description FM SP ...
64165 +*//***************************************************************************/
64166 +#ifndef __FM_SP_H
64167 +#define __FM_SP_H
64168 +
64169 +#include "std_ext.h"
64170 +#include "error_ext.h"
64171 +#include "list_ext.h"
64172 +
64173 +#include "fm_sp_common.h"
64174 +#include "fm_common.h"
64175 +
64176 +
64177 +#define __ERR_MODULE__ MODULE_FM_SP
64178 +
64179 +typedef struct {
64180 + t_FmBufferPrefixContent bufferPrefixContent;
64181 + e_FmDmaSwapOption dmaSwapData;
64182 + e_FmDmaCacheOption dmaIntContextCacheAttr;
64183 + e_FmDmaCacheOption dmaHeaderCacheAttr;
64184 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
64185 + bool dmaWriteOptimize;
64186 + uint16_t liodnOffset;
64187 + bool noScatherGather;
64188 + t_FmBufPoolDepletion *p_BufPoolDepletion;
64189 + t_FmBackupBmPools *p_BackupBmPools;
64190 + t_FmExtPools extBufPools;
64191 +} t_FmVspEntryDriverParams;
64192 +
64193 +typedef struct {
64194 + bool valid;
64195 + volatile bool lock;
64196 + uint8_t pointedOwners;
64197 + uint16_t absoluteSpId;
64198 + uint8_t internalBufferOffset;
64199 + t_FmSpBufMargins bufMargins;
64200 + t_FmSpIntContextDataCopy intContext;
64201 + t_FmSpBufferOffsets bufferOffsets;
64202 + t_Handle h_Fm;
64203 + e_FmPortType portType; /**< Port type */
64204 + uint8_t portId; /**< Port Id - relative to type */
64205 + uint8_t relativeProfileId;
64206 + struct fm_pcd_storage_profile_regs *p_FmSpRegsBase;
64207 + t_FmExtPools extBufPools;
64208 + t_FmVspEntryDriverParams *p_FmVspEntryDriverParams;
64209 +} t_FmVspEntry;
64210 +
64211 +
64212 +#endif /* __FM_SP_H */
64213 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
64214 new file mode 100755
64215 index 00000000..0f772e91
64216 --- /dev/null
64217 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
64218 @@ -0,0 +1,197 @@
64219 +/*
64220 + * Copyright 2013 Freescale Semiconductor Inc.
64221 + *
64222 + * Redistribution and use in source and binary forms, with or without
64223 + * modification, are permitted provided that the following conditions are met:
64224 + * * Redistributions of source code must retain the above copyright
64225 + * notice, this list of conditions and the following disclaimer.
64226 + * * Redistributions in binary form must reproduce the above copyright
64227 + * notice, this list of conditions and the following disclaimer in the
64228 + * documentation and/or other materials provided with the distribution.
64229 + * * Neither the name of Freescale Semiconductor nor the
64230 + * names of its contributors may be used to endorse or promote products
64231 + * derived from this software without specific prior written permission.
64232 + *
64233 + *
64234 + * ALTERNATIVELY, this software may be distributed under the terms of the
64235 + * GNU General Public License ("GPL") as published by the Free Software
64236 + * Foundation, either version 2 of that License or (at your option) any
64237 + * later version.
64238 + *
64239 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64240 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64241 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64242 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64243 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64244 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64245 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64246 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64247 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64248 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64249 + */
64250 +
64251 +#include "fsl_fman_sp.h"
64252 +
64253 +
64254 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
64255 + uint16_t index)
64256 +{
64257 + struct fm_pcd_storage_profile_regs *sp_regs;
64258 + sp_regs = &regs[index];
64259 + return ioread32be(&sp_regs->fm_sp_acnt);
64260 +}
64261 +
64262 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
64263 + uint16_t index, uint32_t value)
64264 +{
64265 + struct fm_pcd_storage_profile_regs *sp_regs;
64266 + sp_regs = &regs[index];
64267 + iowrite32be(value, &sp_regs->fm_sp_acnt);
64268 +}
64269 +
64270 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg)
64271 +{
64272 + cfg->dma_swap_data =
64273 + DEFAULT_FMAN_SP_DMA_SWAP_DATA;
64274 + cfg->int_context_cache_attr =
64275 + DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR;
64276 + cfg->header_cache_attr =
64277 + DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR;
64278 + cfg->scatter_gather_cache_attr =
64279 + DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR;
64280 + cfg->dma_write_optimize =
64281 + DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE;
64282 + cfg->no_scather_gather =
64283 + DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
64284 +}
64285 +
64286 +static inline uint32_t calc_vec_dep(int max_pools, bool *pools,
64287 + struct fman_ext_pools *ext_buf_pools, uint32_t mask)
64288 +{
64289 + int i, j;
64290 + uint32_t vector = 0;
64291 + for (i = 0; i < max_pools; i++)
64292 + if (pools[i])
64293 + for (j = 0; j < ext_buf_pools->num_pools_used; j++)
64294 + if (i == ext_buf_pools->ext_buf_pool[j].id) {
64295 + vector |= mask >> j;
64296 + break;
64297 + }
64298 + return vector;
64299 +}
64300 +
64301 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
64302 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
64303 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
64304 + int max_num_of_pfc_priorities)
64305 +{
64306 + int i = 0, j = 0;
64307 + struct fm_pcd_storage_profile_regs *sp_regs;
64308 + uint32_t tmp_reg, vector;
64309 + struct fman_ext_pools *ext_buf_pools = &fm_vsp_params->fm_ext_pools;
64310 + struct fman_buf_pool_depletion *buf_pool_depletion =
64311 + &fm_vsp_params->buf_pool_depletion;
64312 + struct fman_backup_bm_pools *backup_pools =
64313 + &fm_vsp_params->backup_pools;
64314 + struct fman_sp_int_context_data_copy *int_context_data_copy =
64315 + fm_vsp_params->int_context;
64316 + struct fman_sp_buf_margins *external_buffer_margins =
64317 + fm_vsp_params->buf_margins;
64318 + bool no_scather_gather = fm_vsp_params->no_scather_gather;
64319 + uint16_t liodn_offset = fm_vsp_params->liodn_offset;
64320 +
64321 + sp_regs = &regs[index];
64322 +
64323 + /* fill external buffers manager pool information register*/
64324 + for (i = 0; i < ext_buf_pools->num_pools_used; i++) {
64325 + tmp_reg = FMAN_SP_EXT_BUF_POOL_VALID |
64326 + FMAN_SP_EXT_BUF_POOL_EN_COUNTER;
64327 + tmp_reg |= ((uint32_t)ext_buf_pools->ext_buf_pool[i].id <<
64328 + FMAN_SP_EXT_BUF_POOL_ID_SHIFT);
64329 + tmp_reg |= ext_buf_pools->ext_buf_pool[i].size;
64330 + /* functionality available only for some deriviatives
64331 + (limited by config) */
64332 + for (j = 0; j < backup_pools->num_backup_pools; j++)
64333 + if (ext_buf_pools->ext_buf_pool[i].id ==
64334 + backup_pools->pool_ids[j]) {
64335 + tmp_reg |= FMAN_SP_EXT_BUF_POOL_BACKUP;
64336 + break;
64337 + }
64338 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebmpi[i]);
64339 + }
64340 +
64341 + /* clear unused pools */
64342 + for (i = ext_buf_pools->num_pools_used;
64343 + i < port_max_num_of_ext_pools; i++)
64344 + iowrite32be(0, &sp_regs->fm_sp_ebmpi[i]);
64345 +
64346 + /* fill pool depletion register*/
64347 + tmp_reg = 0;
64348 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->pools_grp_mode_enable) {
64349 + /* calculate vector for number of pools depletion */
64350 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
64351 + pools_to_consider, ext_buf_pools, 0x80000000);
64352 +
64353 + /* configure num of pools and vector for number of pools mode */
64354 + tmp_reg |= (((uint32_t)buf_pool_depletion->num_pools - 1) <<
64355 + FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT);
64356 + tmp_reg |= vector;
64357 + }
64358 +
64359 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->single_pool_mode_enable) {
64360 + /* calculate vector for number of pools depletion */
64361 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
64362 + pools_to_consider_for_single_mode,
64363 + ext_buf_pools, 0x00000080);
64364 +
64365 + /* configure num of pools and vector for number of pools mode */
64366 + tmp_reg |= vector;
64367 + }
64368 +
64369 + /* fill QbbPEV */
64370 + if (buf_pool_depletion->buf_pool_depletion_enabled) {
64371 + vector = 0;
64372 + for (i = 0; i < max_num_of_pfc_priorities; i++)
64373 + if (buf_pool_depletion->pfc_priorities_en[i] == TRUE)
64374 + vector |= 0x00000100 << i;
64375 + tmp_reg |= vector;
64376 + }
64377 + iowrite32be(tmp_reg, &sp_regs->fm_sp_mpd);
64378 +
64379 + /* fill dma attributes register */
64380 + tmp_reg = 0;
64381 + tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data <<
64382 + FMAN_SP_DMA_ATTR_SWP_SHIFT;
64383 + tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr <<
64384 + FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT;
64385 + tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr <<
64386 + FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT;
64387 + tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr <<
64388 + FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT;
64389 + if (fm_vsp_params->dma_write_optimize)
64390 + tmp_reg |= FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE;
64391 + iowrite32be(tmp_reg, &sp_regs->fm_sp_da);
64392 +
64393 + /* IC parameters - fill internal context parameters register */
64394 + tmp_reg = 0;
64395 + tmp_reg |= (((uint32_t)int_context_data_copy->ext_buf_offset/
64396 + OFFSET_UNITS) << FMAN_SP_IC_TO_EXT_SHIFT);
64397 + tmp_reg |= (((uint32_t)int_context_data_copy->int_context_offset/
64398 + OFFSET_UNITS) << FMAN_SP_IC_FROM_INT_SHIFT);
64399 + tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) <<
64400 + FMAN_SP_IC_SIZE_SHIFT);
64401 + iowrite32be(tmp_reg, &sp_regs->fm_sp_icp);
64402 +
64403 + /* buffer margins - fill external buffer margins register */
64404 + tmp_reg = 0;
64405 + tmp_reg |= (((uint32_t)external_buffer_margins->start_margins) <<
64406 + FMAN_SP_EXT_BUF_MARG_START_SHIFT);
64407 + tmp_reg |= (((uint32_t)external_buffer_margins->end_margins) <<
64408 + FMAN_SP_EXT_BUF_MARG_END_SHIFT);
64409 + if (no_scather_gather)
64410 + tmp_reg |= FMAN_SP_SG_DISABLE;
64411 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebm);
64412 +
64413 + /* buffer margins - fill spliodn register */
64414 + iowrite32be(liodn_offset, &sp_regs->fm_sp_spliodn);
64415 +}
64416 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
64417 new file mode 100644
64418 index 00000000..a870b47e
64419 --- /dev/null
64420 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
64421 @@ -0,0 +1,5216 @@
64422 +/*
64423 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64424 + *
64425 + * Redistribution and use in source and binary forms, with or without
64426 + * modification, are permitted provided that the following conditions are met:
64427 + * * Redistributions of source code must retain the above copyright
64428 + * notice, this list of conditions and the following disclaimer.
64429 + * * Redistributions in binary form must reproduce the above copyright
64430 + * notice, this list of conditions and the following disclaimer in the
64431 + * documentation and/or other materials provided with the distribution.
64432 + * * Neither the name of Freescale Semiconductor nor the
64433 + * names of its contributors may be used to endorse or promote products
64434 + * derived from this software without specific prior written permission.
64435 + *
64436 + *
64437 + * ALTERNATIVELY, this software may be distributed under the terms of the
64438 + * GNU General Public License ("GPL") as published by the Free Software
64439 + * Foundation, either version 2 of that License or (at your option) any
64440 + * later version.
64441 + *
64442 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64443 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64444 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64445 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64446 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64447 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64448 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64449 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64450 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64451 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64452 + */
64453 +
64454 +
64455 +/******************************************************************************
64456 + @File fm.c
64457 +
64458 + @Description FM driver routines implementation.
64459 +*//***************************************************************************/
64460 +#include "std_ext.h"
64461 +#include "error_ext.h"
64462 +#include "xx_ext.h"
64463 +#include "string_ext.h"
64464 +#include "sprint_ext.h"
64465 +#include "debug_ext.h"
64466 +#include "fm_muram_ext.h"
64467 +#include <linux/math64.h>
64468 +
64469 +#include "fm_common.h"
64470 +#include "fm_ipc.h"
64471 +#include "fm.h"
64472 +#ifndef CONFIG_FMAN_ARM
64473 +#include <linux/fsl/svr.h>
64474 +#endif
64475 +#include "fsl_fman.h"
64476 +
64477 +
64478 +/****************************************/
64479 +/* static functions */
64480 +/****************************************/
64481 +
64482 +static volatile bool blockingFlag = FALSE;
64483 +static void IpcMsgCompletionCB(t_Handle h_Fm,
64484 + uint8_t *p_Msg,
64485 + uint8_t *p_Reply,
64486 + uint32_t replyLength,
64487 + t_Error status)
64488 +{
64489 + UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
64490 + blockingFlag = FALSE;
64491 +}
64492 +
64493 +static void FreeInitResources(t_Fm *p_Fm)
64494 +{
64495 + if (p_Fm->camBaseAddr)
64496 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
64497 + if (p_Fm->fifoBaseAddr)
64498 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
64499 + if (p_Fm->resAddr)
64500 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
64501 +}
64502 +
64503 +static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
64504 +{
64505 + t_FMIramRegs *p_Iram;
64506 +
64507 + ASSERT_COND(p_Fm);
64508 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64509 +
64510 + return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
64511 +}
64512 +
64513 +static t_Error CheckFmParameters(t_Fm *p_Fm)
64514 +{
64515 + if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit)
64516 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
64517 +#if (DPAA_VERSION < 11)
64518 + if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats ||
64519 + (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
64520 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64521 + ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
64522 +#endif /* (DPAA_VERSION < 11) */
64523 + if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS)
64524 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS));
64525 +// 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))
64526 +// 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));
64527 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ)
64528 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64529 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ)
64530 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64531 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer)
64532 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer"));
64533 +#if (DPAA_VERSION < 11)
64534 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64535 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64536 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64537 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64538 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer)
64539 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer"));
64540 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64541 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64542 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64543 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64544 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer)
64545 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer"));
64546 +#else /* (DPAA_VERSION >= 11) */
64547 + if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)||
64548 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) ||
64549 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT))
64550 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration."));
64551 + if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)||
64552 + (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY))
64553 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration."));
64554 + if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error)
64555 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration."));
64556 +#ifdef FM_AID_MODE_NO_TNUM_SW005
64557 + if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID)
64558 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration."));
64559 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
64560 + if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats)
64561 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration."));
64562 +#endif /* (DPAA_VERSION < 11) */
64563 +
64564 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
64565 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
64566 + if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
64567 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64568 + ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
64569 +
64570 +#if (DPAA_VERSION >= 11)
64571 + if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES)
64572 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!"));
64573 +#endif /* (DPAA_VERSION >= 11) */
64574 +
64575 + if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
64576 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
64577 + if (!p_Fm->p_FmStateStruct->totalFifoSize ||
64578 + (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
64579 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64580 + ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d",
64581 + p_Fm->p_FmStateStruct->totalFifoSize,
64582 + BMI_MAX_FIFO_SIZE));
64583 + if (!p_Fm->p_FmStateStruct->totalNumOfTasks ||
64584 + (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
64585 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
64586 +
64587 +#ifdef FM_HAS_TOTAL_DMAS
64588 + if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas ||
64589 + (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
64590 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
64591 +#endif /* FM_HAS_TOTAL_DMAS */
64592 +
64593 + if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT)
64594 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT));
64595 +
64596 + if (!p_Fm->f_Exception)
64597 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64598 + if (!p_Fm->f_BusError)
64599 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64600 +
64601 +#ifdef FM_NO_WATCHDOG
64602 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) &&
64603 + (p_Fm->p_FmDriverParam->dma_watchdog))
64604 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!"));
64605 +#endif /* FM_NO_WATCHDOG */
64606 +
64607 +#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
64608 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
64609 + (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err))
64610 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
64611 +#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
64612 +
64613 +#ifdef FM_NO_TNUM_AGING
64614 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64615 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64616 + if (p_Fm->p_FmDriverParam->tnum_aging_period)
64617 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!"));
64618 +#endif /* FM_NO_TNUM_AGING */
64619 +
64620 + /* check that user did not set revision-dependent exceptions */
64621 +#ifdef FM_NO_DISPATCH_RAM_ECC
64622 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64623 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64624 + if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
64625 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
64626 +#endif /* FM_NO_DISPATCH_RAM_ECC */
64627 +
64628 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
64629 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4)
64630 + if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC))
64631 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!"));
64632 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
64633 +
64634 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
64635 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
64636 + if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC)
64637 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!"));
64638 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
64639 +
64640 + return E_OK;
64641 +}
64642 +
64643 +
64644 +static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
64645 +{
64646 + ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
64647 +
64648 + if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID)
64649 + p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
64650 +
64651 + /* If the MAC is running on guest-partition and we have IPC session with it,
64652 + we inform him about the event through IPC; otherwise, we ignore the event. */
64653 + else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId])
64654 + {
64655 + t_Error err;
64656 + t_FmIpcIsr fmIpcIsr;
64657 + t_FmIpcMsg msg;
64658 +
64659 + memset(&msg, 0, sizeof(msg));
64660 + msg.msgId = FM_GUEST_ISR;
64661 + fmIpcIsr.pendingReg = pendingReg;
64662 + fmIpcIsr.boolErr = FALSE;
64663 + memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
64664 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
64665 + (uint8_t*)&msg,
64666 + sizeof(msg.msgId) + sizeof(fmIpcIsr),
64667 + NULL,
64668 + NULL,
64669 + NULL,
64670 + NULL);
64671 + if (err != E_OK)
64672 + REPORT_ERROR(MINOR, err, NO_MSG);
64673 + }
64674 + else
64675 + DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!"));
64676 +}
64677 +
64678 +static void BmiErrEvent(t_Fm *p_Fm)
64679 +{
64680 + uint32_t event;
64681 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
64682 +
64683 +
64684 + event = fman_get_bmi_err_event(bmi_rg);
64685 +
64686 + if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC)
64687 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC);
64688 + if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
64689 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
64690 + if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
64691 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
64692 + if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
64693 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
64694 +}
64695 +
64696 +static void QmiErrEvent(t_Fm *p_Fm)
64697 +{
64698 + uint32_t event;
64699 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64700 +
64701 + event = fman_get_qmi_err_event(qmi_rg);
64702 +
64703 + if (event & QMI_ERR_INTR_EN_DOUBLE_ECC)
64704 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
64705 + if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
64706 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
64707 +}
64708 +
64709 +static void DmaErrEvent(t_Fm *p_Fm)
64710 +{
64711 + uint32_t status, com_id;
64712 + uint8_t tnum;
64713 + uint8_t hardwarePortId;
64714 + uint8_t relativePortId;
64715 + uint16_t liodn;
64716 + struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs;
64717 +
64718 + status = fman_get_dma_err_event(dma_rg);
64719 +
64720 + if (status & DMA_STATUS_BUS_ERR)
64721 + {
64722 + com_id = fman_get_dma_com_id(dma_rg);
64723 + hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
64724 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64725 + HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
64726 + tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
64727 + liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK);
64728 + ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
64729 + p_Fm->f_BusError(p_Fm->h_App,
64730 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId],
64731 + relativePortId,
64732 + fman_get_dma_addr(dma_rg),
64733 + tnum,
64734 + liodn);
64735 + }
64736 + if (status & DMA_STATUS_FM_SPDAT_ECC)
64737 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC);
64738 + if (status & DMA_STATUS_READ_ECC)
64739 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
64740 + if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
64741 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
64742 + if (status & DMA_STATUS_FM_WRITE_ECC)
64743 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
64744 + }
64745 +
64746 +static void FpmErrEvent(t_Fm *p_Fm)
64747 +{
64748 + uint32_t event;
64749 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64750 +
64751 + event = fman_get_fpm_err_event(fpm_rg);
64752 +
64753 + if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
64754 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
64755 + if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
64756 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
64757 + if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
64758 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
64759 +}
64760 +
64761 +static void MuramErrIntr(t_Fm *p_Fm)
64762 +{
64763 + uint32_t event;
64764 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64765 +
64766 + event = fman_get_muram_err_event(fpm_rg);
64767 +
64768 + if (event & FPM_RAM_MURAM_ECC)
64769 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
64770 +}
64771 +
64772 +static void IramErrIntr(t_Fm *p_Fm)
64773 +{
64774 + uint32_t event;
64775 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64776 +
64777 + event = fman_get_iram_err_event(fpm_rg);
64778 +
64779 + if (event & FPM_RAM_IRAM_ECC)
64780 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
64781 +}
64782 +
64783 +static void QmiEvent(t_Fm *p_Fm)
64784 +{
64785 + uint32_t event;
64786 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64787 +
64788 + event = fman_get_qmi_event(qmi_rg);
64789 +
64790 + if (event & QMI_INTR_EN_SINGLE_ECC)
64791 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
64792 +}
64793 +
64794 +static void UnimplementedIsr(t_Handle h_Arg)
64795 +{
64796 + UNUSED(h_Arg);
64797 +
64798 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!"));
64799 +}
64800 +
64801 +static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
64802 +{
64803 + UNUSED(h_Arg); UNUSED(event);
64804 +
64805 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!"));
64806 +}
64807 +
64808 +static void EnableTimeStamp(t_Fm *p_Fm)
64809 +{
64810 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64811 +
64812 + ASSERT_COND(p_Fm->p_FmStateStruct);
64813 + ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit);
64814 +
64815 + fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq);
64816 +
64817 + p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
64818 +}
64819 +
64820 +static t_Error ClearIRam(t_Fm *p_Fm)
64821 +{
64822 + t_FMIramRegs *p_Iram;
64823 + int i;
64824 + int iram_size;
64825 +
64826 + ASSERT_COND(p_Fm);
64827 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64828 + iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev);
64829 +
64830 + /* Enable the auto-increment */
64831 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64832 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64833 +
64834 + for (i=0; i < (iram_size/4); i++)
64835 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64836 +
64837 + WRITE_UINT32(p_Iram->iadd, iram_size - 4);
64838 + CORE_MemoryBarrier();
64839 + while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
64840 +
64841 + return E_OK;
64842 +}
64843 +
64844 +static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
64845 +{
64846 + t_FMIramRegs *p_Iram;
64847 + int i;
64848 + uint32_t tmp;
64849 + uint8_t compTo16;
64850 +
64851 + ASSERT_COND(p_Fm);
64852 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64853 +
64854 + /* Enable the auto-increment */
64855 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64856 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64857 +
64858 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64859 + WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]);
64860 +
64861 + compTo16 = (uint8_t)(p_Fm->firmware.size % 16);
64862 + if (compTo16)
64863 + for (i=0; i < ((16-compTo16) / 4); i++)
64864 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64865 +
64866 + WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4);
64867 + while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ;
64868 +
64869 + /* verify that writing has completed */
64870 + while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ;
64871 +
64872 + if (p_Fm->fwVerify)
64873 + {
64874 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64875 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64876 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64877 + {
64878 + tmp = GET_UINT32(p_Iram->idata);
64879 + if (tmp != p_Fm->firmware.p_Code[i])
64880 + RETURN_ERROR(MAJOR, E_WRITE_FAILED,
64881 + ("UCode write error : write 0x%x, read 0x%x",
64882 + p_Fm->firmware.p_Code[i],tmp));
64883 + }
64884 + WRITE_UINT32(p_Iram->iadd, 0x0);
64885 + }
64886 +
64887 + /* Enable patch from IRAM */
64888 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64889 + XX_UDelay(1000);
64890 +
64891 + DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.",
64892 + ((uint16_t *)p_Fm->firmware.p_Code)[2],
64893 + ((uint8_t *)p_Fm->firmware.p_Code)[6],
64894 + ((uint8_t *)p_Fm->firmware.p_Code)[7]));
64895 +
64896 + return E_OK;
64897 +}
64898 +
64899 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
64900 +static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm)
64901 +{
64902 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64903 + uint32_t tmpReg;
64904 + uint32_t savedSpliodn[63];
64905 +
64906 + /* write to IRAM first location the debug instruction */
64907 + WRITE_UINT32(p_Iram->iadd, 0);
64908 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64909 + WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION);
64910 +
64911 + WRITE_UINT32(p_Iram->iadd, 0);
64912 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64913 + while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ;
64914 +
64915 + /* Enable patch from IRAM */
64916 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64917 + CORE_MemoryBarrier();
64918 + XX_UDelay(100);
64919 + IO2MemCpy32((uint8_t *)savedSpliodn,
64920 + (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64921 + 63*sizeof(uint32_t));
64922 +
64923 + /* reset FMAN */
64924 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64925 + CORE_MemoryBarrier();
64926 + XX_UDelay(100);
64927 +
64928 + /* verify breakpoint debug status register */
64929 + tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
64930 + if (!tmpReg)
64931 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'"));
64932 +
64933 + /*************************************/
64934 + /* Load FMan-Controller code to IRAM */
64935 + /*************************************/
64936 + ClearIRam(p_Fm);
64937 + if (p_Fm->firmware.p_Code &&
64938 + (LoadFmanCtrlCode(p_Fm) != E_OK))
64939 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
64940 + XX_UDelay(100);
64941 +
64942 + /* reset FMAN again to start the microcode */
64943 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64944 + CORE_MemoryBarrier();
64945 + XX_UDelay(100);
64946 + Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64947 + (uint8_t *)savedSpliodn,
64948 + 63*sizeof(uint32_t));
64949 +
64950 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
64951 + {
64952 + fman_resume(p_Fm->p_FmFpmRegs);
64953 + CORE_MemoryBarrier();
64954 + XX_UDelay(100);
64955 + }
64956 +
64957 + return E_OK;
64958 +}
64959 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
64960 +
64961 +static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
64962 +{
64963 +#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
64964 +do { \
64965 + 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);\
64966 +} while (0)
64967 +#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
64968 +do { \
64969 + 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);\
64970 +} while (0)
64971 +
64972 + /* error interrupts */
64973 + if (pending & ERR_INTR_EN_1G_MAC0)
64974 + FM_G_CALL_1G_MAC_ERR_ISR(0);
64975 + if (pending & ERR_INTR_EN_1G_MAC1)
64976 + FM_G_CALL_1G_MAC_ERR_ISR(1);
64977 + if (pending & ERR_INTR_EN_1G_MAC2)
64978 + FM_G_CALL_1G_MAC_ERR_ISR(2);
64979 + if (pending & ERR_INTR_EN_1G_MAC3)
64980 + FM_G_CALL_1G_MAC_ERR_ISR(3);
64981 + if (pending & ERR_INTR_EN_1G_MAC4)
64982 + FM_G_CALL_1G_MAC_ERR_ISR(4);
64983 + if (pending & ERR_INTR_EN_1G_MAC5)
64984 + FM_G_CALL_1G_MAC_ERR_ISR(5);
64985 + if (pending & ERR_INTR_EN_1G_MAC6)
64986 + FM_G_CALL_1G_MAC_ERR_ISR(6);
64987 + if (pending & ERR_INTR_EN_1G_MAC7)
64988 + FM_G_CALL_1G_MAC_ERR_ISR(7);
64989 + if (pending & ERR_INTR_EN_10G_MAC0)
64990 + FM_G_CALL_10G_MAC_ERR_ISR(0);
64991 + if (pending & ERR_INTR_EN_10G_MAC1)
64992 + FM_G_CALL_10G_MAC_ERR_ISR(1);
64993 +}
64994 +
64995 +static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
64996 +{
64997 +#define FM_G_CALL_1G_MAC_ISR(_id) \
64998 +do { \
64999 + 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);\
65000 +} while (0)
65001 +#define FM_G_CALL_10G_MAC_ISR(_id) \
65002 +do { \
65003 + 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);\
65004 +} while (0)
65005 +
65006 + if (pending & INTR_EN_1G_MAC0)
65007 + FM_G_CALL_1G_MAC_ISR(0);
65008 + if (pending & INTR_EN_1G_MAC1)
65009 + FM_G_CALL_1G_MAC_ISR(1);
65010 + if (pending & INTR_EN_1G_MAC2)
65011 + FM_G_CALL_1G_MAC_ISR(2);
65012 + if (pending & INTR_EN_1G_MAC3)
65013 + FM_G_CALL_1G_MAC_ISR(3);
65014 + if (pending & INTR_EN_1G_MAC4)
65015 + FM_G_CALL_1G_MAC_ISR(4);
65016 + if (pending & INTR_EN_1G_MAC5)
65017 + FM_G_CALL_1G_MAC_ISR(5);
65018 + if (pending & INTR_EN_1G_MAC6)
65019 + FM_G_CALL_1G_MAC_ISR(6);
65020 + if (pending & INTR_EN_1G_MAC7)
65021 + FM_G_CALL_1G_MAC_ISR(7);
65022 + if (pending & INTR_EN_10G_MAC0)
65023 + FM_G_CALL_10G_MAC_ISR(0);
65024 + if (pending & INTR_EN_10G_MAC1)
65025 + FM_G_CALL_10G_MAC_ISR(1);
65026 + if (pending & INTR_EN_TMR)
65027 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
65028 +}
65029 +
65030 +#if (DPAA_VERSION >= 11)
65031 +static t_Error SetVSPWindow(t_Handle h_Fm,
65032 + uint8_t hardwarePortId,
65033 + uint8_t baseStorageProfile,
65034 + uint8_t log2NumOfProfiles)
65035 +{
65036 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65037 +
65038 + ASSERT_COND(h_Fm);
65039 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
65040 +
65041 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65042 + !p_Fm->p_FmBmiRegs &&
65043 + p_Fm->h_IpcSessions[0])
65044 + {
65045 + t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow;
65046 + t_FmIpcMsg msg;
65047 + t_Error err = E_OK;
65048 +
65049 + memset(&msg, 0, sizeof(msg));
65050 + memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow));
65051 + fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId;
65052 + fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile;
65053 + fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles;
65054 + msg.msgId = FM_VSP_SET_PORT_WINDOW;
65055 + memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow));
65056 +
65057 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65058 + (uint8_t*)&msg,
65059 + sizeof(msg.msgId),
65060 + NULL,
65061 + NULL,
65062 + NULL,
65063 + NULL);
65064 + if (err != E_OK)
65065 + RETURN_ERROR(MINOR, err, NO_MSG);
65066 + return E_OK;
65067 + }
65068 + else if (!p_Fm->p_FmBmiRegs)
65069 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
65070 + ("Either IPC or 'baseAddress' is required!"));
65071 +
65072 + fman_set_vsp_window(p_Fm->p_FmBmiRegs,
65073 + hardwarePortId,
65074 + baseStorageProfile,
65075 + log2NumOfProfiles);
65076 +
65077 + return E_OK;
65078 +}
65079 +
65080 +static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
65081 +{
65082 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65083 + uint8_t profilesFound = 0;
65084 + int i = 0;
65085 + uint32_t intFlags;
65086 +
65087 + if (!numOfProfiles)
65088 + return E_OK;
65089 +
65090 + if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) ||
65091 + (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES))
65092 + return (uint8_t)ILLEGAL_BASE;
65093 +
65094 + if (p_Fm->h_IpcSessions[0])
65095 + {
65096 + t_FmIpcResourceAllocParams ipcAllocParams;
65097 + t_FmIpcMsg msg;
65098 + t_FmIpcReply reply;
65099 + t_Error err;
65100 + uint32_t replyLength;
65101 +
65102 + memset(&msg, 0, sizeof(msg));
65103 + memset(&reply, 0, sizeof(reply));
65104 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
65105 + ipcAllocParams.guestId = p_Fm->guestId;
65106 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
65107 + ipcAllocParams.base = p_Fm->partVSPBase;
65108 + msg.msgId = FM_VSP_ALLOC;
65109 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
65110 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
65111 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65112 + (uint8_t*)&msg,
65113 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
65114 + (uint8_t*)&reply,
65115 + &replyLength,
65116 + NULL,
65117 + NULL);
65118 + if ((err != E_OK) ||
65119 + (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))))
65120 + RETURN_ERROR(MAJOR, err, NO_MSG);
65121 + else
65122 + memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t));
65123 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
65124 + RETURN_ERROR(MAJOR, err, NO_MSG);
65125 + }
65126 + if (p_Fm->guestId != NCSW_MASTER_ID)
65127 + {
65128 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
65129 + return (uint8_t)ILLEGAL_BASE;
65130 + }
65131 +
65132 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65133 + for (i = base; i < base + numOfProfiles; i++)
65134 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
65135 + profilesFound++;
65136 + else
65137 + break;
65138 +
65139 + if (profilesFound == numOfProfiles)
65140 + for (i = base; i<base + numOfProfiles; i++)
65141 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = guestId;
65142 + else
65143 + {
65144 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65145 + return (uint8_t)ILLEGAL_BASE;
65146 + }
65147 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65148 +
65149 + return base;
65150 +}
65151 +
65152 +static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
65153 +{
65154 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65155 + int i = 0;
65156 +
65157 + ASSERT_COND(p_Fm);
65158 +
65159 + if (p_Fm->h_IpcSessions[0])
65160 + {
65161 + t_FmIpcResourceAllocParams ipcAllocParams;
65162 + t_FmIpcMsg msg;
65163 + t_FmIpcReply reply;
65164 + uint32_t replyLength;
65165 + t_Error err;
65166 +
65167 + memset(&msg, 0, sizeof(msg));
65168 + memset(&reply, 0, sizeof(reply));
65169 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
65170 + ipcAllocParams.guestId = p_Fm->guestId;
65171 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
65172 + ipcAllocParams.base = p_Fm->partVSPBase;
65173 + msg.msgId = FM_VSP_FREE;
65174 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
65175 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
65176 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65177 + (uint8_t*)&msg,
65178 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
65179 + (uint8_t*)&reply,
65180 + &replyLength,
65181 + NULL,
65182 + NULL);
65183 + if (err != E_OK)
65184 + REPORT_ERROR(MAJOR, err, NO_MSG);
65185 + return;
65186 + }
65187 + if (p_Fm->guestId != NCSW_MASTER_ID)
65188 + {
65189 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
65190 + return;
65191 + }
65192 +
65193 + ASSERT_COND(p_Fm->p_FmSp);
65194 +
65195 + for (i=base; i<numOfProfiles; i++)
65196 + {
65197 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == guestId)
65198 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
65199 + else
65200 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
65201 + }
65202 +}
65203 +#endif /* (DPAA_VERSION >= 11) */
65204 +
65205 +static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
65206 + uint8_t *p_Msg,
65207 + uint32_t msgLength,
65208 + uint8_t *p_Reply,
65209 + uint32_t *p_ReplyLength)
65210 +{
65211 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65212 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
65213 +
65214 + UNUSED(p_Reply);
65215 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65216 + SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
65217 +
65218 +#ifdef DISABLE_SANITY_CHECKS
65219 + UNUSED(msgLength);
65220 +#endif /* DISABLE_SANITY_CHECKS */
65221 +
65222 + ASSERT_COND(p_Msg);
65223 +
65224 + *p_ReplyLength = 0;
65225 +
65226 + switch (p_IpcMsg->msgId)
65227 + {
65228 + case (FM_GUEST_ISR):
65229 + {
65230 + t_FmIpcIsr ipcIsr;
65231 +
65232 + memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
65233 + if (ipcIsr.boolErr)
65234 + GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
65235 + else
65236 + GuestEventIsr(p_Fm, ipcIsr.pendingReg);
65237 + break;
65238 + }
65239 + default:
65240 + *p_ReplyLength = 0;
65241 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
65242 + }
65243 + return E_OK;
65244 +}
65245 +
65246 +static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
65247 + uint8_t *p_Msg,
65248 + uint32_t msgLength,
65249 + uint8_t *p_Reply,
65250 + uint32_t *p_ReplyLength)
65251 +{
65252 + t_Error err;
65253 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65254 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
65255 + t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
65256 +
65257 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65258 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
65259 +
65260 +#ifdef DISABLE_SANITY_CHECKS
65261 + UNUSED(msgLength);
65262 +#endif /* DISABLE_SANITY_CHECKS */
65263 +
65264 + ASSERT_COND(p_IpcMsg);
65265 +
65266 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
65267 + *p_ReplyLength = 0;
65268 +
65269 + switch (p_IpcMsg->msgId)
65270 + {
65271 + case (FM_GET_SET_PORT_PARAMS):
65272 + {
65273 + t_FmIpcPortInInitParams ipcInitParams;
65274 + t_FmInterModulePortInitParams initParams;
65275 + t_FmIpcPortOutInitParams ipcOutInitParams;
65276 +
65277 + memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
65278 + initParams.hardwarePortId = ipcInitParams.hardwarePortId;
65279 + initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
65280 + initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
65281 + initParams.liodnOffset = ipcInitParams.liodnOffset;
65282 + initParams.numOfTasks = ipcInitParams.numOfTasks;
65283 + initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
65284 + initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
65285 + initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
65286 + initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
65287 + initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
65288 + initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
65289 + initParams.maxFrameLength = ipcInitParams.maxFrameLength;
65290 + initParams.liodnBase = ipcInitParams.liodnBase;
65291 +
65292 + p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
65293 +
65294 + ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
65295 + ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
65296 + ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo;
65297 + ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo;
65298 + ipcOutInitParams.numOfTasks = initParams.numOfTasks;
65299 + ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks;
65300 + ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas;
65301 + ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas;
65302 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams));
65303 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams);
65304 + break;
65305 + }
65306 + case (FM_SET_SIZE_OF_FIFO):
65307 + {
65308 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65309 +
65310 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65311 + p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm,
65312 + ipcPortRsrcParams.hardwarePortId,
65313 + &ipcPortRsrcParams.val,
65314 + &ipcPortRsrcParams.extra,
65315 + (bool)ipcPortRsrcParams.boolInitialConfig);
65316 + *p_ReplyLength = sizeof(uint32_t);
65317 + break;
65318 + }
65319 + case (FM_SET_NUM_OF_TASKS):
65320 + {
65321 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65322 +
65323 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65324 + p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
65325 + (uint8_t*)&ipcPortRsrcParams.val,
65326 + (uint8_t*)&ipcPortRsrcParams.extra,
65327 + (bool)ipcPortRsrcParams.boolInitialConfig);
65328 + *p_ReplyLength = sizeof(uint32_t);
65329 + break;
65330 + }
65331 + case (FM_SET_NUM_OF_OPEN_DMAS):
65332 + {
65333 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65334 +
65335 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65336 + p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
65337 + (uint8_t*)&ipcPortRsrcParams.val,
65338 + (uint8_t*)&ipcPortRsrcParams.extra,
65339 + (bool)ipcPortRsrcParams.boolInitialConfig);
65340 + *p_ReplyLength = sizeof(uint32_t);
65341 + break;
65342 + }
65343 + case (FM_RESUME_STALLED_PORT):
65344 + *p_ReplyLength = sizeof(uint32_t);
65345 + p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
65346 + break;
65347 + case (FM_MASTER_IS_ALIVE):
65348 + {
65349 + uint8_t guestId = p_IpcMsg->msgBody[0];
65350 + /* build the FM master partition IPC address */
65351 + memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
65352 + if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
65353 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
65354 + p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
65355 + if (p_Fm->h_IpcSessions[guestId] == NULL)
65356 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
65357 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
65358 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65359 + break;
65360 + }
65361 + case (FM_IS_PORT_STALLED):
65362 + {
65363 + bool tmp;
65364 +
65365 + p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
65366 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
65367 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65368 + break;
65369 + }
65370 + case (FM_RESET_MAC):
65371 + {
65372 + t_FmIpcMacParams ipcMacParams;
65373 +
65374 + memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
65375 + p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
65376 + (e_FmMacType)(ipcMacParams.enumType),
65377 + ipcMacParams.id);
65378 + *p_ReplyLength = sizeof(uint32_t);
65379 + break;
65380 + }
65381 + case (FM_SET_MAC_MAX_FRAME):
65382 + {
65383 + t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
65384 +
65385 + memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
65386 + err = FmSetMacMaxFrame(p_Fm,
65387 + (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
65388 + ipcMacMaxFrameParams.macParams.id,
65389 + ipcMacMaxFrameParams.maxFrameLength);
65390 + if (err != E_OK)
65391 + REPORT_ERROR(MINOR, err, NO_MSG);
65392 + break;
65393 + }
65394 +#if (DPAA_VERSION >= 11)
65395 + case (FM_VSP_ALLOC) :
65396 + {
65397 + t_FmIpcResourceAllocParams ipcAllocParams;
65398 + uint8_t vspBase;
65399 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65400 + vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65401 + memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t));
65402 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65403 + break;
65404 + }
65405 + case (FM_VSP_FREE) :
65406 + {
65407 + t_FmIpcResourceAllocParams ipcAllocParams;
65408 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65409 + FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65410 + break;
65411 + }
65412 + case (FM_VSP_SET_PORT_WINDOW) :
65413 + {
65414 + t_FmIpcVspSetPortWindow ipcVspSetPortWindow;
65415 + memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow));
65416 + err = SetVSPWindow(h_Fm,
65417 + ipcVspSetPortWindow.hardwarePortId,
65418 + ipcVspSetPortWindow.baseStorageProfile,
65419 + ipcVspSetPortWindow.log2NumOfProfiles);
65420 + return err;
65421 + }
65422 + case (FM_SET_CONG_GRP_PFC_PRIO) :
65423 + {
65424 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65425 + memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65426 + err = FmSetCongestionGroupPFCpriority(h_Fm,
65427 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId,
65428 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap);
65429 + return err;
65430 + }
65431 +#endif /* (DPAA_VERSION >= 11) */
65432 +
65433 + case (FM_FREE_PORT):
65434 + {
65435 + t_FmInterModulePortFreeParams portParams;
65436 + t_FmIpcPortFreeParams ipcPortParams;
65437 +
65438 + memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
65439 + portParams.hardwarePortId = ipcPortParams.hardwarePortId;
65440 + portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
65441 + portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
65442 + FmFreePortParams(h_Fm, &portParams);
65443 + break;
65444 + }
65445 + case (FM_REGISTER_INTR):
65446 + {
65447 + t_FmIpcRegisterIntr ipcRegIntr;
65448 +
65449 + memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
65450 + p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
65451 + break;
65452 + }
65453 + case (FM_GET_PARAMS):
65454 + {
65455 + t_FmIpcParams ipcParams;
65456 +
65457 + /* Get clock frequency */
65458 + ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq;
65459 + ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq;
65460 +
65461 + fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev);
65462 +
65463 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams));
65464 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
65465 + break;
65466 + }
65467 + case (FM_GET_FMAN_CTRL_CODE_REV):
65468 + {
65469 + t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo;
65470 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
65471 +
65472 + p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo);
65473 + ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev;
65474 + ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev;
65475 + ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev;
65476 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo));
65477 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo);
65478 + break;
65479 + }
65480 +
65481 + case (FM_DMA_STAT):
65482 + {
65483 + t_FmDmaStatus dmaStatus;
65484 + t_FmIpcDmaStatus ipcDmaStatus;
65485 +
65486 + FM_GetDmaStatus(h_Fm, &dmaStatus);
65487 + ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
65488 + ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
65489 + ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
65490 + ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
65491 + ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
65492 + ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError;
65493 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
65494 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
65495 + break;
65496 + }
65497 + case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
65498 + p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
65499 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65500 + break;
65501 + case (FM_FREE_FMAN_CTRL_EVENT_REG):
65502 + FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
65503 + break;
65504 + case (FM_GET_TIMESTAMP_SCALE):
65505 + {
65506 + uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
65507 +
65508 + memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
65509 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65510 + break;
65511 + }
65512 + case (FM_GET_COUNTER):
65513 + {
65514 + e_FmCounters inCounter;
65515 + uint32_t outCounter;
65516 +
65517 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
65518 + outCounter = FM_GetCounter(h_Fm, inCounter);
65519 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
65520 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65521 + break;
65522 + }
65523 + case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
65524 + {
65525 + t_FmIpcFmanEvents ipcFmanEvents;
65526 +
65527 + memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
65528 + FmSetFmanCtrlIntr(h_Fm,
65529 + ipcFmanEvents.eventRegId,
65530 + ipcFmanEvents.enableEvents);
65531 + break;
65532 + }
65533 + case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
65534 + {
65535 + uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
65536 +
65537 + memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
65538 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65539 + break;
65540 + }
65541 + case (FM_GET_PHYS_MURAM_BASE):
65542 + {
65543 + t_FmPhysAddr physAddr;
65544 + t_FmIpcPhysAddr ipcPhysAddr;
65545 +
65546 + FmGetPhysicalMuramBase(h_Fm, &physAddr);
65547 + ipcPhysAddr.high = physAddr.high;
65548 + ipcPhysAddr.low = physAddr.low;
65549 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
65550 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
65551 + break;
65552 + }
65553 + case (FM_ENABLE_RAM_ECC):
65554 + {
65555 + if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
65556 + ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
65557 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
65558 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65559 + UNUSED(err);
65560 +#else
65561 + REPORT_ERROR(MINOR, err, NO_MSG);
65562 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65563 + break;
65564 + }
65565 + case (FM_DISABLE_RAM_ECC):
65566 + {
65567 +
65568 + if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
65569 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
65570 + ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
65571 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65572 + UNUSED(err);
65573 +#else
65574 + REPORT_ERROR(MINOR, err, NO_MSG);
65575 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65576 + break;
65577 + }
65578 + case (FM_SET_NUM_OF_FMAN_CTRL):
65579 + {
65580 + t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
65581 +
65582 + memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
65583 + err = FmSetNumOfRiscsPerPort(h_Fm,
65584 + ipcPortNumOfFmanCtrls.hardwarePortId,
65585 + ipcPortNumOfFmanCtrls.numOfFmanCtrls,
65586 + ipcPortNumOfFmanCtrls.orFmanCtrl);
65587 + if (err != E_OK)
65588 + REPORT_ERROR(MINOR, err, NO_MSG);
65589 + break;
65590 + }
65591 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65592 + case (FM_10G_TX_ECC_WA):
65593 + p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
65594 + *p_ReplyLength = sizeof(uint32_t);
65595 + break;
65596 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65597 + default:
65598 + *p_ReplyLength = 0;
65599 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
65600 + }
65601 + return E_OK;
65602 +}
65603 +
65604 +
65605 +/****************************************/
65606 +/* Inter-Module functions */
65607 +/****************************************/
65608 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65609 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
65610 +{
65611 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65612 + t_Error err = E_OK;
65613 + t_FmIpcMsg msg;
65614 + t_FmIpcReply reply;
65615 + uint32_t replyLength;
65616 + uint8_t rxHardwarePortId, txHardwarePortId;
65617 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65618 +
65619 + if (p_Fm->guestId != NCSW_MASTER_ID)
65620 + {
65621 + memset(&msg, 0, sizeof(msg));
65622 + memset(&reply, 0, sizeof(reply));
65623 + msg.msgId = FM_10G_TX_ECC_WA;
65624 + msg.msgBody[0] = macId;
65625 + replyLength = sizeof(uint32_t);
65626 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65627 + (uint8_t*)&msg,
65628 + sizeof(msg.msgId)+sizeof(macId),
65629 + (uint8_t*)&reply,
65630 + &replyLength,
65631 + NULL,
65632 + NULL)) != E_OK)
65633 + RETURN_ERROR(MINOR, err, NO_MSG);
65634 + if (replyLength != sizeof(uint32_t))
65635 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65636 + return (t_Error)(reply.error);
65637 + }
65638 +
65639 + SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
65640 + SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
65641 +
65642 + rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G,
65643 + macId,
65644 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65645 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65646 + txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G,
65647 + macId,
65648 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65649 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65650 + if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
65651 + (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
65652 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
65653 + ("MAC should be initialized prior to Rx and Tx ports!"));
65654 +
65655 + return fman_set_erratum_10gmac_a004_wa(fpm_rg);
65656 +}
65657 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65658 +
65659 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm)
65660 +{
65661 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65662 +
65663 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65664 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
65665 +
65666 + return p_Fm->tnumAgingPeriod;
65667 +}
65668 +
65669 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm,
65670 + uint8_t portNum,
65671 + bool preFetchConfigured)
65672 +{
65673 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65674 +
65675 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65676 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65677 +
65678 + p_Fm->portsPreFetchConfigured[portNum] = TRUE;
65679 + p_Fm->portsPreFetchValue[portNum] = preFetchConfigured;
65680 +
65681 + return E_OK;
65682 +}
65683 +
65684 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm,
65685 + uint8_t portNum,
65686 + bool *p_PortConfigured,
65687 + bool *p_PreFetchConfigured)
65688 +{
65689 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65690 +
65691 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65692 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65693 +
65694 + /* If the prefetch wasn't configured yet (not enable or disabled)
65695 + we return the value TRUE as it was already configured */
65696 + if (!p_Fm->portsPreFetchConfigured[portNum])
65697 + {
65698 + *p_PortConfigured = FALSE;
65699 + *p_PreFetchConfigured = FALSE;
65700 + }
65701 + else
65702 + {
65703 + *p_PortConfigured = TRUE;
65704 + *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]);
65705 + }
65706 +
65707 + return E_OK;
65708 +}
65709 +
65710 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
65711 + uint32_t congestionGroupId,
65712 + uint8_t priorityBitMap)
65713 +{
65714 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65715 + uint32_t regNum;
65716 +
65717 + ASSERT_COND(h_Fm);
65718 +
65719 + if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS)
65720 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65721 + ("Congestion group ID bigger than %d",
65722 + FM_PORT_NUM_OF_CONGESTION_GRPS));
65723 +
65724 + if (p_Fm->guestId == NCSW_MASTER_ID)
65725 + {
65726 + ASSERT_COND(p_Fm->baseAddr);
65727 + regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4;
65728 + fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)),
65729 + congestionGroupId,
65730 + priorityBitMap,
65731 + regNum);
65732 + }
65733 + else if (p_Fm->h_IpcSessions[0])
65734 + {
65735 + t_Error err;
65736 + t_FmIpcMsg msg;
65737 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65738 +
65739 + memset(&msg, 0, sizeof(msg));
65740 + memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65741 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId;
65742 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap;
65743 +
65744 + msg.msgId = FM_SET_CONG_GRP_PFC_PRIO;
65745 + memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65746 +
65747 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65748 + (uint8_t*)&msg,
65749 + sizeof(msg.msgId),
65750 + NULL,
65751 + NULL,
65752 + NULL,
65753 + NULL);
65754 + if (err != E_OK)
65755 + RETURN_ERROR(MINOR, err, NO_MSG);
65756 + }
65757 + else
65758 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!"));
65759 +
65760 + return E_OK;
65761 +}
65762 +
65763 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
65764 +{
65765 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65766 +
65767 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65768 +
65769 + if (!p_Fm->baseAddr)
65770 + {
65771 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65772 + ("No base-addr; probably Guest with IPC!"));
65773 + return 0;
65774 + }
65775 +
65776 + return (p_Fm->baseAddr + FM_MM_PRS);
65777 +}
65778 +
65779 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
65780 +{
65781 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65782 +
65783 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65784 +
65785 + if (!p_Fm->baseAddr)
65786 + {
65787 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65788 + ("No base-addr; probably Guest with IPC!"));
65789 + return 0;
65790 + }
65791 +
65792 + return (p_Fm->baseAddr + FM_MM_KG);
65793 +}
65794 +
65795 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
65796 +{
65797 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65798 +
65799 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65800 +
65801 + if (!p_Fm->baseAddr)
65802 + {
65803 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65804 + ("No base-addr; probably Guest with IPC!"));
65805 + return 0;
65806 + }
65807 +
65808 + return (p_Fm->baseAddr + FM_MM_PLCR);
65809 +}
65810 +
65811 +#if (DPAA_VERSION >= 11)
65812 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm)
65813 +{
65814 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65815 +
65816 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65817 +
65818 + return p_Fm->vspBaseAddr;
65819 +}
65820 +#endif /* (DPAA_VERSION >= 11) */
65821 +
65822 +t_Handle FmGetMuramHandle(t_Handle h_Fm)
65823 +{
65824 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65825 +
65826 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
65827 +
65828 + return (p_Fm->h_FmMuram);
65829 +}
65830 +
65831 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
65832 +{
65833 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65834 +
65835 + if (p_Fm->fmMuramPhysBaseAddr)
65836 + {
65837 + /* General FM driver initialization */
65838 + p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
65839 + p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
65840 + return;
65841 + }
65842 +
65843 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
65844 +
65845 + if (p_Fm->h_IpcSessions[0])
65846 + {
65847 + t_Error err;
65848 + t_FmIpcMsg msg;
65849 + t_FmIpcReply reply;
65850 + uint32_t replyLength;
65851 + t_FmIpcPhysAddr ipcPhysAddr;
65852 +
65853 + memset(&msg, 0, sizeof(msg));
65854 + memset(&reply, 0, sizeof(reply));
65855 + msg.msgId = FM_GET_PHYS_MURAM_BASE;
65856 + replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
65857 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65858 + (uint8_t*)&msg,
65859 + sizeof(msg.msgId),
65860 + (uint8_t*)&reply,
65861 + &replyLength,
65862 + NULL,
65863 + NULL);
65864 + if (err != E_OK)
65865 + {
65866 + REPORT_ERROR(MINOR, err, NO_MSG);
65867 + return;
65868 + }
65869 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
65870 + {
65871 + REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
65872 + return;
65873 + }
65874 + memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
65875 + p_FmPhysAddr->high = ipcPhysAddr.high;
65876 + p_FmPhysAddr->low = ipcPhysAddr.low;
65877 + }
65878 + else
65879 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65880 + ("running in guest-mode without neither IPC nor mapped register!"));
65881 +}
65882 +
65883 +#if (DPAA_VERSION >= 11)
65884 +t_Error FmVSPAllocForPort (t_Handle h_Fm,
65885 + e_FmPortType portType,
65886 + uint8_t portId,
65887 + uint8_t numOfVSPs)
65888 +{
65889 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65890 + t_Error err = E_OK;
65891 + uint32_t profilesFound, intFlags;
65892 + uint8_t first, i;
65893 + uint8_t log2Num;
65894 + uint8_t swPortIndex=0, hardwarePortId;
65895 +
65896 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65897 +
65898 + if (!numOfVSPs)
65899 + return E_OK;
65900 +
65901 + if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES)
65902 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES));
65903 +
65904 + if (!POWER_OF_2(numOfVSPs))
65905 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
65906 +
65907 + LOG2((uint64_t)numOfVSPs, log2Num);
65908 +
65909 + if ((log2Num == 0) || (p_Fm->partVSPBase == 0))
65910 + first = 0;
65911 + else
65912 + first = 1<<log2Num;
65913 +
65914 + if (first > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65915 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65916 +
65917 + if (first < p_Fm->partVSPBase)
65918 + while (first < p_Fm->partVSPBase)
65919 + first = first + numOfVSPs;
65920 +
65921 + if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65922 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65923 +
65924 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65925 + profilesFound = 0;
65926 + for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; )
65927 + {
65928 + if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated)
65929 + {
65930 + profilesFound++;
65931 + i++;
65932 + if (profilesFound == numOfVSPs)
65933 + break;
65934 + }
65935 + else
65936 + {
65937 + profilesFound = 0;
65938 + /* advance i to the next aligned address */
65939 + first = i = (uint8_t)(first + numOfVSPs);
65940 + }
65941 + }
65942 + if (profilesFound == numOfVSPs)
65943 + for (i = first; i<first + numOfVSPs; i++)
65944 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = TRUE;
65945 + else
65946 + {
65947 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65948 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
65949 + }
65950 +
65951 + hardwarePortId = SwPortIdToHwPortId(portType,
65952 + portId,
65953 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65954 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65955 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65956 +
65957 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs;
65958 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first;
65959 +
65960 + if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK)
65961 + for (i = first; i < first + numOfVSPs; i++)
65962 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65963 +
65964 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65965 +
65966 + return err;
65967 +}
65968 +
65969 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
65970 + e_FmPortType portType,
65971 + uint8_t portId)
65972 +{
65973 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65974 + uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i;
65975 + uint32_t intFlags;
65976 +
65977 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65978 +
65979 + hardwarePortId = SwPortIdToHwPortId(portType,
65980 + portId,
65981 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65982 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65983 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65984 +
65985 + numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles;
65986 + first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase;
65987 +
65988 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65989 + for (i = first; i < first + numOfVSPs; i++)
65990 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65991 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65992 +
65993 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0;
65994 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0;
65995 +
65996 + return E_OK;
65997 +}
65998 +#endif /* (DPAA_VERSION >= 11) */
65999 +
66000 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
66001 +{
66002 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66003 + uint8_t i;
66004 +
66005 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66006 +
66007 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66008 + p_Fm->h_IpcSessions[0])
66009 + {
66010 + t_Error err;
66011 + t_FmIpcMsg msg;
66012 + t_FmIpcReply reply;
66013 + uint32_t replyLength;
66014 +
66015 + memset(&msg, 0, sizeof(msg));
66016 + memset(&reply, 0, sizeof(reply));
66017 + msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
66018 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66019 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66020 + (uint8_t*)&msg,
66021 + sizeof(msg.msgId),
66022 + (uint8_t*)&reply,
66023 + &replyLength,
66024 + NULL,
66025 + NULL)) != E_OK)
66026 + RETURN_ERROR(MAJOR, err, NO_MSG);
66027 +
66028 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
66029 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66030 +
66031 + *p_EventId = *(uint8_t*)(reply.replyBody);
66032 +
66033 + return (t_Error)(reply.error);
66034 + }
66035 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66036 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66037 + ("running in guest-mode without IPC!"));
66038 +
66039 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
66040 + if (!p_Fm->usedEventRegs[i])
66041 + {
66042 + p_Fm->usedEventRegs[i] = TRUE;
66043 + *p_EventId = i;
66044 + break;
66045 + }
66046 +
66047 + if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
66048 + RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register."));
66049 +
66050 + return E_OK;
66051 +}
66052 +
66053 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
66054 +{
66055 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66056 +
66057 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
66058 +
66059 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66060 + p_Fm->h_IpcSessions[0])
66061 + {
66062 + t_Error err;
66063 + t_FmIpcMsg msg;
66064 +
66065 + memset(&msg, 0, sizeof(msg));
66066 + msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
66067 + msg.msgBody[0] = eventId;
66068 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66069 + (uint8_t*)&msg,
66070 + sizeof(msg.msgId)+sizeof(eventId),
66071 + NULL,
66072 + NULL,
66073 + NULL,
66074 + NULL);
66075 + if (err != E_OK)
66076 + REPORT_ERROR(MINOR, err, NO_MSG);
66077 + return;
66078 + }
66079 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66080 + {
66081 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
66082 + ("running in guest-mode without IPC!"));
66083 + return;
66084 + }
66085 +
66086 + ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
66087 +}
66088 +
66089 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
66090 +{
66091 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66092 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66093 +
66094 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66095 + !p_Fm->p_FmFpmRegs &&
66096 + p_Fm->h_IpcSessions[0])
66097 + {
66098 + t_FmIpcFmanEvents fmanCtrl;
66099 + t_Error err;
66100 + t_FmIpcMsg msg;
66101 +
66102 + fmanCtrl.eventRegId = eventRegId;
66103 + fmanCtrl.enableEvents = enableEvents;
66104 + memset(&msg, 0, sizeof(msg));
66105 + msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
66106 + memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
66107 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66108 + (uint8_t*)&msg,
66109 + sizeof(msg.msgId)+sizeof(fmanCtrl),
66110 + NULL,
66111 + NULL,
66112 + NULL,
66113 + NULL);
66114 + if (err != E_OK)
66115 + REPORT_ERROR(MINOR, err, NO_MSG);
66116 + return;
66117 + }
66118 + else if (!p_Fm->p_FmFpmRegs)
66119 + {
66120 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
66121 + ("Either IPC or 'baseAddress' is required!"));
66122 + return;
66123 + }
66124 +
66125 + ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66126 + fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents);
66127 +}
66128 +
66129 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
66130 +{
66131 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66132 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66133 +
66134 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66135 + !p_Fm->p_FmFpmRegs &&
66136 + p_Fm->h_IpcSessions[0])
66137 + {
66138 + t_Error err;
66139 + t_FmIpcMsg msg;
66140 + t_FmIpcReply reply;
66141 + uint32_t replyLength, ctrlIntr;
66142 +
66143 + memset(&msg, 0, sizeof(msg));
66144 + memset(&reply, 0, sizeof(reply));
66145 + msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
66146 + msg.msgBody[0] = eventRegId;
66147 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
66148 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66149 + (uint8_t*)&msg,
66150 + sizeof(msg.msgId)+sizeof(eventRegId),
66151 + (uint8_t*)&reply,
66152 + &replyLength,
66153 + NULL,
66154 + NULL);
66155 + if (err != E_OK)
66156 + {
66157 + REPORT_ERROR(MINOR, err, NO_MSG);
66158 + return 0;
66159 + }
66160 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
66161 + {
66162 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66163 + return 0;
66164 + }
66165 + memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
66166 + return ctrlIntr;
66167 + }
66168 + else if (!p_Fm->p_FmFpmRegs)
66169 + {
66170 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
66171 + ("Either IPC or 'baseAddress' is required!"));
66172 + return 0;
66173 + }
66174 +
66175 + return fman_get_ctrl_intr(fpm_rg, eventRegId);
66176 +}
66177 +
66178 +void FmRegisterIntr(t_Handle h_Fm,
66179 + e_FmEventModules module,
66180 + uint8_t modId,
66181 + e_FmIntrType intrType,
66182 + void (*f_Isr) (t_Handle h_Arg),
66183 + t_Handle h_Arg)
66184 +{
66185 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66186 + int event = 0;
66187 +
66188 + ASSERT_COND(h_Fm);
66189 +
66190 + GET_FM_MODULE_EVENT(module, modId, intrType, event);
66191 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
66192 +
66193 + /* register in local FM structure */
66194 + p_Fm->intrMng[event].f_Isr = f_Isr;
66195 + p_Fm->intrMng[event].h_SrcHandle = h_Arg;
66196 +
66197 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66198 + p_Fm->h_IpcSessions[0])
66199 + {
66200 + t_FmIpcRegisterIntr fmIpcRegisterIntr;
66201 + t_Error err;
66202 + t_FmIpcMsg msg;
66203 +
66204 + /* register in Master FM structure */
66205 + fmIpcRegisterIntr.event = (uint32_t)event;
66206 + fmIpcRegisterIntr.guestId = p_Fm->guestId;
66207 + memset(&msg, 0, sizeof(msg));
66208 + msg.msgId = FM_REGISTER_INTR;
66209 + memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
66210 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66211 + (uint8_t*)&msg,
66212 + sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
66213 + NULL,
66214 + NULL,
66215 + NULL,
66216 + NULL);
66217 + if (err != E_OK)
66218 + REPORT_ERROR(MINOR, err, NO_MSG);
66219 + }
66220 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66221 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
66222 + ("running in guest-mode without IPC!"));
66223 +}
66224 +
66225 +void FmUnregisterIntr(t_Handle h_Fm,
66226 + e_FmEventModules module,
66227 + uint8_t modId,
66228 + e_FmIntrType intrType)
66229 +{
66230 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66231 + int event = 0;
66232 +
66233 + ASSERT_COND(h_Fm);
66234 +
66235 + GET_FM_MODULE_EVENT(module, modId,intrType, event);
66236 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
66237 +
66238 + p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
66239 + p_Fm->intrMng[event].h_SrcHandle = NULL;
66240 +}
66241 +
66242 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
66243 +{
66244 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66245 +
66246 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66247 +
66248 + if (p_Fm->guestId != NCSW_MASTER_ID)
66249 + {
66250 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
66251 + return;
66252 + }
66253 +
66254 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
66255 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
66256 +}
66257 +
66258 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
66259 +{
66260 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66261 +
66262 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66263 +
66264 + if (p_Fm->guestId != NCSW_MASTER_ID)
66265 + {
66266 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
66267 + return;
66268 + }
66269 +
66270 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
66271 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
66272 +}
66273 +
66274 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
66275 +{
66276 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66277 +
66278 + if (p_Fm->h_Pcd)
66279 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
66280 +
66281 + p_Fm->h_Pcd = h_FmPcd;
66282 +}
66283 +
66284 +void FmUnregisterPcd(t_Handle h_Fm)
66285 +{
66286 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66287 +
66288 + if (!p_Fm->h_Pcd)
66289 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!"));
66290 +
66291 + p_Fm->h_Pcd = NULL;
66292 +}
66293 +
66294 +t_Handle FmGetPcdHandle(t_Handle h_Fm)
66295 +{
66296 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66297 +
66298 + return p_Fm->h_Pcd;
66299 +}
66300 +
66301 +uint8_t FmGetId(t_Handle h_Fm)
66302 +{
66303 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66304 +
66305 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
66306 +
66307 + return p_Fm->p_FmStateStruct->fmId;
66308 +}
66309 +
66310 +t_Error FmReset(t_Handle h_Fm)
66311 +{
66312 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66313 +
66314 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66315 +
66316 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
66317 + CORE_MemoryBarrier();
66318 + XX_UDelay(100);
66319 +
66320 + return E_OK;
66321 +}
66322 +
66323 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm,
66324 + uint8_t hardwarePortId,
66325 + uint8_t numOfFmanCtrls,
66326 + t_FmFmanCtrl orFmanCtrl)
66327 +{
66328 +
66329 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66330 + struct fman_fpm_regs *fpm_rg;
66331 +
66332 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66333 + SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
66334 +
66335 + fpm_rg = p_Fm->p_FmFpmRegs;
66336 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66337 + !p_Fm->p_FmFpmRegs &&
66338 + p_Fm->h_IpcSessions[0])
66339 + {
66340 + t_Error err;
66341 + t_FmIpcPortNumOfFmanCtrls params;
66342 + t_FmIpcMsg msg;
66343 +
66344 + memset(&msg, 0, sizeof(msg));
66345 + params.hardwarePortId = hardwarePortId;
66346 + params.numOfFmanCtrls = numOfFmanCtrls;
66347 + params.orFmanCtrl = orFmanCtrl;
66348 + msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
66349 + memcpy(msg.msgBody, &params, sizeof(params));
66350 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66351 + (uint8_t*)&msg,
66352 + sizeof(msg.msgId) +sizeof(params),
66353 + NULL,
66354 + NULL,
66355 + NULL,
66356 + NULL);
66357 + if (err != E_OK)
66358 + RETURN_ERROR(MINOR, err, NO_MSG);
66359 + return E_OK;
66360 + }
66361 + else if (!p_Fm->p_FmFpmRegs)
66362 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66363 + ("Either IPC or 'baseAddress' is required!"));
66364 +
66365 + fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl);
66366 +
66367 + return E_OK;
66368 +}
66369 +
66370 +t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams)
66371 +{
66372 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66373 + t_Error err;
66374 + uint32_t intFlags;
66375 + uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId;
66376 + struct fman_rg fman_rg;
66377 +
66378 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
66379 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
66380 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
66381 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
66382 +
66383 + if (p_Fm->guestId != NCSW_MASTER_ID)
66384 + {
66385 + t_FmIpcPortInInitParams portInParams;
66386 + t_FmIpcPortOutInitParams portOutParams;
66387 + t_FmIpcMsg msg;
66388 + t_FmIpcReply reply;
66389 + uint32_t replyLength;
66390 +
66391 + portInParams.hardwarePortId = p_PortParams->hardwarePortId;
66392 + portInParams.enumPortType = (uint32_t)p_PortParams->portType;
66393 + portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode;
66394 + portInParams.liodnOffset = p_PortParams->liodnOffset;
66395 + portInParams.numOfTasks = p_PortParams->numOfTasks;
66396 + portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
66397 + portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
66398 + portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
66399 + portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
66400 + portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
66401 + portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66402 + portInParams.maxFrameLength = p_PortParams->maxFrameLength;
66403 + portInParams.liodnBase = p_PortParams->liodnBase;
66404 +
66405 + memset(&msg, 0, sizeof(msg));
66406 + memset(&reply, 0, sizeof(reply));
66407 + msg.msgId = FM_GET_SET_PORT_PARAMS;
66408 + memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
66409 + replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams));
66410 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66411 + (uint8_t*)&msg,
66412 + sizeof(msg.msgId) +sizeof(portInParams),
66413 + (uint8_t*)&reply,
66414 + &replyLength,
66415 + NULL,
66416 + NULL)) != E_OK)
66417 + RETURN_ERROR(MINOR, err, NO_MSG);
66418 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)))
66419 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66420 + memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams));
66421 +
66422 + p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high;
66423 + p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low;
66424 + p_PortParams->numOfTasks = portOutParams.numOfTasks;
66425 + p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks;
66426 + p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas;
66427 + p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas;
66428 + p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo;
66429 + p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo;
66430 +
66431 + return (t_Error)(reply.error);
66432 + }
66433 +
66434 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66435 +
66436 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66437 + if (p_PortParams->independentMode)
66438 + {
66439 + /* set port parameters */
66440 + p_Fm->independentMode = p_PortParams->independentMode;
66441 + /* disable dispatch limit */
66442 + fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg);
66443 + }
66444 +
66445 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66446 + {
66447 + if (p_Fm->hcPortInitialized)
66448 + {
66449 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66450 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
66451 + }
66452 + else
66453 + p_Fm->hcPortInitialized = TRUE;
66454 + }
66455 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
66456 +
66457 + err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE);
66458 + if (err)
66459 + {
66460 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66461 + RETURN_ERROR(MAJOR, err, NO_MSG);
66462 + }
66463 +
66464 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66465 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66466 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66467 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66468 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66469 + /* for transmit & O/H ports */
66470 + {
66471 + uint8_t enqTh;
66472 + uint8_t deqTh;
66473 +
66474 + /* update qmi ENQ/DEQ threshold */
66475 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
66476 + enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg);
66477 + /* if enqTh is too big, we reduce it to the max value that is still OK */
66478 + if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
66479 + {
66480 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66481 + fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh);
66482 + }
66483 +
66484 + deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg);
66485 + /* if deqTh is too small, we enlarge it to the min value that is still OK.
66486 + deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
66487 + if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
66488 + {
66489 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66490 + fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh);
66491 + }
66492 + }
66493 +
66494 +#ifdef FM_LOW_END_RESTRICTION
66495 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66496 + {
66497 + if (p_Fm->p_FmStateStruct->lowEndRestriction)
66498 + {
66499 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66500 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
66501 + }
66502 + else
66503 + p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
66504 + }
66505 +#endif /* FM_LOW_END_RESTRICTION */
66506 +
66507 + err = FmSetSizeOfFifo(p_Fm,
66508 + hardwarePortId,
66509 + &p_PortParams->sizeOfFifo,
66510 + &p_PortParams->extraSizeOfFifo,
66511 + TRUE);
66512 + if (err)
66513 + {
66514 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66515 + RETURN_ERROR(MAJOR, err, NO_MSG);
66516 + }
66517 +
66518 + err = FmSetNumOfOpenDmas(p_Fm,
66519 + hardwarePortId,
66520 + &p_PortParams->numOfOpenDmas,
66521 + &p_PortParams->numOfExtraOpenDmas,
66522 + TRUE);
66523 + if (err)
66524 + {
66525 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66526 + RETURN_ERROR(MAJOR, err, NO_MSG);
66527 + }
66528 +
66529 + fman_set_liodn_per_port(&fman_rg,
66530 + hardwarePortId,
66531 + p_PortParams->liodnBase,
66532 + p_PortParams->liodnOffset);
66533 +
66534 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66535 + fman_set_order_restoration_per_port(fman_rg.fpm_rg,
66536 + hardwarePortId,
66537 + p_PortParams->independentMode,
66538 + !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)));
66539 +
66540 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66541 +
66542 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66543 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66544 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66545 + {
66546 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66547 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId])
66548 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength;
66549 + else
66550 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66551 + }
66552 + else
66553 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66554 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66555 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66556 + {
66557 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66558 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId])
66559 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength;
66560 + else
66561 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66562 + }
66563 +
66564 + FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
66565 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66566 +
66567 + return E_OK;
66568 +}
66569 +
66570 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
66571 +{
66572 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66573 + uint32_t intFlags;
66574 + uint8_t hardwarePortId = p_PortParams->hardwarePortId;
66575 + uint8_t numOfTasks, numOfDmas, macId;
66576 + uint16_t sizeOfFifo;
66577 + t_Error err;
66578 + t_FmIpcPortFreeParams portParams;
66579 + t_FmIpcMsg msg;
66580 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
66581 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66582 +
66583 + if (p_Fm->guestId != NCSW_MASTER_ID)
66584 + {
66585 + portParams.hardwarePortId = p_PortParams->hardwarePortId;
66586 + portParams.enumPortType = (uint32_t)p_PortParams->portType;
66587 + portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66588 + memset(&msg, 0, sizeof(msg));
66589 + msg.msgId = FM_FREE_PORT;
66590 + memcpy(msg.msgBody, &portParams, sizeof(portParams));
66591 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66592 + (uint8_t*)&msg,
66593 + sizeof(msg.msgId)+sizeof(portParams),
66594 + NULL,
66595 + NULL,
66596 + NULL,
66597 + NULL);
66598 + if (err != E_OK)
66599 + REPORT_ERROR(MINOR, err, NO_MSG);
66600 + return;
66601 + }
66602 +
66603 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66604 +
66605 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66606 +
66607 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66608 + {
66609 + ASSERT_COND(p_Fm->hcPortInitialized);
66610 + p_Fm->hcPortInitialized = FALSE;
66611 + }
66612 +
66613 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
66614 +
66615 + /* free numOfTasks */
66616 + numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
66617 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
66618 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
66619 +
66620 + /* free numOfOpenDmas */
66621 + numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66622 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas);
66623 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas;
66624 +
66625 +#ifdef FM_HAS_TOTAL_DMAS
66626 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66627 + {
66628 + /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
66629 + fman_set_num_of_open_dmas(bmi_rg,
66630 + hardwarePortId,
66631 + 1,
66632 + 0,
66633 + (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize));
66634 + }
66635 +#endif /* FM_HAS_TOTAL_DMAS */
66636 +
66637 + /* free sizeOfFifo */
66638 + sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
66639 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS));
66640 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS);
66641 +
66642 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66643 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66644 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66645 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66646 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66647 + /* for transmit & O/H ports */
66648 + {
66649 + uint8_t enqTh;
66650 + uint8_t deqTh;
66651 +
66652 + /* update qmi ENQ/DEQ threshold */
66653 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
66654 +
66655 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66656 + so we can enlarge enqTh */
66657 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66658 +
66659 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66660 + so we can reduce deqTh */
66661 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66662 +
66663 + fman_set_qmi_enq_th(qmi_rg, enqTh);
66664 + fman_set_qmi_deq_th(qmi_rg, deqTh);
66665 + }
66666 +
66667 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66668 +
66669 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66670 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66671 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66672 + {
66673 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66674 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0;
66675 + }
66676 + else
66677 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66678 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66679 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66680 + {
66681 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66682 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0;
66683 + }
66684 +
66685 +#ifdef FM_LOW_END_RESTRICTION
66686 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66687 + p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
66688 +#endif /* FM_LOW_END_RESTRICTION */
66689 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66690 +}
66691 +
66692 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
66693 +{
66694 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66695 + t_Error err;
66696 + t_FmIpcMsg msg;
66697 + t_FmIpcReply reply;
66698 + uint32_t replyLength;
66699 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66700 +
66701 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66702 + !p_Fm->baseAddr &&
66703 + p_Fm->h_IpcSessions[0])
66704 + {
66705 + memset(&msg, 0, sizeof(msg));
66706 + memset(&reply, 0, sizeof(reply));
66707 + msg.msgId = FM_IS_PORT_STALLED;
66708 + msg.msgBody[0] = hardwarePortId;
66709 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66710 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66711 + (uint8_t*)&msg,
66712 + sizeof(msg.msgId)+sizeof(hardwarePortId),
66713 + (uint8_t*)&reply,
66714 + &replyLength,
66715 + NULL,
66716 + NULL);
66717 + if (err != E_OK)
66718 + RETURN_ERROR(MINOR, err, NO_MSG);
66719 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
66720 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66721 +
66722 + *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
66723 +
66724 + return (t_Error)(reply.error);
66725 + }
66726 + else if (!p_Fm->baseAddr)
66727 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66728 + ("Either IPC or 'baseAddress' is required!"));
66729 +
66730 + *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId);
66731 +
66732 + return E_OK;
66733 +}
66734 +
66735 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
66736 +{
66737 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66738 + t_Error err;
66739 + bool isStalled;
66740 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66741 +
66742 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66743 + !p_Fm->baseAddr &&
66744 + p_Fm->h_IpcSessions[0])
66745 + {
66746 + t_FmIpcMsg msg;
66747 + t_FmIpcReply reply;
66748 + uint32_t replyLength;
66749 +
66750 + memset(&msg, 0, sizeof(msg));
66751 + memset(&reply, 0, sizeof(reply));
66752 + msg.msgId = FM_RESUME_STALLED_PORT;
66753 + msg.msgBody[0] = hardwarePortId;
66754 + replyLength = sizeof(uint32_t);
66755 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66756 + (uint8_t*)&msg,
66757 + sizeof(msg.msgId) + sizeof(hardwarePortId),
66758 + (uint8_t*)&reply,
66759 + &replyLength,
66760 + NULL,
66761 + NULL);
66762 + if (err != E_OK)
66763 + RETURN_ERROR(MINOR, err, NO_MSG);
66764 + if (replyLength != sizeof(uint32_t))
66765 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66766 + return (t_Error)(reply.error);
66767 + }
66768 + else if (!p_Fm->baseAddr)
66769 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66770 + ("Either IPC or 'baseAddress' is required!"));
66771 +
66772 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66773 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!"));
66774 +
66775 + /* Get port status */
66776 + err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
66777 + if (err)
66778 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
66779 + if (!isStalled)
66780 + return E_OK;
66781 +
66782 + fman_resume_stalled_port(fpm_rg, hardwarePortId);
66783 +
66784 + return E_OK;
66785 +}
66786 +
66787 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
66788 +{
66789 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66790 + t_Error err;
66791 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66792 +
66793 +#if (DPAA_VERSION >= 11)
66794 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66795 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66796 + ("FMan MAC reset!"));
66797 +#endif /*(DPAA_VERSION >= 11)*/
66798 +
66799 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66800 + !p_Fm->baseAddr &&
66801 + p_Fm->h_IpcSessions[0])
66802 + {
66803 + t_FmIpcMacParams macParams;
66804 + t_FmIpcMsg msg;
66805 + t_FmIpcReply reply;
66806 + uint32_t replyLength;
66807 +
66808 + memset(&msg, 0, sizeof(msg));
66809 + memset(&reply, 0, sizeof(reply));
66810 + macParams.id = macId;
66811 + macParams.enumType = (uint32_t)type;
66812 + msg.msgId = FM_RESET_MAC;
66813 + memcpy(msg.msgBody, &macParams, sizeof(macParams));
66814 + replyLength = sizeof(uint32_t);
66815 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66816 + (uint8_t*)&msg,
66817 + sizeof(msg.msgId)+sizeof(macParams),
66818 + (uint8_t*)&reply,
66819 + &replyLength,
66820 + NULL,
66821 + NULL);
66822 + if (err != E_OK)
66823 + RETURN_ERROR(MINOR, err, NO_MSG);
66824 + if (replyLength != sizeof(uint32_t))
66825 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66826 + return (t_Error)(reply.error);
66827 + }
66828 + else if (!p_Fm->baseAddr)
66829 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66830 + ("Either IPC or 'baseAddress' is required!"));
66831 +
66832 + err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G));
66833 +
66834 + if (err == -EBUSY)
66835 + return ERROR_CODE(E_TIMEOUT);
66836 + else if (err)
66837 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID"));
66838 +
66839 + return E_OK;
66840 +}
66841 +
66842 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
66843 +{
66844 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66845 +
66846 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66847 + p_Fm->h_IpcSessions[0])
66848 + {
66849 + t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
66850 + t_Error err;
66851 + t_FmIpcMsg msg;
66852 +
66853 + memset(&msg, 0, sizeof(msg));
66854 + macMaxFrameLengthParams.macParams.id = macId;
66855 + macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
66856 + macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
66857 + msg.msgId = FM_SET_MAC_MAX_FRAME;
66858 + memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
66859 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66860 + (uint8_t*)&msg,
66861 + sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
66862 + NULL,
66863 + NULL,
66864 + NULL,
66865 + NULL);
66866 + if (err != E_OK)
66867 + RETURN_ERROR(MINOR, err, NO_MSG);
66868 + return E_OK;
66869 + }
66870 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66871 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66872 + ("running in guest-mode without IPC!"));
66873 +
66874 + /* if port is already initialized, check that MaxFrameLength is smaller
66875 + * or equal to the port's max */
66876 +#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
66877 + if (type == e_FM_MAC_10G)
66878 + {
66879 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])
66880 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] &&
66881 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])))
66882 + p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
66883 + else
66884 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66885 +
66886 + }
66887 + else
66888 +#else
66889 + UNUSED(type);
66890 +#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66891 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])
66892 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] &&
66893 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])))
66894 + p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
66895 + else
66896 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66897 +
66898 + return E_OK;
66899 +}
66900 +
66901 +uint16_t FmGetClockFreq(t_Handle h_Fm)
66902 +{
66903 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66904 +
66905 + /* for multicore environment: this depends on the
66906 + * fact that fmClkFreq was properly initialized at "init". */
66907 + return p_Fm->p_FmStateStruct->fmClkFreq;
66908 +}
66909 +
66910 +uint16_t FmGetMacClockFreq(t_Handle h_Fm)
66911 +{
66912 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66913 +
66914 + return p_Fm->p_FmStateStruct->fmMacClkFreq;
66915 +}
66916 +
66917 +uint32_t FmGetTimeStampScale(t_Handle h_Fm)
66918 +{
66919 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66920 +
66921 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66922 + !p_Fm->baseAddr &&
66923 + p_Fm->h_IpcSessions[0])
66924 + {
66925 + t_Error err;
66926 + t_FmIpcMsg msg;
66927 + t_FmIpcReply reply;
66928 + uint32_t replyLength, timeStamp;
66929 +
66930 + memset(&msg, 0, sizeof(msg));
66931 + memset(&reply, 0, sizeof(reply));
66932 + msg.msgId = FM_GET_TIMESTAMP_SCALE;
66933 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
66934 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66935 + (uint8_t*)&msg,
66936 + sizeof(msg.msgId),
66937 + (uint8_t*)&reply,
66938 + &replyLength,
66939 + NULL,
66940 + NULL)) != E_OK)
66941 + {
66942 + REPORT_ERROR(MAJOR, err, NO_MSG);
66943 + return 0;
66944 + }
66945 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
66946 + {
66947 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66948 + return 0;
66949 + }
66950 +
66951 + memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
66952 + return timeStamp;
66953 + }
66954 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66955 + p_Fm->baseAddr)
66956 + {
66957 + if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN))
66958 + {
66959 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!"));
66960 + return 0;
66961 + }
66962 + }
66963 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66964 + DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled."));
66965 +
66966 + return p_Fm->p_FmStateStruct->count1MicroBit;
66967 +}
66968 +
66969 +t_Error FmEnableRamsEcc(t_Handle h_Fm)
66970 +{
66971 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66972 +
66973 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66974 +
66975 + p_Fm->p_FmStateStruct->ramsEccOwners++;
66976 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66977 +
66978 + return FM_EnableRamsEcc(p_Fm);
66979 +}
66980 +
66981 +t_Error FmDisableRamsEcc(t_Handle h_Fm)
66982 +{
66983 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66984 +
66985 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66986 +
66987 + ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
66988 + p_Fm->p_FmStateStruct->ramsEccOwners--;
66989 +
66990 + if (p_Fm->p_FmStateStruct->ramsEccOwners==0)
66991 + {
66992 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66993 + return FM_DisableRamsEcc(p_Fm);
66994 + }
66995 +
66996 + return E_OK;
66997 +}
66998 +
66999 +uint8_t FmGetGuestId(t_Handle h_Fm)
67000 +{
67001 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67002 +
67003 + return p_Fm->guestId;
67004 +}
67005 +
67006 +bool FmIsMaster(t_Handle h_Fm)
67007 +{
67008 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67009 +
67010 + return (p_Fm->guestId == NCSW_MASTER_ID);
67011 +}
67012 +
67013 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
67014 + uint8_t hardwarePortId,
67015 + uint32_t *p_SizeOfFifo,
67016 + uint32_t *p_ExtraSizeOfFifo,
67017 + bool initialConfig)
67018 +{
67019 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67020 + t_FmIpcPortRsrcParams rsrcParams;
67021 + t_Error err;
67022 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
67023 + uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo;
67024 + uint16_t currentVal = 0, currentExtraVal = 0;
67025 +
67026 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67027 + !p_Fm->baseAddr &&
67028 + p_Fm->h_IpcSessions[0])
67029 + {
67030 + t_FmIpcMsg msg;
67031 + t_FmIpcReply reply;
67032 + uint32_t replyLength;
67033 +
67034 + rsrcParams.hardwarePortId = hardwarePortId;
67035 + rsrcParams.val = sizeOfFifo;
67036 + rsrcParams.extra = extraSizeOfFifo;
67037 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
67038 +
67039 + memset(&msg, 0, sizeof(msg));
67040 + memset(&reply, 0, sizeof(reply));
67041 + msg.msgId = FM_SET_SIZE_OF_FIFO;
67042 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
67043 + replyLength = sizeof(uint32_t);
67044 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67045 + (uint8_t*)&msg,
67046 + sizeof(msg.msgId) + sizeof(rsrcParams),
67047 + (uint8_t*)&reply,
67048 + &replyLength,
67049 + NULL,
67050 + NULL)) != E_OK)
67051 + RETURN_ERROR(MINOR, err, NO_MSG);
67052 + if (replyLength != sizeof(uint32_t))
67053 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67054 + return (t_Error)(reply.error);
67055 + }
67056 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67057 + p_Fm->baseAddr)
67058 + {
67059 + DBG(WARNING, ("No IPC - can't validate FM total-fifo size."));
67060 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
67061 + }
67062 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67063 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
67064 + ("running in guest-mode without neither IPC nor mapped register!"));
67065 +
67066 + if (!initialConfig)
67067 + {
67068 + /* !initialConfig - runtime change of existing value.
67069 + * - read the current FIFO and extra FIFO size */
67070 + currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId);
67071 + currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
67072 + }
67073 +
67074 + if (extraSizeOfFifo > currentExtraVal)
67075 + {
67076 + if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize)
67077 + /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize
67078 + * must be initialized to 1 buffer per port
67079 + */
67080 + p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
67081 +
67082 + p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
67083 + }
67084 +
67085 + /* check that there are enough uncommitted fifo size */
67086 + if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) >
67087 + (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){
67088 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
67089 + ("Port request fifo size + accumulated size > total FIFO size:"));
67090 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
67091 + ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d",
67092 + hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize,
67093 + p_Fm->p_FmStateStruct->accumulatedFifoSize,
67094 + p_Fm->p_FmStateStruct->totalFifoSize));
67095 + }
67096 + else
67097 + {
67098 + /* update accumulated */
67099 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal);
67100 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal;
67101 + p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
67102 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
67103 + }
67104 +
67105 + return E_OK;
67106 +}
67107 +
67108 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
67109 + uint8_t hardwarePortId,
67110 + uint8_t *p_NumOfTasks,
67111 + uint8_t *p_NumOfExtraTasks,
67112 + bool initialConfig)
67113 +{
67114 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67115 + t_Error err;
67116 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
67117 + uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks;
67118 +
67119 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67120 +
67121 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67122 + !p_Fm->baseAddr &&
67123 + p_Fm->h_IpcSessions[0])
67124 + {
67125 + t_FmIpcPortRsrcParams rsrcParams;
67126 + t_FmIpcMsg msg;
67127 + t_FmIpcReply reply;
67128 + uint32_t replyLength;
67129 +
67130 + rsrcParams.hardwarePortId = hardwarePortId;
67131 + rsrcParams.val = numOfTasks;
67132 + rsrcParams.extra = numOfExtraTasks;
67133 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
67134 +
67135 + memset(&msg, 0, sizeof(msg));
67136 + memset(&reply, 0, sizeof(reply));
67137 + msg.msgId = FM_SET_NUM_OF_TASKS;
67138 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
67139 + replyLength = sizeof(uint32_t);
67140 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67141 + (uint8_t*)&msg,
67142 + sizeof(msg.msgId) + sizeof(rsrcParams),
67143 + (uint8_t*)&reply,
67144 + &replyLength,
67145 + NULL,
67146 + NULL)) != E_OK)
67147 + RETURN_ERROR(MINOR, err, NO_MSG);
67148 + if (replyLength != sizeof(uint32_t))
67149 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67150 + return (t_Error)(reply.error);
67151 + }
67152 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67153 + p_Fm->baseAddr)
67154 + {
67155 + DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks."));
67156 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
67157 + }
67158 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67159 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
67160 + ("running in guest-mode without neither IPC nor mapped register!"));
67161 +
67162 + if (!initialConfig)
67163 + {
67164 + /* !initialConfig - runtime change of existing value.
67165 + * - read the current number of tasks */
67166 + currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
67167 + currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId);
67168 + }
67169 +
67170 + if (numOfExtraTasks > currentExtraVal)
67171 + p_Fm->p_FmStateStruct->extraTasksPoolSize =
67172 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
67173 +
67174 + /* check that there are enough uncommitted tasks */
67175 + if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) >
67176 + (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
67177 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67178 + ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
67179 + p_Fm->p_FmStateStruct->fmId));
67180 + else
67181 + {
67182 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal);
67183 + /* update accumulated */
67184 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal;
67185 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
67186 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
67187 + }
67188 +
67189 + return E_OK;
67190 +}
67191 +
67192 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
67193 + uint8_t hardwarePortId,
67194 + uint8_t *p_NumOfOpenDmas,
67195 + uint8_t *p_NumOfExtraOpenDmas,
67196 + bool initialConfig)
67197 +
67198 +{
67199 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67200 + t_Error err;
67201 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
67202 + uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas;
67203 + uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0;
67204 +
67205 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67206 +
67207 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67208 + !p_Fm->baseAddr &&
67209 + p_Fm->h_IpcSessions[0])
67210 + {
67211 + t_FmIpcPortRsrcParams rsrcParams;
67212 + t_FmIpcMsg msg;
67213 + t_FmIpcReply reply;
67214 + uint32_t replyLength;
67215 +
67216 + rsrcParams.hardwarePortId = hardwarePortId;
67217 + rsrcParams.val = numOfOpenDmas;
67218 + rsrcParams.extra = numOfExtraOpenDmas;
67219 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
67220 +
67221 + memset(&msg, 0, sizeof(msg));
67222 + memset(&reply, 0, sizeof(reply));
67223 + msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
67224 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
67225 + replyLength = sizeof(uint32_t);
67226 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67227 + (uint8_t*)&msg,
67228 + sizeof(msg.msgId) + sizeof(rsrcParams),
67229 + (uint8_t*)&reply,
67230 + &replyLength,
67231 + NULL,
67232 + NULL)) != E_OK)
67233 + RETURN_ERROR(MINOR, err, NO_MSG);
67234 + if (replyLength != sizeof(uint32_t))
67235 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67236 + return (t_Error)(reply.error);
67237 + }
67238 +#ifdef FM_HAS_TOTAL_DMAS
67239 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67240 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!"));
67241 +#else
67242 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67243 + p_Fm->baseAddr &&
67244 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
67245 + {
67246 + /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/
67247 +
67248 + if (!numOfOpenDmas)
67249 + {
67250 + /* first config without explic it value: Do Nothing - reset value shouldn't be
67251 + changed, read register for port save */
67252 + *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67253 + *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67254 + }
67255 + else
67256 + /* whether it is the first time with explicit value, or runtime "set" - write register */
67257 + fman_set_num_of_open_dmas(bmi_rg,
67258 + hardwarePortId,
67259 + numOfOpenDmas,
67260 + numOfExtraOpenDmas,
67261 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
67262 + }
67263 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67264 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
67265 + ("running in guest-mode without neither IPC nor mapped register!"));
67266 +#endif /* FM_HAS_TOTAL_DMAS */
67267 +
67268 + if (!initialConfig)
67269 + {
67270 + /* !initialConfig - runtime change of existing value.
67271 + * - read the current number of open Dma's */
67272 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67273 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67274 + }
67275 +
67276 +#ifdef FM_NO_GUARANTEED_RESET_VALUES
67277 + /* it's illegal to be in a state where this is not the first set and no value is specified */
67278 + ASSERT_COND(initialConfig || numOfOpenDmas);
67279 + if (!numOfOpenDmas)
67280 + {
67281 + /* !numOfOpenDmas - first configuration according to values in regs.
67282 + * - read the current number of open Dma's */
67283 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67284 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67285 + /* This is the first configuration and user did not specify value (!numOfOpenDmas),
67286 + * reset values will be used and we just save these values for resource management */
67287 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
67288 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal);
67289 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal;
67290 + *p_NumOfOpenDmas = currentVal;
67291 + *p_NumOfExtraOpenDmas = currentExtraVal;
67292 + return E_OK;
67293 + }
67294 +#endif /* FM_NO_GUARANTEED_RESET_VALUES */
67295 +
67296 + if (numOfExtraOpenDmas > currentExtraVal)
67297 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
67298 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
67299 +
67300 +#ifdef FM_HAS_TOTAL_DMAS
67301 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
67302 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas >
67303 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas))
67304 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67305 + ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
67306 + p_Fm->p_FmStateStruct->fmId));
67307 +#else
67308 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) &&
67309 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
67310 + !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) &&
67311 + (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) &&
67312 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
67313 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1))
67314 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67315 + ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)",
67316 + p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1));
67317 +#endif /* FM_HAS_TOTAL_DMAS */
67318 + else
67319 + {
67320 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal);
67321 + /* update acummulated */
67322 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal;
67323 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
67324 +
67325 +#ifdef FM_HAS_TOTAL_DMAS
67326 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
67327 + totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
67328 +#endif /* FM_HAS_TOTAL_DMAS */
67329 + fman_set_num_of_open_dmas(bmi_rg,
67330 + hardwarePortId,
67331 + numOfOpenDmas,
67332 + numOfExtraOpenDmas,
67333 + totalNumDmas);
67334 + }
67335 +
67336 + return E_OK;
67337 +}
67338 +
67339 +#if (DPAA_VERSION >= 11)
67340 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
67341 + e_FmPortType portType,
67342 + uint8_t portId,
67343 + uint16_t relativeProfile)
67344 +{
67345 + t_Fm *p_Fm;
67346 + t_FmSp *p_FmPcdSp;
67347 + uint8_t swPortIndex=0, hardwarePortId;
67348 +
67349 + ASSERT_COND(h_Fm);
67350 + p_Fm = (t_Fm*)h_Fm;
67351 +
67352 + hardwarePortId = SwPortIdToHwPortId(portType,
67353 + portId,
67354 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67355 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67356 + ASSERT_COND(hardwarePortId);
67357 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67358 +
67359 + p_FmPcdSp = p_Fm->p_FmSp;
67360 + ASSERT_COND(p_FmPcdSp);
67361 +
67362 + if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
67363 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles"));
67364 + if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
67365 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range"));
67366 +
67367 + return E_OK;
67368 +}
67369 +
67370 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
67371 + e_FmPortType portType,
67372 + uint8_t portId,
67373 + uint16_t relativeProfile,
67374 + uint16_t *p_AbsoluteId)
67375 +{
67376 + t_Fm *p_Fm;
67377 + t_FmSp *p_FmPcdSp;
67378 + uint8_t swPortIndex=0, hardwarePortId;
67379 + t_Error err;
67380 +
67381 + ASSERT_COND(h_Fm);
67382 + p_Fm = (t_Fm*)h_Fm;
67383 +
67384 + err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile);
67385 + if (err != E_OK)
67386 + return err;
67387 +
67388 + hardwarePortId = SwPortIdToHwPortId(portType,
67389 + portId,
67390 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67391 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67392 + ASSERT_COND(hardwarePortId);
67393 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67394 +
67395 + p_FmPcdSp = p_Fm->p_FmSp;
67396 + ASSERT_COND(p_FmPcdSp);
67397 +
67398 + *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile);
67399 +
67400 + return E_OK;
67401 +}
67402 +#endif /* (DPAA_VERSION >= 11) */
67403 +
67404 +static t_Error InitFmDma(t_Fm *p_Fm)
67405 +{
67406 + t_Error err;
67407 +
67408 + err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam);
67409 + if (err != E_OK)
67410 + return err;
67411 +
67412 + /* Allocate MURAM for CAM */
67413 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67414 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY),
67415 + DMA_CAM_ALIGN));
67416 + if (!p_Fm->camBaseAddr)
67417 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67418 +
67419 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67420 + 0,
67421 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY));
67422 +
67423 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2)
67424 + {
67425 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
67426 +
67427 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67428 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128),
67429 + 64));
67430 + if (!p_Fm->camBaseAddr)
67431 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67432 +
67433 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67434 + 0,
67435 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128));
67436 +
67437 + switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries)
67438 + {
67439 + case (8):
67440 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000);
67441 + break;
67442 + case (16):
67443 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000);
67444 + break;
67445 + case (24):
67446 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00);
67447 + break;
67448 + case (32):
67449 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff);
67450 + break;
67451 + default:
67452 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries"));
67453 + }
67454 + }
67455 +
67456 + p_Fm->p_FmDriverParam->cam_base_addr =
67457 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
67458 +
67459 + return E_OK;
67460 +}
67461 +
67462 +static t_Error InitFmFpm(t_Fm *p_Fm)
67463 +{
67464 + return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam);
67465 +}
67466 +
67467 +static t_Error InitFmBmi(t_Fm *p_Fm)
67468 +{
67469 + return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam);
67470 +}
67471 +
67472 +static t_Error InitFmQmi(t_Fm *p_Fm)
67473 +{
67474 + return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam);
67475 +}
67476 +
67477 +static t_Error InitGuestMode(t_Fm *p_Fm)
67478 +{
67479 + t_Error err = E_OK;
67480 + int i;
67481 + t_FmIpcMsg msg;
67482 + t_FmIpcReply reply;
67483 + uint32_t replyLength;
67484 +
67485 + ASSERT_COND(p_Fm);
67486 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
67487 +
67488 + /* build the FM guest partition IPC address */
67489 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
67490 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67491 +
67492 + /* build the FM master partition IPC address */
67493 + memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
67494 + if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
67495 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67496 +
67497 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67498 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67499 +
67500 + p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
67501 + if (p_Fm->h_IpcSessions[0])
67502 + {
67503 + uint8_t isMasterAlive;
67504 + t_FmIpcParams ipcParams;
67505 +
67506 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
67507 + if (err)
67508 + RETURN_ERROR(MAJOR, err, NO_MSG);
67509 +
67510 + memset(&msg, 0, sizeof(msg));
67511 + memset(&reply, 0, sizeof(reply));
67512 + msg.msgId = FM_MASTER_IS_ALIVE;
67513 + msg.msgBody[0] = p_Fm->guestId;
67514 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
67515 + do
67516 + {
67517 + blockingFlag = TRUE;
67518 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67519 + (uint8_t*)&msg,
67520 + sizeof(msg.msgId)+sizeof(p_Fm->guestId),
67521 + (uint8_t*)&reply,
67522 + &replyLength,
67523 + IpcMsgCompletionCB,
67524 + p_Fm)) != E_OK)
67525 + REPORT_ERROR(MINOR, err, NO_MSG);
67526 + while (blockingFlag) ;
67527 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
67528 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67529 + isMasterAlive = *(uint8_t*)(reply.replyBody);
67530 + } while (!isMasterAlive);
67531 +
67532 + /* read FM parameters and save */
67533 + memset(&msg, 0, sizeof(msg));
67534 + memset(&reply, 0, sizeof(reply));
67535 + msg.msgId = FM_GET_PARAMS;
67536 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
67537 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67538 + (uint8_t*)&msg,
67539 + sizeof(msg.msgId),
67540 + (uint8_t*)&reply,
67541 + &replyLength,
67542 + NULL,
67543 + NULL)) != E_OK)
67544 + RETURN_ERROR(MAJOR, err, NO_MSG);
67545 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams)))
67546 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67547 + memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams));
67548 +
67549 + p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq;
67550 + p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq;
67551 + p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev;
67552 + p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev;
67553 + }
67554 + else
67555 + {
67556 + DBG(WARNING, ("FM Guest mode - without IPC"));
67557 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
67558 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
67559 + if (p_Fm->baseAddr)
67560 + {
67561 + fman_get_revision(p_Fm->p_FmFpmRegs,
67562 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67563 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67564 +
67565 + }
67566 + }
67567 +
67568 +#if (DPAA_VERSION >= 11)
67569 + p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67570 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67571 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67572 +#endif /* (DPAA_VERSION >= 11) */
67573 +
67574 + /* General FM driver initialization */
67575 + if (p_Fm->baseAddr)
67576 + p_Fm->fmMuramPhysBaseAddr =
67577 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67578 +
67579 + XX_Free(p_Fm->p_FmDriverParam);
67580 + p_Fm->p_FmDriverParam = NULL;
67581 +
67582 + if ((p_Fm->guestId == NCSW_MASTER_ID) ||
67583 + (p_Fm->h_IpcSessions[0]))
67584 + {
67585 + FM_DisableRamsEcc(p_Fm);
67586 + FmMuramClear(p_Fm->h_FmMuram);
67587 + FM_EnableRamsEcc(p_Fm);
67588 + }
67589 +
67590 + return E_OK;
67591 +}
67592 +
67593 +static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception)
67594 +{
67595 + switch (exception) {
67596 + case e_FM_EX_DMA_BUS_ERROR:
67597 + return E_FMAN_EX_DMA_BUS_ERROR;
67598 + case e_FM_EX_DMA_READ_ECC:
67599 + return E_FMAN_EX_DMA_READ_ECC;
67600 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC:
67601 + return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC;
67602 + case e_FM_EX_DMA_FM_WRITE_ECC:
67603 + return E_FMAN_EX_DMA_FM_WRITE_ECC;
67604 + case e_FM_EX_FPM_STALL_ON_TASKS:
67605 + return E_FMAN_EX_FPM_STALL_ON_TASKS;
67606 + case e_FM_EX_FPM_SINGLE_ECC:
67607 + return E_FMAN_EX_FPM_SINGLE_ECC;
67608 + case e_FM_EX_FPM_DOUBLE_ECC:
67609 + return E_FMAN_EX_FPM_DOUBLE_ECC;
67610 + case e_FM_EX_QMI_SINGLE_ECC:
67611 + return E_FMAN_EX_QMI_SINGLE_ECC;
67612 + case e_FM_EX_QMI_DOUBLE_ECC:
67613 + return E_FMAN_EX_QMI_DOUBLE_ECC;
67614 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
67615 + return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID;
67616 + case e_FM_EX_BMI_LIST_RAM_ECC:
67617 + return E_FMAN_EX_BMI_LIST_RAM_ECC;
67618 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
67619 + return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC;
67620 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
67621 + return E_FMAN_EX_BMI_STATISTICS_RAM_ECC;
67622 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
67623 + return E_FMAN_EX_BMI_DISPATCH_RAM_ECC;
67624 + case e_FM_EX_IRAM_ECC:
67625 + return E_FMAN_EX_IRAM_ECC;
67626 + case e_FM_EX_MURAM_ECC:
67627 + return E_FMAN_EX_MURAM_ECC;
67628 + default:
67629 + return E_FMAN_EX_DMA_BUS_ERROR;
67630 + }
67631 +}
67632 +
67633 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev)
67634 +{
67635 + switch (type)
67636 + {
67637 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
67638 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
67639 + CHECK_PORT_ID_OH_PORTS(relativePortId);
67640 + return (uint8_t)(BASE_OH_PORTID + (relativePortId));
67641 + case (e_FM_PORT_TYPE_RX):
67642 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67643 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67644 + case (e_FM_PORT_TYPE_RX_10G):
67645 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67646 + * This is the reason why the 1G port offset is used.
67647 + */
67648 + if (majorRev == 6 && minorRev == 4)
67649 + {
67650 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67651 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67652 + }
67653 + else
67654 + {
67655 + CHECK_PORT_ID_10G_RX_PORTS(relativePortId);
67656 + return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId));
67657 + }
67658 + case (e_FM_PORT_TYPE_TX):
67659 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67660 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67661 + case (e_FM_PORT_TYPE_TX_10G):
67662 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67663 + * This is the reason why the 1G port offset is used.
67664 + */
67665 + if (majorRev == 6 && minorRev == 4)
67666 + {
67667 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67668 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67669 + }
67670 + else
67671 + {
67672 + CHECK_PORT_ID_10G_TX_PORTS(relativePortId);
67673 + return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId));
67674 + }
67675 + default:
67676 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
67677 + return 0;
67678 + }
67679 +}
67680 +
67681 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
67682 +t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId)
67683 +{
67684 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67685 +
67686 + DECLARE_DUMP;
67687 +
67688 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67689 +
67690 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67691 + SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) ||
67692 + p_Fm->baseAddr), E_INVALID_OPERATION);
67693 +
67694 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
67695 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
67696 +
67697 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
67698 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
67699 +
67700 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId)));
67701 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t));
67702 +
67703 + DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId)));
67704 + DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t));
67705 +
67706 + DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId)));
67707 + DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t));
67708 +
67709 + return E_OK;
67710 +}
67711 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
67712 +
67713 +
67714 +/*****************************************************************************/
67715 +/* API Init unit functions */
67716 +/*****************************************************************************/
67717 +t_Handle FM_Config(t_FmParams *p_FmParam)
67718 +{
67719 + t_Fm *p_Fm;
67720 + uint8_t i;
67721 + uintptr_t baseAddr;
67722 +
67723 + SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
67724 + SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
67725 + (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
67726 + E_INVALID_VALUE, NULL);
67727 +
67728 + baseAddr = p_FmParam->baseAddr;
67729 +
67730 + /* Allocate FM structure */
67731 + p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
67732 + if (!p_Fm)
67733 + {
67734 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
67735 + return NULL;
67736 + }
67737 + memset(p_Fm, 0, sizeof(t_Fm));
67738 +
67739 + p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
67740 + if (!p_Fm->p_FmStateStruct)
67741 + {
67742 + XX_Free(p_Fm);
67743 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
67744 + return NULL;
67745 + }
67746 + memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
67747 +
67748 + /* Initialize FM parameters which will be kept by the driver */
67749 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67750 + p_Fm->guestId = p_FmParam->guestId;
67751 +
67752 + for (i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
67753 + p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
67754 +
67755 + /* Allocate the FM driver's parameters structure */
67756 + p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg));
67757 + if (!p_Fm->p_FmDriverParam)
67758 + {
67759 + XX_Free(p_Fm->p_FmStateStruct);
67760 + XX_Free(p_Fm);
67761 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
67762 + return NULL;
67763 + }
67764 + memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg));
67765 +
67766 +#if (DPAA_VERSION >= 11)
67767 + p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp));
67768 + if (!p_Fm->p_FmSp)
67769 + {
67770 + XX_Free(p_Fm->p_FmDriverParam);
67771 + XX_Free(p_Fm->p_FmStateStruct);
67772 + XX_Free(p_Fm);
67773 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed"));
67774 + return NULL;
67775 + }
67776 + memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp));
67777 +
67778 + for (i=0; i<FM_VSP_MAX_NUM_OF_ENTRIES; i++)
67779 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
67780 +#endif /* (DPAA_VERSION >= 11) */
67781 +
67782 + /* Initialize FM parameters which will be kept by the driver */
67783 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67784 + p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
67785 + p_Fm->h_App = p_FmParam->h_App;
67786 + p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
67787 + p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio);
67788 + p_Fm->f_Exception = p_FmParam->f_Exception;
67789 + p_Fm->f_BusError = p_FmParam->f_BusError;
67790 + p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
67791 + p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67792 + p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
67793 + p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
67794 + p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67795 + p_Fm->baseAddr = baseAddr;
67796 + p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
67797 + p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
67798 + p_Fm->hcPortInitialized = FALSE;
67799 + p_Fm->independentMode = FALSE;
67800 +
67801 + p_Fm->h_Spinlock = XX_InitSpinlock();
67802 + if (!p_Fm->h_Spinlock)
67803 + {
67804 + XX_Free(p_Fm->p_FmDriverParam);
67805 + XX_Free(p_Fm->p_FmStateStruct);
67806 + XX_Free(p_Fm);
67807 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!"));
67808 + return NULL;
67809 + }
67810 +
67811 +#if (DPAA_VERSION >= 11)
67812 + p_Fm->partVSPBase = p_FmParam->partVSPBase;
67813 + p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs;
67814 + p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr;
67815 +#endif /* (DPAA_VERSION >= 11) */
67816 +
67817 + fman_defconfig(p_Fm->p_FmDriverParam,
67818 + !!(p_Fm->guestId == NCSW_MASTER_ID));
67819 +/* overide macros dependent parameters */
67820 +#ifdef FM_PEDANTIC_DMA
67821 + p_Fm->p_FmDriverParam->pedantic_dma = TRUE;
67822 + p_Fm->p_FmDriverParam->dma_aid_override = TRUE;
67823 +#endif /* FM_PEDANTIC_DMA */
67824 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67825 + p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE;
67826 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67827 +
67828 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
67829 + p_Fm->p_FmStateStruct->extraFifoPoolSize = 0;
67830 + p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
67831 + p_Fm->resetOnInit = DEFAULT_resetOnInit;
67832 + p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback;
67833 + p_Fm->fwVerify = DEFAULT_VerifyUcode;
67834 + p_Fm->firmware.size = p_FmParam->firmware.size;
67835 + if (p_Fm->firmware.size)
67836 + {
67837 + p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size);
67838 + if (!p_Fm->firmware.p_Code)
67839 + {
67840 + XX_FreeSpinlock(p_Fm->h_Spinlock);
67841 + XX_Free(p_Fm->p_FmStateStruct);
67842 + XX_Free(p_Fm->p_FmDriverParam);
67843 + XX_Free(p_Fm);
67844 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
67845 + return NULL;
67846 + }
67847 + memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size);
67848 + }
67849 +
67850 + if (p_Fm->guestId != NCSW_MASTER_ID)
67851 + return p_Fm;
67852 +
67853 + /* read revision */
67854 + /* Chip dependent, will be configured in Init */
67855 + fman_get_revision(p_Fm->p_FmFpmRegs,
67856 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67857 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67858 +
67859 +#ifdef FM_AID_MODE_NO_TNUM_SW005
67860 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
67861 + p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID;
67862 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
67863 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67864 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
67865 + p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH;
67866 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67867 +
67868 + p_Fm->p_FmStateStruct->totalFifoSize = 0;
67869 + p_Fm->p_FmStateStruct->totalNumOfTasks =
67870 + DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev,
67871 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67872 +
67873 +#ifdef FM_HAS_TOTAL_DMAS
67874 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS;
67875 +#endif /* FM_HAS_TOTAL_DMAS */
67876 +#if (DPAA_VERSION < 11)
67877 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow;
67878 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh;
67879 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries;
67880 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow;
67881 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh;
67882 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow;
67883 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh;
67884 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats;
67885 +#endif /* (DPAA_VERSION < 11) */
67886 +#ifdef FM_NO_TNUM_AGING
67887 + p_Fm->p_FmDriverParam->tnum_aging_period = 0;
67888 +#endif
67889 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
67890 +
67891 + return p_Fm;
67892 +}
67893 +
67894 +/**************************************************************************//**
67895 + @Function FM_Init
67896 +
67897 + @Description Initializes the FM module
67898 +
67899 + @Param[in] h_Fm - FM module descriptor
67900 +
67901 + @Return E_OK on success; Error code otherwise.
67902 +*//***************************************************************************/
67903 +t_Error FM_Init(t_Handle h_Fm)
67904 +{
67905 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67906 + struct fman_cfg *p_FmDriverParam = NULL;
67907 + t_Error err = E_OK;
67908 + int i;
67909 + t_FmRevisionInfo revInfo;
67910 + struct fman_rg fman_rg;
67911 +
67912 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67913 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67914 +
67915 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
67916 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
67917 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
67918 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
67919 +
67920 + p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT;
67921 + p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS;
67922 +
67923 + if (p_Fm->guestId != NCSW_MASTER_ID)
67924 + return InitGuestMode(p_Fm);
67925 +
67926 + /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default
67927 + * according to chip. otherwise, we use user's configuration.
67928 + */
67929 + if (p_Fm->p_FmStateStruct->totalFifoSize == 0)
67930 + p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev,
67931 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67932 +
67933 + CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
67934 +
67935 + p_FmDriverParam = p_Fm->p_FmDriverParam;
67936 +
67937 + FM_GetRevision(p_Fm, &revInfo);
67938 +
67939 + /* clear revision-dependent non existing exception */
67940 +#ifdef FM_NO_DISPATCH_RAM_ECC
67941 + if ((revInfo.majorRev != 4) &&
67942 + (revInfo.majorRev < 6))
67943 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
67944 +#endif /* FM_NO_DISPATCH_RAM_ECC */
67945 +
67946 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
67947 + if (revInfo.majorRev == 4)
67948 + p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
67949 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
67950 +
67951 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
67952 + if (revInfo.majorRev >= 6)
67953 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC;
67954 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
67955 +
67956 + FmMuramClear(p_Fm->h_FmMuram);
67957 +
67958 + /* clear CPG */
67959 + IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS);
67960 +
67961 + /* add to the default exceptions the user's definitions */
67962 + p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions;
67963 +
67964 + /* Reset the FM if required */
67965 + if (p_Fm->resetOnInit)
67966 + {
67967 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67968 + if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK)
67969 + RETURN_ERROR(MAJOR, err, NO_MSG);
67970 +#else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67971 +
67972 + if (p_Fm->f_ResetOnInitOverride)
67973 + {
67974 + /* Perform user specific FMan reset */
67975 + p_Fm->f_ResetOnInitOverride(h_Fm);
67976 + }
67977 + else
67978 + {
67979 + /* Perform FMan reset */
67980 + FmReset(h_Fm);
67981 + }
67982 +
67983 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
67984 + {
67985 + fman_resume(p_Fm->p_FmFpmRegs);
67986 + XX_UDelay(100);
67987 + }
67988 +#endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67989 + }
67990 +
67991 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67992 + if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */
67993 + {
67994 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67995 + /* Load FMan-Controller code to IRAM */
67996 +
67997 + ClearIRam(p_Fm);
67998 +
67999 + if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK))
68000 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
68001 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
68002 + }
68003 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
68004 +
68005 +#ifdef FM_CAPWAP_SUPPORT
68006 + /* save first 256 byte in MURAM */
68007 + p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
68008 + if (!p_Fm->resAddr)
68009 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
68010 +
68011 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
68012 +#endif /* FM_CAPWAP_SUPPORT */
68013 +
68014 +#if (DPAA_VERSION >= 11)
68015 + p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
68016 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
68017 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
68018 +#endif /* (DPAA_VERSION >= 11) */
68019 +
68020 + /* General FM driver initialization */
68021 + p_Fm->fmMuramPhysBaseAddr =
68022 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
68023 +
68024 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
68025 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
68026 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
68027 + p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
68028 +
68029 + p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions;
68030 +
68031 + /**********************/
68032 + /* Init DMA Registers */
68033 + /**********************/
68034 + err = InitFmDma(p_Fm);
68035 + if (err != E_OK)
68036 + {
68037 + FreeInitResources(p_Fm);
68038 + RETURN_ERROR(MAJOR, err, NO_MSG);
68039 + }
68040 +
68041 + /**********************/
68042 + /* Init FPM Registers */
68043 + /**********************/
68044 + err = InitFmFpm(p_Fm);
68045 + if (err != E_OK)
68046 + {
68047 + FreeInitResources(p_Fm);
68048 + RETURN_ERROR(MAJOR, err, NO_MSG);
68049 + }
68050 +
68051 + /* define common resources */
68052 + /* allocate MURAM for FIFO according to total size */
68053 + p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
68054 + p_Fm->p_FmStateStruct->totalFifoSize,
68055 + BMI_FIFO_ALIGN));
68056 + if (!p_Fm->fifoBaseAddr)
68057 + {
68058 + FreeInitResources(p_Fm);
68059 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed"));
68060 + }
68061 +
68062 + p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
68063 + p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize;
68064 + p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks;
68065 + p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq;
68066 +
68067 + /**********************/
68068 + /* Init BMI Registers */
68069 + /**********************/
68070 + err = InitFmBmi(p_Fm);
68071 + if (err != E_OK)
68072 + {
68073 + FreeInitResources(p_Fm);
68074 + RETURN_ERROR(MAJOR, err, NO_MSG);
68075 + }
68076 +
68077 + /**********************/
68078 + /* Init QMI Registers */
68079 + /**********************/
68080 + err = InitFmQmi(p_Fm);
68081 + if (err != E_OK)
68082 + {
68083 + FreeInitResources(p_Fm);
68084 + RETURN_ERROR(MAJOR, err, NO_MSG);
68085 + }
68086 +
68087 + /* build the FM master partition IPC address */
68088 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
68089 + {
68090 + FreeInitResources(p_Fm);
68091 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
68092 + }
68093 +
68094 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
68095 + if (err)
68096 + {
68097 + FreeInitResources(p_Fm);
68098 + RETURN_ERROR(MAJOR, err, NO_MSG);
68099 + }
68100 +
68101 + /* Register the FM interrupts handlers */
68102 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
68103 + {
68104 + XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
68105 + XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
68106 + }
68107 +
68108 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
68109 + {
68110 + XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm);
68111 + XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
68112 + }
68113 +
68114 + err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam);
68115 + if (err != E_OK)
68116 + return err; /* FIXME */
68117 +
68118 + EnableTimeStamp(p_Fm);
68119 +
68120 + if (p_Fm->firmware.p_Code)
68121 + {
68122 + XX_Free(p_Fm->firmware.p_Code);
68123 + p_Fm->firmware.p_Code = NULL;
68124 + }
68125 +
68126 + XX_Free(p_Fm->p_FmDriverParam);
68127 + p_Fm->p_FmDriverParam = NULL;
68128 +
68129 + return E_OK;
68130 +}
68131 +
68132 +/**************************************************************************//**
68133 + @Function FM_Free
68134 +
68135 + @Description Frees all resources that were assigned to FM module.
68136 +
68137 + Calling this routine invalidates the descriptor.
68138 +
68139 + @Param[in] h_Fm - FM module descriptor
68140 +
68141 + @Return E_OK on success; Error code otherwise.
68142 +*//***************************************************************************/
68143 +t_Error FM_Free(t_Handle h_Fm)
68144 +{
68145 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68146 + struct fman_rg fman_rg;
68147 +
68148 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68149 +
68150 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68151 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68152 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68153 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68154 +
68155 + if (p_Fm->guestId != NCSW_MASTER_ID)
68156 + {
68157 +#if (DPAA_VERSION >= 11)
68158 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
68159 +
68160 + if (p_Fm->p_FmSp)
68161 + {
68162 + XX_Free(p_Fm->p_FmSp);
68163 + p_Fm->p_FmSp = NULL;
68164 + }
68165 +#endif /* (DPAA_VERSION >= 11) */
68166 +
68167 + if (p_Fm->fmModuleName[0] != 0)
68168 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
68169 +
68170 + if (!p_Fm->recoveryMode)
68171 + XX_Free(p_Fm->p_FmStateStruct);
68172 +
68173 + XX_Free(p_Fm);
68174 +
68175 + return E_OK;
68176 + }
68177 +
68178 + fman_free_resources(&fman_rg);
68179 +
68180 + if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
68181 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
68182 +
68183 + if (p_Fm->p_FmStateStruct)
68184 + {
68185 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
68186 + {
68187 + XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
68188 + XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
68189 + }
68190 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
68191 + {
68192 + XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
68193 + XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
68194 + }
68195 + }
68196 +
68197 +#if (DPAA_VERSION >= 11)
68198 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
68199 +
68200 + if (p_Fm->p_FmSp)
68201 + {
68202 + XX_Free(p_Fm->p_FmSp);
68203 + p_Fm->p_FmSp = NULL;
68204 + }
68205 +#endif /* (DPAA_VERSION >= 11) */
68206 +
68207 + if (p_Fm->h_Spinlock)
68208 + XX_FreeSpinlock(p_Fm->h_Spinlock);
68209 +
68210 + if (p_Fm->p_FmDriverParam)
68211 + {
68212 + if (p_Fm->firmware.p_Code)
68213 + XX_Free(p_Fm->firmware.p_Code);
68214 + XX_Free(p_Fm->p_FmDriverParam);
68215 + p_Fm->p_FmDriverParam = NULL;
68216 + }
68217 +
68218 + FreeInitResources(p_Fm);
68219 +
68220 + if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
68221 + XX_Free(p_Fm->p_FmStateStruct);
68222 +
68223 + XX_Free(p_Fm);
68224 +
68225 + return E_OK;
68226 +}
68227 +
68228 +/*************************************************/
68229 +/* API Advanced Init unit functions */
68230 +/*************************************************/
68231 +
68232 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
68233 +{
68234 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68235 +
68236 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68237 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68238 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68239 +
68240 + p_Fm->resetOnInit = enable;
68241 +
68242 + return E_OK;
68243 +}
68244 +
68245 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride)
68246 +{
68247 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68248 +
68249 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68250 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68251 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68252 +
68253 + p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride;
68254 +
68255 + return E_OK;
68256 +}
68257 +
68258 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
68259 +{
68260 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68261 +
68262 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68263 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68264 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68265 +
68266 + p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
68267 +
68268 + return E_OK;
68269 +}
68270 +
68271 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
68272 +{
68273 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68274 + enum fman_dma_cache_override fsl_cache_override;
68275 +
68276 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68277 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68278 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68279 +
68280 + FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride)
68281 + p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override;
68282 +
68283 + return E_OK;
68284 +}
68285 +
68286 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
68287 +{
68288 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68289 +
68290 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68291 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68292 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68293 +
68294 + p_Fm->p_FmDriverParam->dma_aid_override = aidOverride;
68295 +
68296 + return E_OK;
68297 +}
68298 +
68299 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
68300 +{
68301 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68302 + enum fman_dma_aid_mode fsl_aid_mode;
68303 +
68304 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68305 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68306 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68307 +
68308 + FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode);
68309 + p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode;
68310 +
68311 + return E_OK;
68312 +}
68313 +
68314 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
68315 +{
68316 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68317 +
68318 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68319 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68320 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68321 +
68322 +#if (DPAA_VERSION >= 11)
68323 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68324 +#else
68325 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats;
68326 +
68327 + return E_OK;
68328 +#endif /* (DPAA_VERSION >= 11) */
68329 +}
68330 +
68331 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
68332 +{
68333 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68334 +
68335 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68336 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68337 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68338 +
68339 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries;
68340 +
68341 + return E_OK;
68342 +}
68343 +
68344 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
68345 +{
68346 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68347 + enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt;
68348 +
68349 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68350 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68351 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68352 +
68353 + FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode);
68354 + p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt;
68355 +
68356 + return E_OK;
68357 +}
68358 +
68359 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
68360 +{
68361 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68362 +
68363 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68364 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68365 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68366 +
68367 + p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop;
68368 +
68369 + return E_OK;
68370 +}
68371 +
68372 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
68373 +{
68374 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68375 + enum fman_dma_emergency_level fsl_dma_emer;
68376 +
68377 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68378 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68379 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68380 +
68381 + FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel);
68382 + p_Fm->p_FmDriverParam->dma_en_emergency = TRUE;
68383 + p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect;
68384 + p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer;
68385 +
68386 + return E_OK;
68387 +}
68388 +
68389 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
68390 +{
68391 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68392 +
68393 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68394 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68395 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68396 +
68397 + p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE;
68398 + p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt;
68399 +
68400 + return E_OK;
68401 +}
68402 +
68403 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
68404 +{
68405 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68406 + enum fman_dma_err fsl_dma_err;
68407 +
68408 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68409 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68410 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68411 +
68412 + FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr);
68413 + p_Fm->p_FmDriverParam->dma_err = fsl_dma_err;
68414 +
68415 + return E_OK;
68416 +}
68417 +
68418 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
68419 +{
68420 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68421 + enum fman_catastrophic_err fsl_catastrophic_err;
68422 +
68423 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68424 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68425 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68426 +
68427 + FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr);
68428 + p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err;
68429 +
68430 + return E_OK;
68431 +}
68432 +
68433 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
68434 +{
68435 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68436 +
68437 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68438 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68439 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68440 +
68441 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68442 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68443 +
68444 + p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE;
68445 +
68446 + return E_OK;
68447 +}
68448 +
68449 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
68450 +{
68451 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68452 +
68453 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE );
68454 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68455 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68456 +
68457 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68458 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68459 +
68460 + p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE;
68461 +
68462 + return E_OK;
68463 +}
68464 +
68465 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
68466 +{
68467 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68468 +
68469 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68470 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68471 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68472 +
68473 + p_Fm->p_FmDriverParam->halt_on_external_activ = enable;
68474 +
68475 + return E_OK;
68476 +}
68477 +
68478 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
68479 +{
68480 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68481 +
68482 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68483 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68484 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68485 +
68486 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68487 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68488 +
68489 + p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable;
68490 +
68491 + return E_OK;
68492 +}
68493 +
68494 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
68495 +{
68496 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68497 + uint32_t bitMask = 0;
68498 +
68499 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68500 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68501 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68502 +
68503 + GET_EXCEPTION_FLAG(bitMask, exception);
68504 + if (bitMask)
68505 + {
68506 + if (enable)
68507 + p_Fm->userSetExceptions |= bitMask;
68508 + else
68509 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
68510 + }
68511 + else
68512 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
68513 +
68514 + return E_OK;
68515 +}
68516 +
68517 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
68518 +{
68519 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68520 +
68521 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68522 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68523 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68524 +
68525 + p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable;
68526 +
68527 + return E_OK;
68528 +}
68529 +
68530 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
68531 +{
68532 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68533 +
68534 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68535 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68536 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68537 +
68538 + p_Fm->p_FmDriverParam->tnum_aging_period = tnumAgingPeriod;
68539 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
68540 +
68541 + return E_OK;
68542 +}
68543 +
68544 +/****************************************************/
68545 +/* Hidden-DEBUG Only API */
68546 +/****************************************************/
68547 +
68548 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
68549 +{
68550 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68551 +
68552 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68553 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68554 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68555 +
68556 + p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit;
68557 + p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh;
68558 + p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh;
68559 + p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh;
68560 + p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh;
68561 + p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh;
68562 + p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh;
68563 + p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh;
68564 + p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh;
68565 +
68566 + return E_OK;
68567 +}
68568 +
68569 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
68570 +{
68571 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68572 +
68573 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68574 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68575 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68576 +
68577 + p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency;
68578 +
68579 + return E_OK;
68580 +}
68581 +
68582 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68583 +
68584 +{
68585 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68586 +
68587 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68588 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68589 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68590 +
68591 +#if (DPAA_VERSION >= 11)
68592 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68593 +#else
68594 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68595 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68596 +
68597 + return E_OK;
68598 +#endif
68599 +}
68600 +
68601 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68602 +{
68603 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68604 +
68605 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68606 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68607 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68608 +
68609 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68610 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68611 +
68612 + return E_OK;
68613 +}
68614 +
68615 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68616 +{
68617 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68618 +
68619 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68620 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68621 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68622 +
68623 +#if (DPAA_VERSION >= 11)
68624 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68625 +#else
68626 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68627 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68628 +
68629 + return E_OK;
68630 +#endif
68631 +}
68632 +
68633 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
68634 +{
68635 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68636 +
68637 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68638 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68639 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68640 +
68641 + p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue;
68642 +
68643 + return E_OK;
68644 +}
68645 +
68646 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
68647 +{
68648 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68649 +
68650 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68651 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68652 +UNUSED(p_Fm);
68653 +
68654 + return E_OK;
68655 +}
68656 +
68657 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
68658 +{
68659 + t_Fm* p_Fm = (t_Fm*)h_Fm;
68660 + if (p_Params->setParams.type & UPDATE_FM_CLD)
68661 + {
68662 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32(
68663 + p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800);
68664 + }
68665 + if (p_Params->setParams.type & CLEAR_IRAM_READY)
68666 + {
68667 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
68668 + WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY);
68669 + }
68670 + if (p_Params->setParams.type & UPDATE_FPM_EXTC)
68671 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000);
68672 + if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR)
68673 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000);
68674 + if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP)
68675 + {
68676 + if (p_Params->setParams.sleep)
68677 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68678 + p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
68679 + else
68680 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68681 + p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
68682 + }
68683 + if (p_Params->getParams.type & GET_FM_CLD)
68684 + p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld);
68685 + if (p_Params->getParams.type & GET_FMQM_GS)
68686 + p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs);
68687 + if (p_Params->getParams.type & GET_FM_NPI)
68688 + p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi);
68689 + if (p_Params->getParams.type & GET_FMFP_EXTC)
68690 + p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc);
68691 + return E_OK;
68692 +}
68693 +
68694 +
68695 +/****************************************************/
68696 +/* API Run-time Control uint functions */
68697 +/****************************************************/
68698 +void FM_EventIsr(t_Handle h_Fm)
68699 +{
68700 +#define FM_M_CALL_1G_MAC_ISR(_id) \
68701 + { \
68702 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \
68703 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \
68704 + else \
68705 + 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);\
68706 + }
68707 +#define FM_M_CALL_10G_MAC_ISR(_id) \
68708 + { \
68709 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \
68710 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \
68711 + else \
68712 + 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);\
68713 + }
68714 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68715 + uint32_t pending, event;
68716 + struct fman_fpm_regs *fpm_rg;
68717 +
68718 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68719 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68720 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68721 +
68722 + fpm_rg = p_Fm->p_FmFpmRegs;
68723 +
68724 + /* normal interrupts */
68725 + pending = fman_get_normal_pending(fpm_rg);
68726 + if (!pending)
68727 + return;
68728 + if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt
68729 + {
68730 + t_FmGetSetParams fmGetSetParams;
68731 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
68732 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
68733 + fmGetSetParams.setParams.sleep = 0;
68734 + FmGetSetParams(h_Fm, &fmGetSetParams);
68735 + }
68736 + if (pending & INTR_EN_QMI)
68737 + QmiEvent(p_Fm);
68738 + if (pending & INTR_EN_PRS)
68739 + p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
68740 + if (pending & INTR_EN_PLCR)
68741 + p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
68742 + if (pending & INTR_EN_TMR)
68743 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
68744 +
68745 + /* MAC events may belong to different partitions */
68746 + if (pending & INTR_EN_1G_MAC0)
68747 + FM_M_CALL_1G_MAC_ISR(0);
68748 + if (pending & INTR_EN_1G_MAC1)
68749 + FM_M_CALL_1G_MAC_ISR(1);
68750 + if (pending & INTR_EN_1G_MAC2)
68751 + FM_M_CALL_1G_MAC_ISR(2);
68752 + if (pending & INTR_EN_1G_MAC3)
68753 + FM_M_CALL_1G_MAC_ISR(3);
68754 + if (pending & INTR_EN_1G_MAC4)
68755 + FM_M_CALL_1G_MAC_ISR(4);
68756 + if (pending & INTR_EN_1G_MAC5)
68757 + FM_M_CALL_1G_MAC_ISR(5);
68758 + if (pending & INTR_EN_1G_MAC6)
68759 + FM_M_CALL_1G_MAC_ISR(6);
68760 + if (pending & INTR_EN_1G_MAC7)
68761 + FM_M_CALL_1G_MAC_ISR(7);
68762 + if (pending & INTR_EN_10G_MAC0)
68763 + FM_M_CALL_10G_MAC_ISR(0);
68764 + if (pending & INTR_EN_10G_MAC1)
68765 + FM_M_CALL_10G_MAC_ISR(1);
68766 +
68767 + /* IM port events may belong to different partitions */
68768 + if (pending & INTR_EN_REV0)
68769 + {
68770 + event = fman_get_controller_event(fpm_rg, 0);
68771 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
68772 + /*TODO IPC ISR For Fman Ctrl */
68773 + ASSERT_COND(0);
68774 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
68775 + else
68776 + p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
68777 +
68778 + }
68779 + if (pending & INTR_EN_REV1)
68780 + {
68781 + event = fman_get_controller_event(fpm_rg, 1);
68782 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
68783 + /*TODO IPC ISR For Fman Ctrl */
68784 + ASSERT_COND(0);
68785 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
68786 + else
68787 + p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
68788 + }
68789 + if (pending & INTR_EN_REV2)
68790 + {
68791 + event = fman_get_controller_event(fpm_rg, 2);
68792 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
68793 + /*TODO IPC ISR For Fman Ctrl */
68794 + ASSERT_COND(0);
68795 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
68796 + else
68797 + p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
68798 + }
68799 + if (pending & INTR_EN_REV3)
68800 + {
68801 + event = fman_get_controller_event(fpm_rg, 3);
68802 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
68803 + /*TODO IPC ISR For Fman Ctrl */
68804 + ASSERT_COND(0);
68805 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
68806 + else
68807 + p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
68808 + }
68809 +#ifdef FM_MACSEC_SUPPORT
68810 + if (pending & INTR_EN_MACSEC_MAC0)
68811 + {
68812 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId)
68813 + SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending);
68814 + else
68815 + p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle);
68816 + }
68817 +#endif /* FM_MACSEC_SUPPORT */
68818 +}
68819 +
68820 +t_Error FM_ErrorIsr(t_Handle h_Fm)
68821 +{
68822 +#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
68823 + { \
68824 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
68825 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
68826 + else \
68827 + 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);\
68828 + }
68829 +#define FM_M_CALL_10G_MAC_ERR_ISR(_id) \
68830 + { \
68831 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \
68832 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \
68833 + else \
68834 + 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);\
68835 + }
68836 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68837 + uint32_t pending;
68838 + struct fman_fpm_regs *fpm_rg;
68839 +
68840 + SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
68841 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68842 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68843 +
68844 + fpm_rg = p_Fm->p_FmFpmRegs;
68845 +
68846 + /* error interrupts */
68847 + pending = fman_get_fpm_error_interrupts(fpm_rg);
68848 + if (!pending)
68849 + return ERROR_CODE(E_EMPTY);
68850 +
68851 + if (pending & ERR_INTR_EN_BMI)
68852 + BmiErrEvent(p_Fm);
68853 + if (pending & ERR_INTR_EN_QMI)
68854 + QmiErrEvent(p_Fm);
68855 + if (pending & ERR_INTR_EN_FPM)
68856 + FpmErrEvent(p_Fm);
68857 + if (pending & ERR_INTR_EN_DMA)
68858 + DmaErrEvent(p_Fm);
68859 + if (pending & ERR_INTR_EN_IRAM)
68860 + IramErrIntr(p_Fm);
68861 + if (pending & ERR_INTR_EN_MURAM)
68862 + MuramErrIntr(p_Fm);
68863 + if (pending & ERR_INTR_EN_PRS)
68864 + p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
68865 + if (pending & ERR_INTR_EN_PLCR)
68866 + p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
68867 + if (pending & ERR_INTR_EN_KG)
68868 + p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
68869 +
68870 + /* MAC events may belong to different partitions */
68871 + if (pending & ERR_INTR_EN_1G_MAC0)
68872 + FM_M_CALL_1G_MAC_ERR_ISR(0);
68873 + if (pending & ERR_INTR_EN_1G_MAC1)
68874 + FM_M_CALL_1G_MAC_ERR_ISR(1);
68875 + if (pending & ERR_INTR_EN_1G_MAC2)
68876 + FM_M_CALL_1G_MAC_ERR_ISR(2);
68877 + if (pending & ERR_INTR_EN_1G_MAC3)
68878 + FM_M_CALL_1G_MAC_ERR_ISR(3);
68879 + if (pending & ERR_INTR_EN_1G_MAC4)
68880 + FM_M_CALL_1G_MAC_ERR_ISR(4);
68881 + if (pending & ERR_INTR_EN_1G_MAC5)
68882 + FM_M_CALL_1G_MAC_ERR_ISR(5);
68883 + if (pending & ERR_INTR_EN_1G_MAC6)
68884 + FM_M_CALL_1G_MAC_ERR_ISR(6);
68885 + if (pending & ERR_INTR_EN_1G_MAC7)
68886 + FM_M_CALL_1G_MAC_ERR_ISR(7);
68887 + if (pending & ERR_INTR_EN_10G_MAC0)
68888 + FM_M_CALL_10G_MAC_ERR_ISR(0);
68889 + if (pending & ERR_INTR_EN_10G_MAC1)
68890 + FM_M_CALL_10G_MAC_ERR_ISR(1);
68891 +
68892 +#ifdef FM_MACSEC_SUPPORT
68893 + if (pending & ERR_INTR_EN_MACSEC_MAC0)
68894 + {
68895 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId)
68896 + SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending);
68897 + else
68898 + p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle);
68899 + }
68900 +#endif /* FM_MACSEC_SUPPORT */
68901 +
68902 + return E_OK;
68903 +}
68904 +
68905 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
68906 +{
68907 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68908 + int i;
68909 + uint8_t sum;
68910 + uint8_t hardwarePortId;
68911 + uint8_t weights[64];
68912 + uint8_t weight, maxPercent = 0;
68913 + struct fman_bmi_regs *bmi_rg;
68914 +
68915 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68916 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68917 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68918 +
68919 + bmi_rg = p_Fm->p_FmBmiRegs;
68920 +
68921 + memset(weights, 0, (sizeof(uint8_t) * 64));
68922 +
68923 + /* check that all ports add up to 100% */
68924 + sum = 0;
68925 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68926 + sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
68927 + if (sum != 100)
68928 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
68929 +
68930 + /* find highest percent */
68931 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68932 + {
68933 + if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
68934 + maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
68935 + }
68936 +
68937 + ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */
68938 +
68939 + /* calculate weight for each port */
68940 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68941 + {
68942 + weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent);
68943 + /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division
68944 + is not reached, we round up so that:
68945 + 0 until maxPercent/PORT_MAX_WEIGHT get "1"
68946 + maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
68947 + ...
68948 + maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
68949 + if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
68950 + weight++;
68951 +
68952 + /* find the location of this port within the register */
68953 + hardwarePortId =
68954 + SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type,
68955 + p_PortsBandwidth->portsBandwidths[i].relativePortId,
68956 + p_Fm->p_FmStateStruct->revInfo.majorRev,
68957 + p_Fm->p_FmStateStruct->revInfo.minorRev);
68958 +
68959 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68960 + weights[hardwarePortId] = weight;
68961 + }
68962 +
68963 + fman_set_ports_bandwidth(bmi_rg, weights);
68964 +
68965 + return E_OK;
68966 +}
68967 +
68968 +t_Error FM_EnableRamsEcc(t_Handle h_Fm)
68969 +{
68970 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68971 + struct fman_fpm_regs *fpm_rg;
68972 +
68973 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68974 +
68975 + fpm_rg = p_Fm->p_FmFpmRegs;
68976 +
68977 + if (p_Fm->guestId != NCSW_MASTER_ID)
68978 + {
68979 + t_FmIpcMsg msg;
68980 + t_Error err;
68981 +
68982 + memset(&msg, 0, sizeof(msg));
68983 + msg.msgId = FM_ENABLE_RAM_ECC;
68984 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68985 + (uint8_t*)&msg,
68986 + sizeof(msg.msgId),
68987 + NULL,
68988 + NULL,
68989 + NULL,
68990 + NULL);
68991 + if (err != E_OK)
68992 + RETURN_ERROR(MINOR, err, NO_MSG);
68993 + return E_OK;
68994 + }
68995 +
68996 + if (!p_Fm->p_FmStateStruct->internalCall)
68997 + p_Fm->p_FmStateStruct->explicitEnable = TRUE;
68998 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68999 +
69000 + if (p_Fm->p_FmStateStruct->ramsEccEnable)
69001 + return E_OK;
69002 + else
69003 + {
69004 + fman_enable_rams_ecc(fpm_rg);
69005 + p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
69006 + }
69007 +
69008 + return E_OK;
69009 +}
69010 +
69011 +t_Error FM_DisableRamsEcc(t_Handle h_Fm)
69012 +{
69013 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69014 + bool explicitDisable = FALSE;
69015 + struct fman_fpm_regs *fpm_rg;
69016 +
69017 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69018 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69019 +
69020 + fpm_rg = p_Fm->p_FmFpmRegs;
69021 +
69022 + if (p_Fm->guestId != NCSW_MASTER_ID)
69023 + {
69024 + t_Error err;
69025 + t_FmIpcMsg msg;
69026 +
69027 + memset(&msg, 0, sizeof(msg));
69028 + msg.msgId = FM_DISABLE_RAM_ECC;
69029 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69030 + (uint8_t*)&msg,
69031 + sizeof(msg.msgId),
69032 + NULL,
69033 + NULL,
69034 + NULL,
69035 + NULL)) != E_OK)
69036 + RETURN_ERROR(MINOR, err, NO_MSG);
69037 + return E_OK;
69038 + }
69039 +
69040 + if (!p_Fm->p_FmStateStruct->internalCall)
69041 + explicitDisable = TRUE;
69042 + p_Fm->p_FmStateStruct->internalCall = FALSE;
69043 +
69044 + /* if rams are already disabled, or if rams were explicitly enabled and are
69045 + currently called indirectly (not explicitly), ignore this call. */
69046 + if (!p_Fm->p_FmStateStruct->ramsEccEnable ||
69047 + (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
69048 + return E_OK;
69049 + else
69050 + {
69051 + if (p_Fm->p_FmStateStruct->explicitEnable)
69052 + /* This is the case were both explicit are TRUE.
69053 + Turn off this flag for cases were following ramsEnable
69054 + routines are called */
69055 + p_Fm->p_FmStateStruct->explicitEnable = FALSE;
69056 +
69057 + fman_enable_rams_ecc(fpm_rg);
69058 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
69059 + }
69060 +
69061 + return E_OK;
69062 +}
69063 +
69064 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
69065 +{
69066 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69067 + uint32_t bitMask = 0;
69068 + enum fman_exceptions fslException;
69069 + struct fman_rg fman_rg;
69070 +
69071 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69072 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69073 +
69074 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69075 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69076 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69077 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69078 +
69079 + GET_EXCEPTION_FLAG(bitMask, exception);
69080 + if (bitMask)
69081 + {
69082 + if (enable)
69083 + p_Fm->p_FmStateStruct->exceptions |= bitMask;
69084 + else
69085 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
69086 +
69087 + fslException = FmanExceptionTrans(exception);
69088 +
69089 + return (t_Error)fman_set_exception(&fman_rg,
69090 + fslException,
69091 + enable);
69092 + }
69093 + else
69094 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
69095 +
69096 + return E_OK;
69097 +}
69098 +
69099 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
69100 +{
69101 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69102 +
69103 + p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev;
69104 + p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev;
69105 +
69106 + return E_OK;
69107 +}
69108 +
69109 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo)
69110 +{
69111 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69112 + t_FMIramRegs *p_Iram;
69113 + uint32_t revInfo;
69114 +
69115 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69116 + SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER);
69117 +
69118 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
69119 + p_Fm->h_IpcSessions[0])
69120 + {
69121 + t_Error err;
69122 + t_FmIpcMsg msg;
69123 + t_FmIpcReply reply;
69124 + uint32_t replyLength;
69125 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
69126 +
69127 + memset(&msg, 0, sizeof(msg));
69128 + memset(&reply, 0, sizeof(reply));
69129 + msg.msgId = FM_GET_FMAN_CTRL_CODE_REV;
69130 + replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo);
69131 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69132 + (uint8_t*)&msg,
69133 + sizeof(msg.msgId),
69134 + (uint8_t*)&reply,
69135 + &replyLength,
69136 + NULL,
69137 + NULL)) != E_OK)
69138 + RETURN_ERROR(MINOR, err, NO_MSG);
69139 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo)))
69140 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69141 + memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo));
69142 + p_RevisionInfo->packageRev = ipcRevInfo.packageRev;
69143 + p_RevisionInfo->majorRev = ipcRevInfo.majorRev;
69144 + p_RevisionInfo->minorRev = ipcRevInfo.minorRev;
69145 + return (t_Error)(reply.error);
69146 + }
69147 + else if (p_Fm->guestId != NCSW_MASTER_ID)
69148 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
69149 + ("running in guest-mode without IPC!"));
69150 +
69151 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
69152 + WRITE_UINT32(p_Iram->iadd, 0x4);
69153 + while (GET_UINT32(p_Iram->iadd) != 0x4) ;
69154 + revInfo = GET_UINT32(p_Iram->idata);
69155 + p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16);
69156 + p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8);
69157 + p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF);
69158 +
69159 + return E_OK;
69160 +}
69161 +
69162 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
69163 +{
69164 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69165 + t_Error err;
69166 + uint32_t counterValue;
69167 + struct fman_rg fman_rg;
69168 + enum fman_counters fsl_counter;
69169 +
69170 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
69171 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
69172 +
69173 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69174 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69175 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69176 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69177 +
69178 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
69179 + !p_Fm->baseAddr &&
69180 + p_Fm->h_IpcSessions[0])
69181 + {
69182 + t_FmIpcMsg msg;
69183 + t_FmIpcReply reply;
69184 + uint32_t replyLength, outCounter;
69185 +
69186 + memset(&msg, 0, sizeof(msg));
69187 + memset(&reply, 0, sizeof(reply));
69188 + msg.msgId = FM_GET_COUNTER;
69189 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
69190 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
69191 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69192 + (uint8_t*)&msg,
69193 + sizeof(msg.msgId) +sizeof(counterValue),
69194 + (uint8_t*)&reply,
69195 + &replyLength,
69196 + NULL,
69197 + NULL);
69198 + if (err != E_OK)
69199 + {
69200 + REPORT_ERROR(MAJOR, err, NO_MSG);
69201 + return 0;
69202 + }
69203 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
69204 + {
69205 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69206 + return 0;
69207 + }
69208 +
69209 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
69210 + return outCounter;
69211 + }
69212 + else if (!p_Fm->baseAddr)
69213 + {
69214 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!"));
69215 + return 0;
69216 + }
69217 +
69218 + /* When applicable (when there is an 'enable counters' bit,
69219 + check that counters are enabled */
69220 + switch (counter)
69221 + {
69222 + case (e_FM_COUNTERS_DEQ_1):
69223 + case (e_FM_COUNTERS_DEQ_2):
69224 + case (e_FM_COUNTERS_DEQ_3):
69225 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) ||
69226 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
69227 + {
69228 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported"));
69229 + return 0;
69230 + }
69231 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
69232 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
69233 + case (e_FM_COUNTERS_DEQ_0):
69234 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
69235 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
69236 + case (e_FM_COUNTERS_DEQ_FROM_FD):
69237 + case (e_FM_COUNTERS_DEQ_CONFIRM):
69238 + if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
69239 + {
69240 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled"));
69241 + return 0;
69242 + }
69243 + break;
69244 + default:
69245 + break;
69246 + }
69247 +
69248 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
69249 + return fman_get_counter(&fman_rg, fsl_counter);
69250 +}
69251 +
69252 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
69253 +{
69254 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69255 + struct fman_rg fman_rg;
69256 + enum fman_counters fsl_counter;
69257 +
69258 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69259 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69260 +
69261 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69262 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69263 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69264 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69265 +
69266 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
69267 + return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val);
69268 +}
69269 +
69270 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
69271 +{
69272 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69273 + struct fman_dma_regs *dma_rg;
69274 +
69275 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69276 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69277 +
69278 + dma_rg = p_Fm->p_FmDmaRegs;
69279 +
69280 + fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable);
69281 +}
69282 +
69283 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
69284 +{
69285 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69286 + struct fman_dma_regs *dma_rg;
69287 +
69288 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69289 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69290 +
69291 + dma_rg = p_Fm->p_FmDmaRegs;
69292 +
69293 + fman_set_dma_ext_bus_pri(dma_rg, pri);
69294 +}
69295 +
69296 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
69297 +{
69298 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69299 + uint32_t dmaStatus;
69300 + struct fman_dma_regs *dma_rg;
69301 +
69302 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69303 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69304 +
69305 + dma_rg = p_Fm->p_FmDmaRegs;
69306 +
69307 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
69308 + !p_Fm->baseAddr &&
69309 + p_Fm->h_IpcSessions[0])
69310 + {
69311 + t_FmIpcDmaStatus ipcDmaStatus;
69312 + t_FmIpcMsg msg;
69313 + t_FmIpcReply reply;
69314 + t_Error err;
69315 + uint32_t replyLength;
69316 +
69317 + memset(&msg, 0, sizeof(msg));
69318 + memset(&reply, 0, sizeof(reply));
69319 + msg.msgId = FM_DMA_STAT;
69320 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
69321 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69322 + (uint8_t*)&msg,
69323 + sizeof(msg.msgId),
69324 + (uint8_t*)&reply,
69325 + &replyLength,
69326 + NULL,
69327 + NULL);
69328 + if (err != E_OK)
69329 + {
69330 + REPORT_ERROR(MINOR, err, NO_MSG);
69331 + return;
69332 + }
69333 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
69334 + {
69335 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69336 + return;
69337 + }
69338 + memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
69339 +
69340 + p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
69341 + p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
69342 + p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
69343 + p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
69344 + p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
69345 + p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */
69346 + return;
69347 + }
69348 + else if (!p_Fm->baseAddr)
69349 + {
69350 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
69351 + ("Either IPC or 'baseAddress' is required!"));
69352 + return;
69353 + }
69354 +
69355 + dmaStatus = fman_get_dma_status(dma_rg);
69356 +
69357 + p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
69358 + p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR);
69359 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69360 + p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC);
69361 + else
69362 + {
69363 + p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC);
69364 + p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC);
69365 + p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC);
69366 + }
69367 +}
69368 +
69369 +void FM_Resume(t_Handle h_Fm)
69370 +{
69371 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69372 + struct fman_fpm_regs *fpm_rg;
69373 +
69374 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69375 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69376 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69377 +
69378 + fpm_rg = p_Fm->p_FmFpmRegs;
69379 +
69380 + fman_resume(fpm_rg);
69381 +}
69382 +
69383 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
69384 + fmSpecialOperations_t spOper,
69385 + uint8_t *p_SpOperCoding)
69386 +{
69387 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69388 + t_FmCtrlCodeRevisionInfo revInfo;
69389 + t_Error err;
69390 +
69391 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69392 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69393 + SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER);
69394 +
69395 + if (!spOper)
69396 + {
69397 + *p_SpOperCoding = 0;
69398 + return E_OK;
69399 + }
69400 +
69401 + if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK)
69402 + {
69403 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
69404 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
69405 + }
69406 + else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
69407 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
69408 +
69409 + switch (spOper)
69410 + {
69411 + case (FM_SP_OP_CAPWAP_DTLS_DEC):
69412 + *p_SpOperCoding = 9;
69413 + break;
69414 + case (FM_SP_OP_CAPWAP_DTLS_ENC):
69415 + *p_SpOperCoding = 10;
69416 + break;
69417 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP):
69418 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69419 + *p_SpOperCoding = 5;
69420 + break;
69421 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP):
69422 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69423 + *p_SpOperCoding = 6;
69424 + break;
69425 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD):
69426 + *p_SpOperCoding = 3;
69427 + break;
69428 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN):
69429 + *p_SpOperCoding = 1;
69430 + break;
69431 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR):
69432 + *p_SpOperCoding = 12;
69433 + break;
69434 + case (FM_SP_OP_IPSEC|FM_SP_OP_RPD):
69435 + *p_SpOperCoding = 4;
69436 + break;
69437 + case (FM_SP_OP_IPSEC):
69438 + *p_SpOperCoding = 2;
69439 + break;
69440 + case (FM_SP_OP_DCL4C):
69441 + *p_SpOperCoding = 7;
69442 + break;
69443 + case (FM_SP_OP_CLEAR_RPD):
69444 + *p_SpOperCoding = 8;
69445 + break;
69446 + default:
69447 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
69448 + }
69449 +
69450 + return E_OK;
69451 +}
69452 +
69453 +t_Error FM_CtrlMonStart(t_Handle h_Fm)
69454 +{
69455 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69456 + t_FmTrbRegs *p_MonRegs;
69457 + uint8_t i;
69458 +
69459 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69460 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69461 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69462 +
69463 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69464 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG);
69465 +
69466 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69467 + {
69468 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69469 +
69470 + /* Reset control registers */
69471 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET);
69472 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET);
69473 +
69474 + /* Configure: counter #1 counts all stalls in risc - ldsched stall
69475 + counter #2 counts all stalls in risc - other stall*/
69476 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL);
69477 +
69478 + /* Enable monitoring */
69479 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS);
69480 + }
69481 +
69482 + return E_OK;
69483 +}
69484 +
69485 +t_Error FM_CtrlMonStop(t_Handle h_Fm)
69486 +{
69487 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69488 + t_FmTrbRegs *p_MonRegs;
69489 + uint8_t i;
69490 +
69491 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69492 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69493 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69494 +
69495 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69496 + {
69497 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69498 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS);
69499 + }
69500 +
69501 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69502 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG);
69503 +
69504 + return E_OK;
69505 +}
69506 +
69507 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon)
69508 +{
69509 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69510 + t_FmTrbRegs *p_MonRegs;
69511 + uint64_t clkCnt, utilValue, effValue;
69512 +
69513 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69514 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69515 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69516 + SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER);
69517 +
69518 + if (fmCtrlIndex >= FM_NUM_OF_CTRL)
69519 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index"));
69520 +
69521 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex));
69522 +
69523 + clkCnt = (uint64_t)
69524 + ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl));
69525 +
69526 + utilValue = (uint64_t)
69527 + ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l));
69528 +
69529 + effValue = (uint64_t)
69530 + ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l));
69531 +
69532 + p_Mon->percentCnt[0] = (uint8_t)div64_u64((clkCnt - utilValue) * 100, clkCnt);
69533 + if (clkCnt != utilValue)
69534 + p_Mon->percentCnt[1] = (uint8_t)div64_u64(((clkCnt - utilValue) - effValue) * 100, clkCnt - utilValue);
69535 + else
69536 + p_Mon->percentCnt[1] = 0;
69537 +
69538 + return E_OK;
69539 +}
69540 +
69541 +t_Handle FM_GetMuramHandle(t_Handle h_Fm)
69542 +{
69543 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69544 +
69545 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
69546 +
69547 + return (p_Fm->h_FmMuram);
69548 +}
69549 +
69550 +/****************************************************/
69551 +/* Hidden-DEBUG Only API */
69552 +/****************************************************/
69553 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
69554 +{
69555 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69556 + enum fman_exceptions fslException;
69557 + struct fman_rg fman_rg;
69558 +
69559 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69560 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69561 +
69562 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69563 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69564 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69565 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69566 +
69567 + switch (exception)
69568 + {
69569 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
69570 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
69571 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69572 + break;
69573 + case e_FM_EX_QMI_SINGLE_ECC:
69574 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69575 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration."));
69576 +
69577 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
69578 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69579 + break;
69580 + case e_FM_EX_QMI_DOUBLE_ECC:
69581 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
69582 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69583 + break;
69584 + case e_FM_EX_BMI_LIST_RAM_ECC:
69585 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
69586 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69587 + break;
69588 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
69589 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC))
69590 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69591 + break;
69592 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
69593 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
69594 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69595 + break;
69596 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
69597 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
69598 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69599 + break;
69600 + default:
69601 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
69602 + }
69603 +
69604 + fslException = FmanExceptionTrans(exception);
69605 + fman_force_intr (&fman_rg, fslException);
69606 +
69607 + return E_OK;
69608 +}
69609 +
69610 +t_Handle FmGetPcd(t_Handle h_Fm)
69611 +{
69612 + return ((t_Fm*)h_Fm)->h_Pcd;
69613 +}
69614 +#if (DPAA_VERSION >= 11)
69615 +extern void *g_MemacRegs;
69616 +void fm_clk_down(void);
69617 +uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask);
69618 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId)
69619 +{
69620 + int macId;
69621 + uint32_t event, rcr;
69622 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69623 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69624 + rcr |= 0x04000000;
69625 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69626 +
69627 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
69628 + do
69629 + {
69630 + event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF);
69631 + } while ((event & 0x00000020) == 0);
69632 + fm_clk_down();
69633 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69634 + rcr &= ~0x04000000;
69635 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69636 +}
69637 +#endif
69638 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
69639 new file mode 100644
69640 index 00000000..0bded75d
69641 --- /dev/null
69642 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
69643 @@ -0,0 +1,648 @@
69644 +/*
69645 + * Copyright 2008-2012 Freescale Semiconductor Inc.
69646 + *
69647 + * Redistribution and use in source and binary forms, with or without
69648 + * modification, are permitted provided that the following conditions are met:
69649 + * * Redistributions of source code must retain the above copyright
69650 + * notice, this list of conditions and the following disclaimer.
69651 + * * Redistributions in binary form must reproduce the above copyright
69652 + * notice, this list of conditions and the following disclaimer in the
69653 + * documentation and/or other materials provided with the distribution.
69654 + * * Neither the name of Freescale Semiconductor nor the
69655 + * names of its contributors may be used to endorse or promote products
69656 + * derived from this software without specific prior written permission.
69657 + *
69658 + *
69659 + * ALTERNATIVELY, this software may be distributed under the terms of the
69660 + * GNU General Public License ("GPL") as published by the Free Software
69661 + * Foundation, either version 2 of that License or (at your option) any
69662 + * later version.
69663 + *
69664 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
69665 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69666 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
69667 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
69668 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69669 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69670 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
69671 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69672 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69673 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69674 + */
69675 +
69676 +
69677 +/******************************************************************************
69678 + @File fm.h
69679 +
69680 + @Description FM internal structures and definitions.
69681 +*//***************************************************************************/
69682 +#ifndef __FM_H
69683 +#define __FM_H
69684 +
69685 +#include "error_ext.h"
69686 +#include "std_ext.h"
69687 +#include "fm_ext.h"
69688 +#include "fm_ipc.h"
69689 +
69690 +#include "fsl_fman.h"
69691 +
69692 +#define __ERR_MODULE__ MODULE_FM
69693 +
69694 +#define FM_MAX_NUM_OF_HW_PORT_IDS 64
69695 +#define FM_MAX_NUM_OF_GUESTS 100
69696 +
69697 +/**************************************************************************//**
69698 + @Description Exceptions
69699 +*//***************************************************************************/
69700 +#define FM_EX_DMA_BUS_ERROR 0x80000000 /**< DMA bus error. */
69701 +#define FM_EX_DMA_READ_ECC 0x40000000
69702 +#define FM_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
69703 +#define FM_EX_DMA_FM_WRITE_ECC 0x10000000
69704 +#define FM_EX_FPM_STALL_ON_TASKS 0x08000000 /**< Stall of tasks on FPM */
69705 +#define FM_EX_FPM_SINGLE_ECC 0x04000000 /**< Single ECC on FPM */
69706 +#define FM_EX_FPM_DOUBLE_ECC 0x02000000
69707 +#define FM_EX_QMI_SINGLE_ECC 0x01000000 /**< Single ECC on FPM */
69708 +#define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */
69709 +#define FM_EX_QMI_DOUBLE_ECC 0x00400000
69710 +#define FM_EX_BMI_LIST_RAM_ECC 0x00200000
69711 +#define FM_EX_BMI_STORAGE_PROFILE_ECC 0x00100000
69712 +#define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000
69713 +#define FM_EX_IRAM_ECC 0x00040000
69714 +#define FM_EX_MURAM_ECC 0x00020000
69715 +#define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000
69716 +#define FM_EX_DMA_SINGLE_PORT_ECC 0x00008000
69717 +
69718 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
69719 +
69720 +#define DMA_THRESH_COMMQ_MASK 0xFF000000
69721 +#define DMA_THRESH_READ_INT_BUF_MASK 0x007F0000
69722 +#define DMA_THRESH_WRITE_INT_BUF_MASK 0x0000007F
69723 +
69724 +#define GET_EXCEPTION_FLAG(bitMask, exception) \
69725 +switch (exception){ \
69726 + case e_FM_EX_DMA_BUS_ERROR: \
69727 + bitMask = FM_EX_DMA_BUS_ERROR; break; \
69728 + case e_FM_EX_DMA_SINGLE_PORT_ECC: \
69729 + bitMask = FM_EX_DMA_SINGLE_PORT_ECC; break; \
69730 + case e_FM_EX_DMA_READ_ECC: \
69731 + bitMask = FM_EX_DMA_READ_ECC; break; \
69732 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \
69733 + bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \
69734 + case e_FM_EX_DMA_FM_WRITE_ECC: \
69735 + bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \
69736 + case e_FM_EX_FPM_STALL_ON_TASKS: \
69737 + bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \
69738 + case e_FM_EX_FPM_SINGLE_ECC: \
69739 + bitMask = FM_EX_FPM_SINGLE_ECC; break; \
69740 + case e_FM_EX_FPM_DOUBLE_ECC: \
69741 + bitMask = FM_EX_FPM_DOUBLE_ECC; break; \
69742 + case e_FM_EX_QMI_SINGLE_ECC: \
69743 + bitMask = FM_EX_QMI_SINGLE_ECC; break; \
69744 + case e_FM_EX_QMI_DOUBLE_ECC: \
69745 + bitMask = FM_EX_QMI_DOUBLE_ECC; break; \
69746 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \
69747 + bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \
69748 + case e_FM_EX_BMI_LIST_RAM_ECC: \
69749 + bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \
69750 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: \
69751 + bitMask = FM_EX_BMI_STORAGE_PROFILE_ECC; break; \
69752 + case e_FM_EX_BMI_STATISTICS_RAM_ECC: \
69753 + bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \
69754 + case e_FM_EX_BMI_DISPATCH_RAM_ECC: \
69755 + bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \
69756 + case e_FM_EX_IRAM_ECC: \
69757 + bitMask = FM_EX_IRAM_ECC; break; \
69758 + case e_FM_EX_MURAM_ECC: \
69759 + bitMask = FM_EX_MURAM_ECC; break; \
69760 + default: bitMask = 0;break; \
69761 +}
69762 +
69763 +#define GET_FM_MODULE_EVENT(_mod, _id, _intrType, _event) \
69764 + switch (_mod) { \
69765 + case e_FM_MOD_PRS: \
69766 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69767 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
69768 + break; \
69769 + case e_FM_MOD_KG: \
69770 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69771 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
69772 + break; \
69773 + case e_FM_MOD_PLCR: \
69774 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69775 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
69776 + break; \
69777 + case e_FM_MOD_TMR: \
69778 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69779 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
69780 + break; \
69781 + case e_FM_MOD_10G_MAC: \
69782 + if (_id >= FM_MAX_NUM_OF_10G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69783 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_10G_MAC0 + _id) : (e_FM_EV_10G_MAC0 + _id); \
69784 + break; \
69785 + case e_FM_MOD_1G_MAC: \
69786 + if (_id >= FM_MAX_NUM_OF_1G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69787 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_1G_MAC0 + _id) : (e_FM_EV_1G_MAC0 + _id); \
69788 + break; \
69789 + case e_FM_MOD_MACSEC: \
69790 + switch (_id){ \
69791 + case (0): _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_MACSEC_MAC0:e_FM_EV_MACSEC_MAC0; \
69792 + break; \
69793 + } \
69794 + break; \
69795 + case e_FM_MOD_FMAN_CTRL: \
69796 + if (_intrType == e_FM_INTR_TYPE_ERR) _event = e_FM_EV_DUMMY_LAST; \
69797 + else _event = (e_FM_EV_FMAN_CTRL_0 + _id); \
69798 + break; \
69799 + default: _event = e_FM_EV_DUMMY_LAST; \
69800 + break; \
69801 + }
69802 +
69803 +#define FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, _cache_override) \
69804 + switch (_cache_override){ \
69805 + case e_FM_DMA_NO_CACHE_OR: \
69806 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69807 + case e_FM_DMA_NO_STASH_DATA: \
69808 + fsl_cache_override = E_FMAN_DMA_NO_STASH_DATA; break; \
69809 + case e_FM_DMA_MAY_STASH_DATA: \
69810 + fsl_cache_override = E_FMAN_DMA_MAY_STASH_DATA; break; \
69811 + case e_FM_DMA_STASH_DATA: \
69812 + fsl_cache_override = E_FMAN_DMA_STASH_DATA; break; \
69813 + default: \
69814 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69815 + }
69816 +
69817 +#define FMAN_AID_MODE_TRANS(fsl_aid_mode, _aid_mode) \
69818 + switch (_aid_mode){ \
69819 + case e_FM_DMA_AID_OUT_PORT_ID: \
69820 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69821 + case e_FM_DMA_AID_OUT_TNUM: \
69822 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_TNUM; break; \
69823 + default: \
69824 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69825 + }
69826 +
69827 +#define FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, _dma_dbg_cnt) \
69828 + switch (_dma_dbg_cnt){ \
69829 + case e_FM_DMA_DBG_NO_CNT: \
69830 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69831 + case e_FM_DMA_DBG_CNT_DONE: \
69832 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_DONE; break; \
69833 + case e_FM_DMA_DBG_CNT_COMM_Q_EM: \
69834 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_COMM_Q_EM; break; \
69835 + case e_FM_DMA_DBG_CNT_INT_READ_EM: \
69836 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_READ_EM; break; \
69837 + case e_FM_DMA_DBG_CNT_INT_WRITE_EM: \
69838 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_WRITE_EM ; break; \
69839 + case e_FM_DMA_DBG_CNT_FPM_WAIT: \
69840 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_FPM_WAIT ; break; \
69841 + case e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC: \
69842 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC ; break; \
69843 + case e_FM_DMA_DBG_CNT_RAW_WAR_PROT: \
69844 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT ; break; \
69845 + default: \
69846 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69847 + }
69848 +
69849 +#define FMAN_DMA_EMER_TRANS(fsl_dma_emer, _dma_emer) \
69850 + switch (_dma_emer){ \
69851 + case e_FM_DMA_EM_EBS: \
69852 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69853 + case e_FM_DMA_EM_SOS: \
69854 + fsl_dma_emer = E_FMAN_DMA_EM_SOS; break; \
69855 + default: \
69856 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69857 + }
69858 +
69859 +#define FMAN_DMA_ERR_TRANS(fsl_dma_err, _dma_err) \
69860 + switch (_dma_err){ \
69861 + case e_FM_DMA_ERR_CATASTROPHIC: \
69862 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69863 + case e_FM_DMA_ERR_REPORT: \
69864 + fsl_dma_err = E_FMAN_DMA_ERR_REPORT; break; \
69865 + default: \
69866 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69867 + }
69868 +
69869 +#define FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, _catastrophic_err) \
69870 + switch (_catastrophic_err){ \
69871 + case e_FM_CATASTROPHIC_ERR_STALL_PORT: \
69872 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69873 + case e_FM_CATASTROPHIC_ERR_STALL_TASK: \
69874 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_TASK; break; \
69875 + default: \
69876 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69877 + }
69878 +
69879 +#define FMAN_COUNTERS_TRANS(fsl_counters, _counters) \
69880 + switch (_counters){ \
69881 + case e_FM_COUNTERS_ENQ_TOTAL_FRAME: \
69882 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69883 + case e_FM_COUNTERS_DEQ_TOTAL_FRAME: \
69884 + fsl_counters = E_FMAN_COUNTERS_DEQ_TOTAL_FRAME; break; \
69885 + case e_FM_COUNTERS_DEQ_0: \
69886 + fsl_counters = E_FMAN_COUNTERS_DEQ_0; break; \
69887 + case e_FM_COUNTERS_DEQ_1: \
69888 + fsl_counters = E_FMAN_COUNTERS_DEQ_1; break; \
69889 + case e_FM_COUNTERS_DEQ_2: \
69890 + fsl_counters = E_FMAN_COUNTERS_DEQ_2; break; \
69891 + case e_FM_COUNTERS_DEQ_3: \
69892 + fsl_counters = E_FMAN_COUNTERS_DEQ_3; break; \
69893 + case e_FM_COUNTERS_DEQ_FROM_DEFAULT: \
69894 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_DEFAULT; break; \
69895 + case e_FM_COUNTERS_DEQ_FROM_CONTEXT: \
69896 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_CONTEXT; break; \
69897 + case e_FM_COUNTERS_DEQ_FROM_FD: \
69898 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_FD; break; \
69899 + case e_FM_COUNTERS_DEQ_CONFIRM: \
69900 + fsl_counters = E_FMAN_COUNTERS_DEQ_CONFIRM; break; \
69901 + default: \
69902 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69903 + }
69904 +
69905 +/**************************************************************************//**
69906 + @Description defaults
69907 +*//***************************************************************************/
69908 +#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\
69909 + FM_EX_DMA_READ_ECC |\
69910 + FM_EX_DMA_SYSTEM_WRITE_ECC |\
69911 + FM_EX_DMA_FM_WRITE_ECC |\
69912 + FM_EX_FPM_STALL_ON_TASKS |\
69913 + FM_EX_FPM_SINGLE_ECC |\
69914 + FM_EX_FPM_DOUBLE_ECC |\
69915 + FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\
69916 + FM_EX_BMI_LIST_RAM_ECC |\
69917 + FM_EX_BMI_STORAGE_PROFILE_ECC |\
69918 + FM_EX_BMI_STATISTICS_RAM_ECC |\
69919 + FM_EX_IRAM_ECC |\
69920 + FM_EX_MURAM_ECC |\
69921 + FM_EX_BMI_DISPATCH_RAM_ECC |\
69922 + FM_EX_QMI_DOUBLE_ECC |\
69923 + FM_EX_QMI_SINGLE_ECC)
69924 +
69925 +#define DEFAULT_eccEnable FALSE
69926 +#ifdef FM_PEDANTIC_DMA
69927 +#define DEFAULT_aidOverride TRUE
69928 +#else
69929 +#define DEFAULT_aidOverride FALSE
69930 +#endif /* FM_PEDANTIC_DMA */
69931 +#define DEFAULT_aidMode e_FM_DMA_AID_OUT_TNUM
69932 +#define DEFAULT_dmaStopOnBusError FALSE
69933 +#define DEFAULT_stopAtBusError FALSE
69934 +#define DEFAULT_axiDbgNumOfBeats 1
69935 +#define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69936 +#define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69937 +#define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69938 +#define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69939 +#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT
69940 +#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC
69941 +#define DEFAULT_resetOnInit FALSE
69942 +#define DEFAULT_resetOnInitOverrideCallback NULL
69943 +#define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */
69944 +#define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */
69945 +#define DEFAULT_externalEccRamsEnable FALSE
69946 +#define DEFAULT_VerifyUcode FALSE
69947 +
69948 +#if (DPAA_VERSION < 11)
69949 +#define DEFAULT_totalFifoSize(major, minor) \
69950 + (((major == 2) || (major == 5)) ? \
69951 + (100*KILOBYTE) : ((major == 4) ? \
69952 + (49*KILOBYTE) : (122*KILOBYTE)))
69953 +#define DEFAULT_totalNumOfTasks(major, minor) \
69954 + BMI_MAX_NUM_OF_TASKS
69955 +
69956 +#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2)
69957 +#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4)
69958 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69959 +#define DEFAULT_dmaCamNumOfEntries 32
69960 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69961 +#define DEFAULT_dmaEnEmergency FALSE
69962 +#define DEFAULT_dmaSosEmergency 0
69963 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69964 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69965 +#define DEFAULT_dmaEmergencySwitchCounter 0
69966 +
69967 +#define DEFAULT_dispLimit 0
69968 +#define DEFAULT_prsDispTh 16
69969 +#define DEFAULT_plcrDispTh 16
69970 +#define DEFAULT_kgDispTh 16
69971 +#define DEFAULT_bmiDispTh 16
69972 +#define DEFAULT_qmiEnqDispTh 16
69973 +#define DEFAULT_qmiDeqDispTh 16
69974 +#define DEFAULT_fmCtl1DispTh 16
69975 +#define DEFAULT_fmCtl2DispTh 16
69976 +
69977 +#else /* (DPAA_VERSION < 11) */
69978 +/* Defaults are registers' reset values */
69979 +#define DEFAULT_totalFifoSize(major, minor) \
69980 + (((major == 6) && ((minor == 1) || (minor == 4))) ? \
69981 + (156*KILOBYTE) : (295*KILOBYTE))
69982 +
69983 +/* According to the default value of FMBM_CFG2[TNTSKS] */
69984 +#define DEFAULT_totalNumOfTasks(major, minor) \
69985 + (((major == 6) && ((minor == 1) || (minor == 4))) ? 59 : 124)
69986 +
69987 +#define DEFAULT_dmaCommQLow 0x2A
69988 +#define DEFAULT_dmaCommQHigh 0x3F
69989 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69990 +#define DEFAULT_dmaCamNumOfEntries 64
69991 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69992 +#define DEFAULT_dmaEnEmergency FALSE
69993 +#define DEFAULT_dmaSosEmergency 0
69994 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69995 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69996 +#define DEFAULT_dmaEmergencySwitchCounter 0
69997 +
69998 +#define DEFAULT_dispLimit 0
69999 +#define DEFAULT_prsDispTh 16
70000 +#define DEFAULT_plcrDispTh 16
70001 +#define DEFAULT_kgDispTh 16
70002 +#define DEFAULT_bmiDispTh 16
70003 +#define DEFAULT_qmiEnqDispTh 16
70004 +#define DEFAULT_qmiDeqDispTh 16
70005 +#define DEFAULT_fmCtl1DispTh 16
70006 +#define DEFAULT_fmCtl2DispTh 16
70007 +#endif /* (DPAA_VERSION < 11) */
70008 +
70009 +#define FM_TIMESTAMP_1_USEC_BIT 8
70010 +
70011 +/**************************************************************************//**
70012 + @Collection Defines used for enabling/disabling FM interrupts
70013 + @{
70014 +*//***************************************************************************/
70015 +#define ERR_INTR_EN_DMA 0x00010000
70016 +#define ERR_INTR_EN_FPM 0x80000000
70017 +#define ERR_INTR_EN_BMI 0x00800000
70018 +#define ERR_INTR_EN_QMI 0x00400000
70019 +#define ERR_INTR_EN_PRS 0x00200000
70020 +#define ERR_INTR_EN_KG 0x00100000
70021 +#define ERR_INTR_EN_PLCR 0x00080000
70022 +#define ERR_INTR_EN_MURAM 0x00040000
70023 +#define ERR_INTR_EN_IRAM 0x00020000
70024 +#define ERR_INTR_EN_10G_MAC0 0x00008000
70025 +#define ERR_INTR_EN_10G_MAC1 0x00000040
70026 +#define ERR_INTR_EN_1G_MAC0 0x00004000
70027 +#define ERR_INTR_EN_1G_MAC1 0x00002000
70028 +#define ERR_INTR_EN_1G_MAC2 0x00001000
70029 +#define ERR_INTR_EN_1G_MAC3 0x00000800
70030 +#define ERR_INTR_EN_1G_MAC4 0x00000400
70031 +#define ERR_INTR_EN_1G_MAC5 0x00000200
70032 +#define ERR_INTR_EN_1G_MAC6 0x00000100
70033 +#define ERR_INTR_EN_1G_MAC7 0x00000080
70034 +#define ERR_INTR_EN_MACSEC_MAC0 0x00000001
70035 +
70036 +#define INTR_EN_QMI 0x40000000
70037 +#define INTR_EN_PRS 0x20000000
70038 +#define INTR_EN_WAKEUP 0x10000000
70039 +#define INTR_EN_PLCR 0x08000000
70040 +#define INTR_EN_1G_MAC0 0x00080000
70041 +#define INTR_EN_1G_MAC1 0x00040000
70042 +#define INTR_EN_1G_MAC2 0x00020000
70043 +#define INTR_EN_1G_MAC3 0x00010000
70044 +#define INTR_EN_1G_MAC4 0x00000040
70045 +#define INTR_EN_1G_MAC5 0x00000020
70046 +#define INTR_EN_1G_MAC6 0x00000008
70047 +#define INTR_EN_1G_MAC7 0x00000002
70048 +#define INTR_EN_10G_MAC0 0x00200000
70049 +#define INTR_EN_10G_MAC1 0x00100000
70050 +#define INTR_EN_REV0 0x00008000
70051 +#define INTR_EN_REV1 0x00004000
70052 +#define INTR_EN_REV2 0x00002000
70053 +#define INTR_EN_REV3 0x00001000
70054 +#define INTR_EN_BRK 0x00000080
70055 +#define INTR_EN_TMR 0x01000000
70056 +#define INTR_EN_MACSEC_MAC0 0x00000001
70057 +/* @} */
70058 +
70059 +/**************************************************************************//**
70060 + @Description Memory Mapped Registers
70061 +*//***************************************************************************/
70062 +
70063 +#if defined(__MWERKS__) && !defined(__GNUC__)
70064 +#pragma pack(push,1)
70065 +#endif /* defined(__MWERKS__) && ... */
70066 +
70067 +typedef struct
70068 +{
70069 + volatile uint32_t iadd; /**< FM IRAM instruction address register */
70070 + volatile uint32_t idata; /**< FM IRAM instruction data register */
70071 + volatile uint32_t itcfg; /**< FM IRAM timing config register */
70072 + volatile uint32_t iready; /**< FM IRAM ready register */
70073 + volatile uint32_t res[0x1FFFC];
70074 +} t_FMIramRegs;
70075 +
70076 +/* Trace buffer registers -
70077 + each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */
70078 +typedef struct t_FmTrbRegs
70079 +{
70080 + volatile uint32_t tcrh;
70081 + volatile uint32_t tcrl;
70082 + volatile uint32_t tesr;
70083 + volatile uint32_t tecr0h;
70084 + volatile uint32_t tecr0l;
70085 + volatile uint32_t terf0h;
70086 + volatile uint32_t terf0l;
70087 + volatile uint32_t tecr1h;
70088 + volatile uint32_t tecr1l;
70089 + volatile uint32_t terf1h;
70090 + volatile uint32_t terf1l;
70091 + volatile uint32_t tpcch;
70092 + volatile uint32_t tpccl;
70093 + volatile uint32_t tpc1h;
70094 + volatile uint32_t tpc1l;
70095 + volatile uint32_t tpc2h;
70096 + volatile uint32_t tpc2l;
70097 + volatile uint32_t twdimr;
70098 + volatile uint32_t twicvr;
70099 + volatile uint32_t tar;
70100 + volatile uint32_t tdr;
70101 + volatile uint32_t tsnum1;
70102 + volatile uint32_t tsnum2;
70103 + volatile uint32_t tsnum3;
70104 + volatile uint32_t tsnum4;
70105 +} t_FmTrbRegs;
70106 +
70107 +#if defined(__MWERKS__) && !defined(__GNUC__)
70108 +#pragma pack(pop)
70109 +#endif /* defined(__MWERKS__) && ... */
70110 +
70111 +/**************************************************************************//**
70112 + @Description General defines
70113 +*//***************************************************************************/
70114 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
70115 +#define FM_FW_DEBUG_INSTRUCTION 0x6ffff805UL
70116 +
70117 +/**************************************************************************//**
70118 + @Description FPM defines
70119 +*//***************************************************************************/
70120 +/* masks */
70121 +#define FPM_BRKC_RDBG 0x00000200
70122 +#define FPM_BRKC_SLP 0x00000800
70123 +/**************************************************************************//**
70124 + @Description BMI defines
70125 +*//***************************************************************************/
70126 +/* masks */
70127 +#define BMI_INIT_START 0x80000000
70128 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
70129 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
70130 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
70131 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
70132 +/**************************************************************************//**
70133 + @Description QMI defines
70134 +*//***************************************************************************/
70135 +/* masks */
70136 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
70137 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
70138 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
70139 +
70140 +/**************************************************************************//**
70141 + @Description IRAM defines
70142 +*//***************************************************************************/
70143 +/* masks */
70144 +#define IRAM_IADD_AIE 0x80000000
70145 +#define IRAM_READY 0x80000000
70146 +
70147 +/**************************************************************************//**
70148 + @Description TRB defines
70149 +*//***************************************************************************/
70150 +/* masks */
70151 +#define TRB_TCRH_RESET 0x04000000
70152 +#define TRB_TCRH_ENABLE_COUNTERS 0x84008000
70153 +#define TRB_TCRH_DISABLE_COUNTERS 0x8400C000
70154 +#define TRB_TCRL_RESET 0x20000000
70155 +#define TRB_TCRL_UTIL 0x00000460
70156 +typedef struct {
70157 + void (*f_Isr) (t_Handle h_Arg, uint32_t event);
70158 + t_Handle h_SrcHandle;
70159 +} t_FmanCtrlIntrSrc;
70160 +
70161 +
70162 +typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event);
70163 +
70164 +typedef struct
70165 +{
70166 +/***************************/
70167 +/* Master/Guest parameters */
70168 +/***************************/
70169 + uint8_t fmId;
70170 + e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS];
70171 + uint16_t fmClkFreq;
70172 + uint16_t fmMacClkFreq;
70173 + t_FmRevisionInfo revInfo;
70174 +/**************************/
70175 +/* Master Only parameters */
70176 +/**************************/
70177 + bool enabledTimeStamp;
70178 + uint8_t count1MicroBit;
70179 + uint8_t totalNumOfTasks;
70180 + uint32_t totalFifoSize;
70181 + uint8_t maxNumOfOpenDmas;
70182 + uint8_t accumulatedNumOfTasks;
70183 + uint32_t accumulatedFifoSize;
70184 + uint8_t accumulatedNumOfOpenDmas;
70185 + uint8_t accumulatedNumOfDeqTnums;
70186 +#ifdef FM_LOW_END_RESTRICTION
70187 + bool lowEndRestriction;
70188 +#endif /* FM_LOW_END_RESTRICTION */
70189 + uint32_t exceptions;
70190 + int irq;
70191 + int errIrq;
70192 + bool ramsEccEnable;
70193 + bool explicitEnable;
70194 + bool internalCall;
70195 + uint8_t ramsEccOwners;
70196 + uint32_t extraFifoPoolSize;
70197 + uint8_t extraTasksPoolSize;
70198 + uint8_t extraOpenDmasPoolSize;
70199 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
70200 + uint16_t portMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
70201 + uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
70202 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
70203 + uint16_t portMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
70204 + uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
70205 +} t_FmStateStruct;
70206 +
70207 +#if (DPAA_VERSION >= 11)
70208 +typedef struct t_FmMapParam {
70209 + uint16_t profilesBase;
70210 + uint16_t numOfProfiles;
70211 + t_Handle h_FmPort;
70212 +} t_FmMapParam;
70213 +
70214 +typedef struct t_FmAllocMng {
70215 + bool allocated;
70216 + uint8_t ownerId; /* guestId for KG in multi-partition only,
70217 + portId for PLCR in any environment */
70218 +} t_FmAllocMng;
70219 +
70220 +typedef struct t_FmPcdSpEntry {
70221 + bool valid;
70222 + t_FmAllocMng profilesMng;
70223 +} t_FmPcdSpEntry;
70224 +
70225 +typedef struct t_FmSp {
70226 + void *p_FmPcdStoragePrflRegs;
70227 + t_FmPcdSpEntry profiles[FM_VSP_MAX_NUM_OF_ENTRIES];
70228 + t_FmMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
70229 +} t_FmSp;
70230 +#endif /* (DPAA_VERSION >= 11) */
70231 +
70232 +typedef struct t_Fm
70233 +{
70234 +/***************************/
70235 +/* Master/Guest parameters */
70236 +/***************************/
70237 +/* locals for recovery */
70238 + uintptr_t baseAddr;
70239 +
70240 +/* un-needed for recovery */
70241 + t_Handle h_Pcd;
70242 + char fmModuleName[MODULE_NAME_SIZE];
70243 + char fmIpcHandlerModuleName[FM_MAX_NUM_OF_GUESTS][MODULE_NAME_SIZE];
70244 + t_Handle h_IpcSessions[FM_MAX_NUM_OF_GUESTS];
70245 + t_FmIntrSrc intrMng[e_FM_EV_DUMMY_LAST]; /* FM exceptions user callback */
70246 + uint8_t guestId;
70247 +/**************************/
70248 +/* Master Only parameters */
70249 +/**************************/
70250 +/* locals for recovery */
70251 + struct fman_fpm_regs *p_FmFpmRegs;
70252 + struct fman_bmi_regs *p_FmBmiRegs;
70253 + struct fman_qmi_regs *p_FmQmiRegs;
70254 + struct fman_dma_regs *p_FmDmaRegs;
70255 + struct fman_regs *p_FmRegs;
70256 + t_FmExceptionsCallback *f_Exception;
70257 + t_FmBusErrorCallback *f_BusError;
70258 + t_Handle h_App; /* Application handle */
70259 + t_Handle h_Spinlock;
70260 + bool recoveryMode;
70261 + t_FmStateStruct *p_FmStateStruct;
70262 + uint16_t tnumAgingPeriod;
70263 +#if (DPAA_VERSION >= 11)
70264 + t_FmSp *p_FmSp;
70265 + uint8_t partNumOfVSPs;
70266 + uint8_t partVSPBase;
70267 + uintptr_t vspBaseAddr;
70268 +#endif /* (DPAA_VERSION >= 11) */
70269 + bool portsPreFetchConfigured[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
70270 + bool portsPreFetchValue[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
70271 +
70272 +/* un-needed for recovery */
70273 + struct fman_cfg *p_FmDriverParam;
70274 + t_Handle h_FmMuram;
70275 + uint64_t fmMuramPhysBaseAddr;
70276 + bool independentMode;
70277 + bool hcPortInitialized;
70278 + uintptr_t camBaseAddr; /* save for freeing */
70279 + uintptr_t resAddr;
70280 + uintptr_t fifoBaseAddr; /* save for freeing */
70281 + t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */
70282 + bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS];
70283 + t_FmFirmwareParams firmware;
70284 + bool fwVerify;
70285 + bool resetOnInit;
70286 + t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride;
70287 + uint32_t userSetExceptions;
70288 +} t_Fm;
70289 +
70290 +
70291 +#endif /* __FM_H */
70292 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
70293 new file mode 100644
70294 index 00000000..7ce36a76
70295 --- /dev/null
70296 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
70297 @@ -0,0 +1,465 @@
70298 +/*
70299 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70300 + *
70301 + * Redistribution and use in source and binary forms, with or without
70302 + * modification, are permitted provided that the following conditions are met:
70303 + * * Redistributions of source code must retain the above copyright
70304 + * notice, this list of conditions and the following disclaimer.
70305 + * * Redistributions in binary form must reproduce the above copyright
70306 + * notice, this list of conditions and the following disclaimer in the
70307 + * documentation and/or other materials provided with the distribution.
70308 + * * Neither the name of Freescale Semiconductor nor the
70309 + * names of its contributors may be used to endorse or promote products
70310 + * derived from this software without specific prior written permission.
70311 + *
70312 + *
70313 + * ALTERNATIVELY, this software may be distributed under the terms of the
70314 + * GNU General Public License ("GPL") as published by the Free Software
70315 + * Foundation, either version 2 of that License or (at your option) any
70316 + * later version.
70317 + *
70318 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70319 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70320 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70321 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70322 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70323 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70324 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70325 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70326 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70327 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70328 + */
70329 +
70330 +
70331 +/**************************************************************************//**
70332 + @File fm_ipc.h
70333 +
70334 + @Description FM Inter-Partition prototypes, structures and definitions.
70335 +*//***************************************************************************/
70336 +#ifndef __FM_IPC_H
70337 +#define __FM_IPC_H
70338 +
70339 +#include "error_ext.h"
70340 +#include "std_ext.h"
70341 +
70342 +
70343 +/**************************************************************************//**
70344 + @Group FM_grp Frame Manager API
70345 +
70346 + @Description FM API functions, definitions and enums
70347 +
70348 + @{
70349 +*//***************************************************************************/
70350 +
70351 +/**************************************************************************//**
70352 + @Group FM_IPC_grp FM Inter-Partition messaging Unit
70353 +
70354 + @Description FM Inter-Partition messaging unit API definitions and enums.
70355 +
70356 + @{
70357 +*//***************************************************************************/
70358 +
70359 +#if defined(__MWERKS__) && !defined(__GNUC__)
70360 +#pragma pack(push,1)
70361 +#endif /* defined(__MWERKS__) && ... */
70362 +
70363 +/**************************************************************************//**
70364 + @Description enum for defining MAC types
70365 +*//***************************************************************************/
70366 +
70367 +/**************************************************************************//**
70368 + @Description A structure of parameters for specifying a MAC.
70369 +*//***************************************************************************/
70370 +typedef _Packed struct
70371 +{
70372 + uint8_t id;
70373 + uint32_t enumType;
70374 +} _PackedType t_FmIpcMacParams;
70375 +
70376 +/**************************************************************************//**
70377 + @Description A structure of parameters for specifying a MAC.
70378 +*//***************************************************************************/
70379 +typedef _Packed struct
70380 +{
70381 + t_FmIpcMacParams macParams;
70382 + uint16_t maxFrameLength;
70383 +} _PackedType t_FmIpcMacMaxFrameParams;
70384 +
70385 +/**************************************************************************//**
70386 + @Description FM physical Address
70387 +*//***************************************************************************/
70388 +typedef _Packed struct t_FmIpcPhysAddr
70389 +{
70390 + volatile uint8_t high;
70391 + volatile uint32_t low;
70392 +} _PackedType t_FmIpcPhysAddr;
70393 +
70394 +
70395 +typedef _Packed struct t_FmIpcPortOutInitParams {
70396 + uint8_t numOfTasks; /**< OUT */
70397 + uint8_t numOfExtraTasks; /**< OUT */
70398 + uint8_t numOfOpenDmas; /**< OUT */
70399 + uint8_t numOfExtraOpenDmas; /**< OUT */
70400 + uint32_t sizeOfFifo; /**< OUT */
70401 + uint32_t extraSizeOfFifo; /**< OUT */
70402 + t_FmIpcPhysAddr ipcPhysAddr; /**< OUT */
70403 +} _PackedType t_FmIpcPortOutInitParams;
70404 +
70405 +/**************************************************************************//**
70406 + @Description Structure for IPC communication during FM_PORT_Init.
70407 +*//***************************************************************************/
70408 +typedef _Packed struct t_FmIpcPortInInitParams {
70409 + uint8_t hardwarePortId; /**< IN. port Id */
70410 + uint32_t enumPortType; /**< IN. Port type */
70411 + uint8_t boolIndependentMode;/**< IN. TRUE if FM Port operates in independent mode */
70412 + uint16_t liodnOffset; /**< IN. Port's requested resource */
70413 + uint8_t numOfTasks; /**< IN. Port's requested resource */
70414 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
70415 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
70416 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
70417 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
70418 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
70419 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70420 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
70421 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
70422 + LIODN base for this port, to be
70423 + used together with LIODN offset. */
70424 +} _PackedType t_FmIpcPortInInitParams;
70425 +
70426 +
70427 +/**************************************************************************//**
70428 + @Description Structure for IPC communication between port and FM
70429 + regarding tasks and open DMA resources management.
70430 +*//***************************************************************************/
70431 +typedef _Packed struct t_FmIpcPortRsrcParams {
70432 + uint8_t hardwarePortId; /**< IN. port Id */
70433 + uint32_t val; /**< IN. Port's requested resource */
70434 + uint32_t extra; /**< IN. Port's requested resource */
70435 + uint8_t boolInitialConfig;
70436 +} _PackedType t_FmIpcPortRsrcParams;
70437 +
70438 +
70439 +/**************************************************************************//**
70440 + @Description Structure for IPC communication between port and FM
70441 + regarding tasks and open DMA resources management.
70442 +*//***************************************************************************/
70443 +typedef _Packed struct t_FmIpcPortFifoParams {
70444 + t_FmIpcPortRsrcParams rsrcParams;
70445 + uint32_t enumPortType;
70446 + uint8_t boolIndependentMode;
70447 + uint8_t deqPipelineDepth;
70448 + uint8_t numOfPools;
70449 + uint16_t secondLargestBufSize;
70450 + uint16_t largestBufSize;
70451 + uint8_t boolInitialConfig;
70452 +} _PackedType t_FmIpcPortFifoParams;
70453 +
70454 +/**************************************************************************//**
70455 + @Description Structure for port-FM communication during FM_PORT_Free.
70456 +*//***************************************************************************/
70457 +typedef _Packed struct t_FmIpcPortFreeParams {
70458 + uint8_t hardwarePortId; /**< IN. port Id */
70459 + uint32_t enumPortType; /**< IN. Port type */
70460 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70461 +} _PackedType t_FmIpcPortFreeParams;
70462 +
70463 +/**************************************************************************//**
70464 + @Description Structure for defining DMA status
70465 +*//***************************************************************************/
70466 +typedef _Packed struct t_FmIpcDmaStatus {
70467 + uint8_t boolCmqNotEmpty; /**< Command queue is not empty */
70468 + uint8_t boolBusError; /**< Bus error occurred */
70469 + uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */
70470 + uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
70471 + uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
70472 + uint8_t boolSinglePortEccError; /**< Single port ECC error from FM side */
70473 +} _PackedType t_FmIpcDmaStatus;
70474 +
70475 +typedef _Packed struct t_FmIpcRegisterIntr
70476 +{
70477 + uint8_t guestId; /* IN */
70478 + uint32_t event; /* IN */
70479 +} _PackedType t_FmIpcRegisterIntr;
70480 +
70481 +typedef _Packed struct t_FmIpcIsr
70482 +{
70483 + uint8_t boolErr; /* IN */
70484 + uint32_t pendingReg; /* IN */
70485 +} _PackedType t_FmIpcIsr;
70486 +
70487 +/**************************************************************************//**
70488 + @Description structure for returning FM parameters
70489 +*//***************************************************************************/
70490 +typedef _Packed struct t_FmIpcParams {
70491 + uint16_t fmClkFreq; /**< OUT: FM Clock frequency */
70492 + uint16_t fmMacClkFreq; /**< OUT: FM MAC clock frequence */
70493 + uint8_t majorRev; /**< OUT: FM Major revision */
70494 + uint8_t minorRev; /**< OUT: FM Minor revision */
70495 +} _PackedType t_FmIpcParams;
70496 +
70497 +
70498 +/**************************************************************************//**
70499 + @Description structure for returning Fman Ctrl Code revision information
70500 +*//***************************************************************************/
70501 +typedef _Packed struct t_FmIpcFmanCtrlCodeRevisionInfo {
70502 + uint16_t packageRev; /**< OUT: Package revision */
70503 + uint8_t majorRev; /**< OUT: Major revision */
70504 + uint8_t minorRev; /**< OUT: Minor revision */
70505 +} _PackedType t_FmIpcFmanCtrlCodeRevisionInfo;
70506 +
70507 +/**************************************************************************//**
70508 + @Description Structure for defining Fm number of Fman controlers
70509 +*//***************************************************************************/
70510 +typedef _Packed struct t_FmIpcPortNumOfFmanCtrls {
70511 + uint8_t hardwarePortId; /**< IN. port Id */
70512 + uint8_t numOfFmanCtrls; /**< IN. Port type */
70513 + t_FmFmanCtrl orFmanCtrl; /**< IN. fman controller for order restoration*/
70514 +} t_FmIpcPortNumOfFmanCtrls;
70515 +
70516 +/**************************************************************************//**
70517 + @Description structure for setting Fman contriller events
70518 +*//***************************************************************************/
70519 +typedef _Packed struct t_FmIpcFmanEvents {
70520 + uint8_t eventRegId; /**< IN: Fman controller event register id */
70521 + uint32_t enableEvents; /**< IN/OUT: required enabled events mask */
70522 +} _PackedType t_FmIpcFmanEvents;
70523 +
70524 +typedef _Packed struct t_FmIpcResourceAllocParams {
70525 + uint8_t guestId;
70526 + uint16_t base;
70527 + uint16_t num;
70528 +}_PackedType t_FmIpcResourceAllocParams;
70529 +
70530 +typedef _Packed struct t_FmIpcVspSetPortWindow {
70531 + uint8_t hardwarePortId;
70532 + uint8_t baseStorageProfile;
70533 + uint8_t log2NumOfProfiles;
70534 +}_PackedType t_FmIpcVspSetPortWindow;
70535 +
70536 +typedef _Packed struct t_FmIpcSetCongestionGroupPfcPriority {
70537 + uint32_t congestionGroupId;
70538 + uint8_t priorityBitMap;
70539 +}_PackedType t_FmIpcSetCongestionGroupPfcPriority;
70540 +
70541 +#define FM_IPC_MAX_REPLY_BODY_SIZE 20
70542 +#define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
70543 +#define FM_IPC_MAX_MSG_SIZE 30
70544 +
70545 +typedef _Packed struct t_FmIpcMsg
70546 +{
70547 + uint32_t msgId;
70548 + uint8_t msgBody[FM_IPC_MAX_MSG_SIZE];
70549 +} _PackedType t_FmIpcMsg;
70550 +
70551 +typedef _Packed struct t_FmIpcReply
70552 +{
70553 + uint32_t error;
70554 + uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE];
70555 +} _PackedType t_FmIpcReply;
70556 +
70557 +#if defined(__MWERKS__) && !defined(__GNUC__)
70558 +#pragma pack(pop)
70559 +#endif /* defined(__MWERKS__) && ... */
70560 +
70561 +
70562 +/***************************************************************************/
70563 +/************************ FRONT-END-TO-BACK-END*****************************/
70564 +/***************************************************************************/
70565 +
70566 +/**************************************************************************//**
70567 + @Function FM_GET_TIMESTAMP_SCALE
70568 +
70569 + @Description Used by FM front-end.
70570 +
70571 + @Param[out] uint32_t Pointer
70572 +*//***************************************************************************/
70573 +#define FM_GET_TIMESTAMP_SCALE 1
70574 +
70575 +/**************************************************************************//**
70576 + @Function FM_GET_COUNTER
70577 +
70578 + @Description Used by FM front-end.
70579 +
70580 + @Param[in/out] t_FmIpcGetCounter Pointer
70581 +*//***************************************************************************/
70582 +#define FM_GET_COUNTER 2
70583 +
70584 +/**************************************************************************//**
70585 + @Function FM_GET_SET_PORT_PARAMS
70586 +
70587 + @Description Used by FM front-end for the PORT module in order to set and get
70588 + parameters in/from master FM module on FM PORT initialization time.
70589 +
70590 + @Param[in/out] t_FmIcPortInitParams Pointer
70591 +*//***************************************************************************/
70592 +#define FM_GET_SET_PORT_PARAMS 4
70593 +
70594 +/**************************************************************************//**
70595 + @Function FM_FREE_PORT
70596 +
70597 + @Description Used by FM front-end for the PORT module when a port is freed
70598 + to free all FM PORT resources.
70599 +
70600 + @Param[in] uint8_t Pointer
70601 +*//***************************************************************************/
70602 +#define FM_FREE_PORT 5
70603 +
70604 +/**************************************************************************//**
70605 + @Function FM_RESET_MAC
70606 +
70607 + @Description Used by front-end for the MAC module to reset the MAC registers
70608 +
70609 + @Param[in] t_FmIpcMacParams Pointer .
70610 +*//***************************************************************************/
70611 +#define FM_RESET_MAC 6
70612 +
70613 +/**************************************************************************//**
70614 + @Function FM_RESUME_STALLED_PORT
70615 +
70616 + @Description Used by FM front-end for the PORT module in order to
70617 + release a stalled FM Port.
70618 +
70619 + @Param[in] uint8_t Pointer
70620 +*//***************************************************************************/
70621 +#define FM_RESUME_STALLED_PORT 7
70622 +
70623 +/**************************************************************************//**
70624 + @Function FM_IS_PORT_STALLED
70625 +
70626 + @Description Used by FM front-end for the PORT module in order to check whether
70627 + an FM port is stalled.
70628 +
70629 + @Param[in/out] t_FmIcPortIsStalled Pointer
70630 +*//***************************************************************************/
70631 +#define FM_IS_PORT_STALLED 8
70632 +
70633 +/**************************************************************************//**
70634 + @Function FM_GET_PARAMS
70635 +
70636 + @Description Used by FM front-end for the PORT module in order to dump
70637 + return FM parameters.
70638 +
70639 + @Param[in] uint8_t Pointer
70640 +*//***************************************************************************/
70641 +#define FM_GET_PARAMS 10
70642 +
70643 +/**************************************************************************//**
70644 + @Function FM_REGISTER_INTR
70645 +
70646 + @Description Used by FM front-end to register an interrupt handler to
70647 + be called upon interrupt for guest.
70648 +
70649 + @Param[out] t_FmIpcRegisterIntr Pointer
70650 +*//***************************************************************************/
70651 +#define FM_REGISTER_INTR 11
70652 +
70653 +/**************************************************************************//**
70654 + @Function FM_DMA_STAT
70655 +
70656 + @Description Used by FM front-end to read the FM DMA status.
70657 +
70658 + @Param[out] t_FmIpcDmaStatus Pointer
70659 +*//***************************************************************************/
70660 +#define FM_DMA_STAT 13
70661 +
70662 +/**************************************************************************//**
70663 + @Function FM_ALLOC_FMAN_CTRL_EVENT_REG
70664 +
70665 + @Description Used by FM front-end to allocate event register.
70666 +
70667 + @Param[out] Event register id Pointer
70668 +*//***************************************************************************/
70669 +#define FM_ALLOC_FMAN_CTRL_EVENT_REG 14
70670 +
70671 +/**************************************************************************//**
70672 + @Function FM_FREE_FMAN_CTRL_EVENT_REG
70673 +
70674 + @Description Used by FM front-end to free locate event register.
70675 +
70676 + @Param[in] uint8_t Pointer - Event register id
70677 +*//***************************************************************************/
70678 +#define FM_FREE_FMAN_CTRL_EVENT_REG 15
70679 +
70680 +/**************************************************************************//**
70681 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70682 +
70683 + @Description Used by FM front-end to enable events in the FPM
70684 + Fman controller event register.
70685 +
70686 + @Param[in] t_FmIpcFmanEvents Pointer
70687 +*//***************************************************************************/
70688 +#define FM_SET_FMAN_CTRL_EVENTS_ENABLE 16
70689 +
70690 +/**************************************************************************//**
70691 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70692 +
70693 + @Description Used by FM front-end to enable events in the FPM
70694 + Fman controller event register.
70695 +
70696 + @Param[in/out] t_FmIpcFmanEvents Pointer
70697 +*//***************************************************************************/
70698 +#define FM_GET_FMAN_CTRL_EVENTS_ENABLE 17
70699 +
70700 +/**************************************************************************//**
70701 + @Function FM_SET_MAC_MAX_FRAME
70702 +
70703 + @Description Used by FM front-end to set MAC's MTU/RTU's in
70704 + back-end.
70705 +
70706 + @Param[in/out] t_FmIpcMacMaxFrameParams Pointer
70707 +*//***************************************************************************/
70708 +#define FM_SET_MAC_MAX_FRAME 18
70709 +
70710 +/**************************************************************************//**
70711 + @Function FM_GET_PHYS_MURAM_BASE
70712 +
70713 + @Description Used by FM front-end in order to get MURAM base address
70714 +
70715 + @Param[in/out] t_FmIpcPhysAddr Pointer
70716 +*//***************************************************************************/
70717 +#define FM_GET_PHYS_MURAM_BASE 19
70718 +
70719 +/**************************************************************************//**
70720 + @Function FM_MASTER_IS_ALIVE
70721 +
70722 + @Description Used by FM front-end in order to verify Master is up
70723 +
70724 + @Param[in/out] bool
70725 +*//***************************************************************************/
70726 +#define FM_MASTER_IS_ALIVE 20
70727 +
70728 +#define FM_ENABLE_RAM_ECC 21
70729 +#define FM_DISABLE_RAM_ECC 22
70730 +#define FM_SET_NUM_OF_FMAN_CTRL 23
70731 +#define FM_SET_SIZE_OF_FIFO 24
70732 +#define FM_SET_NUM_OF_TASKS 25
70733 +#define FM_SET_NUM_OF_OPEN_DMAS 26
70734 +#define FM_VSP_ALLOC 27
70735 +#define FM_VSP_FREE 28
70736 +#define FM_VSP_SET_PORT_WINDOW 29
70737 +#define FM_GET_FMAN_CTRL_CODE_REV 30
70738 +#define FM_SET_CONG_GRP_PFC_PRIO 31
70739 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
70740 +#define FM_10G_TX_ECC_WA 100
70741 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
70742 +
70743 +/***************************************************************************/
70744 +/************************ BACK-END-TO-FRONT-END*****************************/
70745 +/***************************************************************************/
70746 +
70747 +/**************************************************************************//**
70748 + @Function FM_GUEST_ISR
70749 +
70750 + @Description Used by FM back-end to report an interrupt to the front-end.
70751 +
70752 + @Param[out] t_FmIpcIsr Pointer
70753 +*//***************************************************************************/
70754 +#define FM_GUEST_ISR 1
70755 +
70756 +
70757 +
70758 +/** @} */ /* end of FM_IPC_grp group */
70759 +/** @} */ /* end of FM_grp group */
70760 +
70761 +
70762 +#endif /* __FM_IPC_H */
70763 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
70764 new file mode 100644
70765 index 00000000..0bc67cb7
70766 --- /dev/null
70767 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
70768 @@ -0,0 +1,174 @@
70769 +/*
70770 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70771 + *
70772 + * Redistribution and use in source and binary forms, with or without
70773 + * modification, are permitted provided that the following conditions are met:
70774 + * * Redistributions of source code must retain the above copyright
70775 + * notice, this list of conditions and the following disclaimer.
70776 + * * Redistributions in binary form must reproduce the above copyright
70777 + * notice, this list of conditions and the following disclaimer in the
70778 + * documentation and/or other materials provided with the distribution.
70779 + * * Neither the name of Freescale Semiconductor nor the
70780 + * names of its contributors may be used to endorse or promote products
70781 + * derived from this software without specific prior written permission.
70782 + *
70783 + *
70784 + * ALTERNATIVELY, this software may be distributed under the terms of the
70785 + * GNU General Public License ("GPL") as published by the Free Software
70786 + * Foundation, either version 2 of that License or (at your option) any
70787 + * later version.
70788 + *
70789 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70790 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70791 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70792 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70793 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70794 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70795 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70796 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70797 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70798 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70799 + */
70800 +
70801 +
70802 +/******************************************************************************
70803 + @File FM_muram.c
70804 +
70805 + @Description FM MURAM ...
70806 +*//***************************************************************************/
70807 +#include "error_ext.h"
70808 +#include "std_ext.h"
70809 +#include "mm_ext.h"
70810 +#include "string_ext.h"
70811 +#include "sprint_ext.h"
70812 +#include "fm_muram_ext.h"
70813 +#include "fm_common.h"
70814 +
70815 +#define __ERR_MODULE__ MODULE_FM_MURAM
70816 +
70817 +
70818 +typedef struct
70819 +{
70820 + t_Handle h_Mem;
70821 + uintptr_t baseAddr;
70822 + uint32_t size;
70823 +} t_FmMuram;
70824 +
70825 +
70826 +void FmMuramClear(t_Handle h_FmMuram)
70827 +{
70828 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70829 +
70830 + SANITY_CHECK_RETURN(h_FmMuram, E_INVALID_HANDLE);
70831 + IOMemSet32(UINT_TO_PTR(p_FmMuram->baseAddr), 0, p_FmMuram->size);
70832 +}
70833 +
70834 +
70835 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size)
70836 +{
70837 + t_Handle h_Mem;
70838 + t_FmMuram *p_FmMuram;
70839 +
70840 + if (!baseAddress)
70841 + {
70842 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress 0 is not supported"));
70843 + return NULL;
70844 + }
70845 +
70846 + if (baseAddress%4)
70847 + {
70848 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress not 4 bytes aligned!"));
70849 + return NULL;
70850 + }
70851 +
70852 + /* Allocate FM MURAM structure */
70853 + p_FmMuram = (t_FmMuram *) XX_Malloc(sizeof(t_FmMuram));
70854 + if (!p_FmMuram)
70855 + {
70856 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MURAM driver structure"));
70857 + return NULL;
70858 + }
70859 + memset(p_FmMuram, 0, sizeof(t_FmMuram));
70860 +
70861 +
70862 + if ((MM_Init(&h_Mem, baseAddress, size) != E_OK) || (!h_Mem))
70863 + {
70864 + XX_Free(p_FmMuram);
70865 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM partition!!!"));
70866 + return NULL;
70867 + }
70868 +
70869 + /* Initialize FM MURAM parameters which will be kept by the driver */
70870 + p_FmMuram->baseAddr = baseAddress;
70871 + p_FmMuram->size = size;
70872 + p_FmMuram->h_Mem = h_Mem;
70873 +
70874 + return p_FmMuram;
70875 +}
70876 +
70877 +t_Error FM_MURAM_Free(t_Handle h_FmMuram)
70878 +{
70879 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70880 +
70881 + if (p_FmMuram->h_Mem)
70882 + MM_Free(p_FmMuram->h_Mem);
70883 +
70884 + XX_Free(h_FmMuram);
70885 +
70886 + return E_OK;
70887 +}
70888 +
70889 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align)
70890 +{
70891 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70892 + uintptr_t addr;
70893 +
70894 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70895 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70896 +
70897 + addr = (uintptr_t)MM_Get(p_FmMuram->h_Mem, size, align ,"FM MURAM");
70898 +
70899 + if (addr == ILLEGAL_BASE)
70900 + return NULL;
70901 +
70902 + return UINT_TO_PTR(addr);
70903 +}
70904 +
70905 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size)
70906 +{
70907 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70908 + uintptr_t addr;
70909 +
70910 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70911 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70912 +
70913 + addr = (uintptr_t)MM_GetForce(p_FmMuram->h_Mem, base, size, "FM MURAM");
70914 +
70915 + if (addr == ILLEGAL_BASE)
70916 + return NULL;
70917 +
70918 + return UINT_TO_PTR(addr);
70919 +}
70920 +
70921 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr)
70922 +{
70923 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70924 +
70925 + SANITY_CHECK_RETURN_ERROR(h_FmMuram, E_INVALID_HANDLE);
70926 + SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE);
70927 +
70928 + if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0)
70929 + RETURN_ERROR(MINOR, E_INVALID_ADDRESS, ("memory pointer!!!"));
70930 +
70931 + return E_OK;
70932 +}
70933 +
70934 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram)
70935 +{
70936 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70937 +
70938 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, 0);
70939 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, 0);
70940 +
70941 + return MM_GetFreeMemSize(p_FmMuram->h_Mem);
70942 +}
70943 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
70944 new file mode 100755
70945 index 00000000..a41ecd04
70946 --- /dev/null
70947 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
70948 @@ -0,0 +1,1398 @@
70949 +/*
70950 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70951 + *
70952 + * Redistribution and use in source and binary forms, with or without
70953 + * modification, are permitted provided that the following conditions are met:
70954 + * * Redistributions of source code must retain the above copyright
70955 + * notice, this list of conditions and the following disclaimer.
70956 + * * Redistributions in binary form must reproduce the above copyright
70957 + * notice, this list of conditions and the following disclaimer in the
70958 + * documentation and/or other materials provided with the distribution.
70959 + * * Neither the name of Freescale Semiconductor nor the
70960 + * names of its contributors may be used to endorse or promote products
70961 + * derived from this software without specific prior written permission.
70962 + *
70963 + *
70964 + * ALTERNATIVELY, this software may be distributed under the terms of the
70965 + * GNU General Public License ("GPL") as published by the Free Software
70966 + * Foundation, either version 2 of that License or (at your option) any
70967 + * later version.
70968 + *
70969 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70970 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70971 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70972 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70973 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70974 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70975 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70976 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70977 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70978 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70979 + */
70980 +
70981 +
70982 +#include <linux/math64.h>
70983 +#include "fsl_fman.h"
70984 +#include "dpaa_integration_ext.h"
70985 +
70986 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg)
70987 +{
70988 + uint32_t event, mask, force;
70989 +
70990 + event = ioread32be(&bmi_rg->fmbm_ievr);
70991 + mask = ioread32be(&bmi_rg->fmbm_ier);
70992 + event &= mask;
70993 + /* clear the forced events */
70994 + force = ioread32be(&bmi_rg->fmbm_ifr);
70995 + if (force & event)
70996 + iowrite32be(force & ~event, &bmi_rg->fmbm_ifr);
70997 + /* clear the acknowledged events */
70998 + iowrite32be(event, &bmi_rg->fmbm_ievr);
70999 + return event;
71000 +}
71001 +
71002 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg)
71003 +{
71004 + uint32_t event, mask, force;
71005 +
71006 + event = ioread32be(&qmi_rg->fmqm_eie);
71007 + mask = ioread32be(&qmi_rg->fmqm_eien);
71008 + event &= mask;
71009 +
71010 + /* clear the forced events */
71011 + force = ioread32be(&qmi_rg->fmqm_eif);
71012 + if (force & event)
71013 + iowrite32be(force & ~event, &qmi_rg->fmqm_eif);
71014 + /* clear the acknowledged events */
71015 + iowrite32be(event, &qmi_rg->fmqm_eie);
71016 + return event;
71017 +}
71018 +
71019 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg)
71020 +{
71021 + return ioread32be(&dma_rg->fmdmtcid);
71022 +}
71023 +
71024 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg)
71025 +{
71026 + uint64_t addr;
71027 +
71028 + addr = (uint64_t)ioread32be(&dma_rg->fmdmtal);
71029 + addr |= ((uint64_t)(ioread32be(&dma_rg->fmdmtah)) << 32);
71030 +
71031 + return addr;
71032 +}
71033 +
71034 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg)
71035 +{
71036 + uint32_t status, mask;
71037 +
71038 + status = ioread32be(&dma_rg->fmdmsr);
71039 + mask = ioread32be(&dma_rg->fmdmmr);
71040 +
71041 + /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */
71042 + if ((mask & DMA_MODE_BER) != DMA_MODE_BER)
71043 + status &= ~DMA_STATUS_BUS_ERR;
71044 +
71045 + /* clear relevant bits if mask has no DMA_MODE_ECC */
71046 + if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC)
71047 + status &= ~(DMA_STATUS_FM_SPDAT_ECC |
71048 + DMA_STATUS_READ_ECC |
71049 + DMA_STATUS_SYSTEM_WRITE_ECC |
71050 + DMA_STATUS_FM_WRITE_ECC);
71051 +
71052 + /* clear set events */
71053 + iowrite32be(status, &dma_rg->fmdmsr);
71054 +
71055 + return status;
71056 +}
71057 +
71058 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg)
71059 +{
71060 + uint32_t event;
71061 +
71062 + event = ioread32be(&fpm_rg->fmfp_ee);
71063 + /* clear the all occurred events */
71064 + iowrite32be(event, &fpm_rg->fmfp_ee);
71065 + return event;
71066 +}
71067 +
71068 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg)
71069 +{
71070 + uint32_t event, mask;
71071 +
71072 + event = ioread32be(&fpm_rg->fm_rcr);
71073 + mask = ioread32be(&fpm_rg->fm_rie);
71074 +
71075 + /* clear MURAM event bit (do not clear IRAM event) */
71076 + iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr);
71077 +
71078 + if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
71079 + return event;
71080 + else
71081 + return 0;
71082 +}
71083 +
71084 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg)
71085 +{
71086 + uint32_t event, mask;
71087 +
71088 + event = ioread32be(&fpm_rg->fm_rcr) ;
71089 + mask = ioread32be(&fpm_rg->fm_rie);
71090 + /* clear IRAM event bit (do not clear MURAM event) */
71091 + iowrite32be(event & ~FPM_RAM_MURAM_ECC,
71092 + &fpm_rg->fm_rcr);
71093 +
71094 + if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
71095 + return event;
71096 + else
71097 + return 0;
71098 +}
71099 +
71100 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg)
71101 +{
71102 + uint32_t event, mask, force;
71103 +
71104 + event = ioread32be(&qmi_rg->fmqm_ie);
71105 + mask = ioread32be(&qmi_rg->fmqm_ien);
71106 + event &= mask;
71107 + /* clear the forced events */
71108 + force = ioread32be(&qmi_rg->fmqm_if);
71109 + if (force & event)
71110 + iowrite32be(force & ~event, &qmi_rg->fmqm_if);
71111 + /* clear the acknowledged events */
71112 + iowrite32be(event, &qmi_rg->fmqm_ie);
71113 + return event;
71114 +}
71115 +
71116 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
71117 + uint8_t count1ubit,
71118 + uint16_t fm_clk_freq)
71119 +{
71120 + uint32_t tmp;
71121 + uint64_t frac;
71122 + uint32_t intgr;
71123 + uint32_t ts_freq = (uint32_t)(1 << count1ubit); /* in Mhz */
71124 +
71125 + /* configure timestamp so that bit 8 will count 1 microsecond
71126 + * Find effective count rate at TIMESTAMP least significant bits:
71127 + * Effective_Count_Rate = 1MHz x 2^8 = 256MHz
71128 + * Find frequency ratio between effective count rate and the clock:
71129 + * Effective_Count_Rate / CLK e.g. for 600 MHz clock:
71130 + * 256/600 = 0.4266666... */
71131 +
71132 + intgr = ts_freq / fm_clk_freq;
71133 + /* we multiply by 2^16 to keep the fraction of the division
71134 + * we do not div back, since we write this value as a fraction
71135 + * see spec */
71136 +
71137 + frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * fm_clk_freq;
71138 + /* we check remainder of the division in order to round up if not int */
71139 + if (do_div(frac, fm_clk_freq))
71140 + frac++;
71141 +
71142 + tmp = (intgr << FPM_TS_INT_SHIFT) | (uint16_t)frac;
71143 + iowrite32be(tmp, &fpm_rg->fmfp_tsc2);
71144 +
71145 + /* enable timestamp with original clock */
71146 + iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1);
71147 +}
71148 +
71149 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg)
71150 +{
71151 + return ioread32be(&fpm_rg->fm_epi);
71152 +}
71153 +
71154 +
71155 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg)
71156 +{
71157 + int timeout = 100;
71158 +
71159 + iowrite32be(0x40000000, &fpm_rg->fmfp_extc);
71160 +
71161 + while ((ioread32be(&fpm_rg->fmfp_extc) & 0x40000000) && --timeout)
71162 + udelay(10);
71163 +
71164 + if (!timeout)
71165 + return -EBUSY;
71166 + return 0;
71167 +}
71168 +
71169 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg,
71170 + uint8_t event_reg_id,
71171 + uint32_t enable_events)
71172 +{
71173 + iowrite32be(enable_events, &fpm_rg->fmfp_cee[event_reg_id]);
71174 +}
71175 +
71176 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id)
71177 +{
71178 + return ioread32be(&fpm_rg->fmfp_cee[event_reg_id]);
71179 +}
71180 +
71181 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
71182 + uint8_t port_id,
71183 + uint8_t num_fman_ctrls,
71184 + uint32_t or_fman_ctrl)
71185 +{
71186 + uint32_t tmp = 0;
71187 +
71188 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
71189 + /*TODO - maybe to put CTL# according to another criteria*/
71190 + if (num_fman_ctrls == 2)
71191 + tmp = FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1;
71192 + /* order restoration */
71193 + tmp |= (or_fman_ctrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | or_fman_ctrl;
71194 +
71195 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71196 +}
71197 +
71198 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
71199 + uint8_t port_id,
71200 + bool independent_mode,
71201 + bool is_rx_port)
71202 +{
71203 + uint32_t tmp = 0;
71204 +
71205 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
71206 + if (independent_mode) {
71207 + if (is_rx_port)
71208 + tmp |= (FPM_PRT_FM_CTL1 <<
71209 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL1;
71210 + else
71211 + tmp |= (FPM_PRT_FM_CTL2 <<
71212 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL2;
71213 + } else {
71214 + tmp |= (FPM_PRT_FM_CTL2|FPM_PRT_FM_CTL1);
71215 +
71216 + /* order restoration */
71217 + if (port_id % 2)
71218 + tmp |= (FPM_PRT_FM_CTL1 <<
71219 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
71220 + else
71221 + tmp |= (FPM_PRT_FM_CTL2 <<
71222 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
71223 + }
71224 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71225 +}
71226 +
71227 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg)
71228 +{
71229 + return (uint8_t)ioread32be(&qmi_rg->fmqm_gc);
71230 +}
71231 +
71232 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg)
71233 +{
71234 + return (uint8_t)(ioread32be(&qmi_rg->fmqm_gc) >> 8);
71235 +}
71236 +
71237 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
71238 +{
71239 + uint32_t tmp_reg;
71240 +
71241 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
71242 + tmp_reg &= ~QMI_CFG_ENQ_MASK;
71243 + tmp_reg |= ((uint32_t)val << 8);
71244 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
71245 +}
71246 +
71247 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
71248 +{
71249 + uint32_t tmp_reg;
71250 +
71251 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
71252 + tmp_reg &= ~QMI_CFG_DEQ_MASK;
71253 + tmp_reg |= (uint32_t)val;
71254 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
71255 +}
71256 +
71257 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg)
71258 +{
71259 + iowrite32be(0, &fpm_rg->fmfp_mxd);
71260 +}
71261 +
71262 +void fman_set_liodn_per_port(struct fman_rg *fman_rg, uint8_t port_id,
71263 + uint16_t liodn_base,
71264 + uint16_t liodn_ofst)
71265 +{
71266 + uint32_t tmp;
71267 +
71268 + if ((port_id > 63) || (port_id < 1))
71269 + return;
71270 +
71271 + /* set LIODN base for this port */
71272 + tmp = ioread32be(&fman_rg->dma_rg->fmdmplr[port_id / 2]);
71273 + if (port_id % 2) {
71274 + tmp &= ~FM_LIODN_BASE_MASK;
71275 + tmp |= (uint32_t)liodn_base;
71276 + } else {
71277 + tmp &= ~(FM_LIODN_BASE_MASK << DMA_LIODN_SHIFT);
71278 + tmp |= (uint32_t)liodn_base << DMA_LIODN_SHIFT;
71279 + }
71280 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmplr[port_id / 2]);
71281 + iowrite32be((uint32_t)liodn_ofst,
71282 + &fman_rg->bmi_rg->fmbm_spliodn[port_id - 1]);
71283 +}
71284 +
71285 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
71286 +{
71287 + return (bool)!!(ioread32be(&fpm_rg->fmfp_ps[port_id]) & FPM_PS_STALLED);
71288 +}
71289 +
71290 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
71291 +{
71292 + uint32_t tmp;
71293 +
71294 + tmp = (uint32_t)((port_id << FPM_PORT_FM_CTL_PORTID_SHIFT) |
71295 + FPM_PRC_REALSE_STALLED);
71296 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71297 +}
71298 +
71299 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t mac_id, bool is_10g)
71300 +{
71301 + uint32_t msk, timeout = 100;
71302 +
71303 + /* Get the relevant bit mask */
71304 + if (is_10g) {
71305 + switch (mac_id) {
71306 + case(0):
71307 + msk = FPM_RSTC_10G0_RESET;
71308 + break;
71309 + case(1):
71310 + msk = FPM_RSTC_10G1_RESET;
71311 + break;
71312 + default:
71313 + return -EINVAL;
71314 + }
71315 + } else {
71316 + switch (mac_id) {
71317 + case(0):
71318 + msk = FPM_RSTC_1G0_RESET;
71319 + break;
71320 + case(1):
71321 + msk = FPM_RSTC_1G1_RESET;
71322 + break;
71323 + case(2):
71324 + msk = FPM_RSTC_1G2_RESET;
71325 + break;
71326 + case(3):
71327 + msk = FPM_RSTC_1G3_RESET;
71328 + break;
71329 + case(4):
71330 + msk = FPM_RSTC_1G4_RESET;
71331 + break;
71332 + case (5):
71333 + msk = FPM_RSTC_1G5_RESET;
71334 + break;
71335 + case (6):
71336 + msk = FPM_RSTC_1G6_RESET;
71337 + break;
71338 + case (7):
71339 + msk = FPM_RSTC_1G7_RESET;
71340 + break;
71341 + default:
71342 + return -EINVAL;
71343 + }
71344 + }
71345 + /* reset */
71346 + iowrite32be(msk, &fpm_rg->fm_rstc);
71347 + while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout)
71348 + udelay(10);
71349 +
71350 + if (!timeout)
71351 + return -EBUSY;
71352 + return 0;
71353 +}
71354 +
71355 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71356 +{
71357 + uint32_t tmp_reg;
71358 +
71359 + if ((port_id > 63) || (port_id < 1))
71360 + return 0;
71361 +
71362 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id - 1]);
71363 + return (uint16_t)((tmp_reg & BMI_FIFO_SIZE_MASK) + 1);
71364 +}
71365 +
71366 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg)
71367 +{
71368 + uint32_t reg, res;
71369 +
71370 + reg = ioread32be(&bmi_rg->fmbm_cfg1);
71371 + res = (reg >> BMI_CFG1_FIFO_SIZE_SHIFT) & 0x3ff;
71372 + return res * FMAN_BMI_FIFO_UNITS;
71373 +}
71374 +
71375 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
71376 + uint8_t port_id)
71377 +{
71378 + uint32_t tmp_reg;
71379 +
71380 + if ((port_id > 63) || (port_id < 1))
71381 + return 0;
71382 +
71383 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id-1]);
71384 + return (uint16_t)((tmp_reg & BMI_EXTRA_FIFO_SIZE_MASK) >>
71385 + BMI_EXTRA_FIFO_SIZE_SHIFT);
71386 +}
71387 +
71388 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
71389 + uint8_t port_id,
71390 + uint32_t sz_fifo,
71391 + uint32_t extra_sz_fifo)
71392 +{
71393 + uint32_t tmp;
71394 +
71395 + if ((port_id > 63) || (port_id < 1))
71396 + return;
71397 +
71398 + /* calculate reg */
71399 + tmp = (uint32_t)((sz_fifo / FMAN_BMI_FIFO_UNITS - 1) |
71400 + ((extra_sz_fifo / FMAN_BMI_FIFO_UNITS) <<
71401 + BMI_EXTRA_FIFO_SIZE_SHIFT));
71402 + iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]);
71403 +}
71404 +
71405 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71406 +{
71407 + uint32_t tmp;
71408 +
71409 + if ((port_id > 63) || (port_id < 1))
71410 + return 0;
71411 +
71412 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71413 + return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >>
71414 + BMI_NUM_OF_TASKS_SHIFT) + 1);
71415 +}
71416 +
71417 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71418 +{
71419 + uint32_t tmp;
71420 +
71421 + if ((port_id > 63) || (port_id < 1))
71422 + return 0;
71423 +
71424 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71425 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >>
71426 + BMI_EXTRA_NUM_OF_TASKS_SHIFT);
71427 +}
71428 +
71429 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
71430 + uint8_t port_id,
71431 + uint8_t num_tasks,
71432 + uint8_t num_extra_tasks)
71433 +{
71434 + uint32_t tmp;
71435 +
71436 + if ((port_id > 63) || (port_id < 1))
71437 + return;
71438 +
71439 + /* calculate reg */
71440 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71441 + ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
71442 + tmp |= (uint32_t)(((num_tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) |
71443 + (num_extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
71444 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71445 +}
71446 +
71447 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71448 +{
71449 + uint32_t tmp;
71450 +
71451 + if ((port_id > 63) || (port_id < 1))
71452 + return 0;
71453 +
71454 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71455 + return (uint8_t)(((tmp & BMI_NUM_OF_DMAS_MASK) >>
71456 + BMI_NUM_OF_DMAS_SHIFT) + 1);
71457 +}
71458 +
71459 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71460 +{
71461 + uint32_t tmp;
71462 +
71463 + if ((port_id > 63) || (port_id < 1))
71464 + return 0;
71465 +
71466 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71467 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >>
71468 + BMI_EXTRA_NUM_OF_DMAS_SHIFT);
71469 +}
71470 +
71471 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
71472 + uint8_t port_id,
71473 + uint8_t num_open_dmas,
71474 + uint8_t num_extra_open_dmas,
71475 + uint8_t total_num_dmas)
71476 +{
71477 + uint32_t tmp = 0;
71478 +
71479 + if ((port_id > 63) || (port_id < 1))
71480 + return;
71481 +
71482 + /* calculate reg */
71483 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71484 + ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
71485 + tmp |= (uint32_t)(((num_open_dmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
71486 + (num_extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
71487 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71488 +
71489 + /* update total num of DMA's with committed number of open DMAS,
71490 + * and max uncommitted pool. */
71491 + if (total_num_dmas)
71492 + {
71493 + tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
71494 + tmp |= (uint32_t)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT;
71495 + iowrite32be(tmp, &bmi_rg->fmbm_cfg2);
71496 + }
71497 +}
71498 +
71499 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
71500 + uint8_t port_id,
71501 + uint8_t base_storage_profile,
71502 + uint8_t log2_num_of_profiles)
71503 +{
71504 + uint32_t tmp = 0;
71505 + if ((port_id > 63) || (port_id < 1))
71506 + return;
71507 +
71508 + tmp = ioread32be(&bmi_rg->fmbm_spliodn[port_id-1]);
71509 + tmp |= (uint32_t)((uint32_t)base_storage_profile & 0x3f) << 16;
71510 + tmp |= (uint32_t)log2_num_of_profiles << 28;
71511 + iowrite32be(tmp, &bmi_rg->fmbm_spliodn[port_id-1]);
71512 +}
71513 +
71514 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
71515 + uint32_t congestion_group_id,
71516 + uint8_t priority_bit_map,
71517 + uint32_t reg_num)
71518 +{
71519 + uint32_t offset, tmp = 0;
71520 +
71521 + offset = (congestion_group_id%4)*8;
71522 +
71523 + tmp = ioread32be(&cpg_rg[reg_num]);
71524 + tmp &= ~(0xFF<<offset);
71525 + tmp |= (uint32_t)priority_bit_map << offset;
71526 +
71527 + iowrite32be(tmp,&cpg_rg[reg_num]);
71528 +}
71529 +
71530 +/*****************************************************************************/
71531 +/* API Init unit functions */
71532 +/*****************************************************************************/
71533 +void fman_defconfig(struct fman_cfg *cfg, bool is_master)
71534 +{
71535 + memset(cfg, 0, sizeof(struct fman_cfg));
71536 +
71537 + cfg->catastrophic_err = DEFAULT_CATASTROPHIC_ERR;
71538 + cfg->dma_err = DEFAULT_DMA_ERR;
71539 + cfg->halt_on_external_activ = DEFAULT_HALT_ON_EXTERNAL_ACTIVATION;
71540 + cfg->halt_on_unrecov_ecc_err = DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR;
71541 + cfg->en_iram_test_mode = FALSE;
71542 + cfg->en_muram_test_mode = FALSE;
71543 + cfg->external_ecc_rams_enable = DEFAULT_EXTERNAL_ECC_RAMS_ENABLE;
71544 +
71545 + if (!is_master)
71546 + return;
71547 +
71548 + cfg->dma_aid_override = DEFAULT_AID_OVERRIDE;
71549 + cfg->dma_aid_mode = DEFAULT_AID_MODE;
71550 + cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW;
71551 + cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH;
71552 + cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE;
71553 + cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES;
71554 + cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE;
71555 + cfg->dma_en_emergency = DEFAULT_DMA_EN_EMERGENCY;
71556 + cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY;
71557 + cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG;
71558 + cfg->dma_en_emergency_smoother = DEFAULT_DMA_EN_EMERGENCY_SMOOTHER;
71559 + cfg->dma_emergency_switch_counter = DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER;
71560 + cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT;
71561 + cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH;
71562 + cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH;
71563 + cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH;
71564 + cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH;
71565 + cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH;
71566 + cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH;
71567 + cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH;
71568 + cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH;
71569 +
71570 + cfg->pedantic_dma = FALSE;
71571 + cfg->tnum_aging_period = DEFAULT_TNUM_AGING_PERIOD;
71572 + cfg->dma_stop_on_bus_error = FALSE;
71573 + cfg->qmi_deq_option_support = FALSE;
71574 +}
71575 +
71576 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71577 +{
71578 + uint32_t tmp_reg;
71579 +
71580 + /* read the values from the registers as they are initialized by the HW with
71581 + * the required values.
71582 + */
71583 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg1);
71584 + cfg->total_fifo_size =
71585 + (((tmp_reg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * FMAN_BMI_FIFO_UNITS;
71586 +
71587 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg2);
71588 + cfg->total_num_of_tasks =
71589 + (uint8_t)(((tmp_reg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1);
71590 +
71591 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmtr);
71592 + cfg->dma_comm_qtsh_asrt_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71593 +
71594 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmhy);
71595 + cfg->dma_comm_qtsh_clr_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71596 +
71597 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmmr);
71598 + cfg->dma_cache_override = (enum fman_dma_cache_override)((tmp_reg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT);
71599 + cfg->dma_cam_num_of_entries = (uint8_t)((((tmp_reg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS);
71600 + cfg->dma_aid_override = (bool)((tmp_reg & DMA_MODE_AID_OR)? TRUE:FALSE);
71601 + cfg->dma_dbg_cnt_mode = (enum fman_dma_dbg_cnt_mode)((tmp_reg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT);
71602 + cfg->dma_en_emergency = (bool)((tmp_reg & DMA_MODE_EB)? TRUE : FALSE);
71603 +
71604 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_mxd);
71605 + cfg->disp_limit_tsh = (uint8_t)((tmp_reg & FPM_DISP_LIMIT_MASK) >> FPM_DISP_LIMIT_SHIFT);
71606 +
71607 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist1);
71608 + cfg->prs_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PRS_MASK ) >> FPM_THR1_PRS_SHIFT);
71609 + cfg->plcr_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_KG_MASK ) >> FPM_THR1_KG_SHIFT);
71610 + cfg->kg_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PLCR_MASK ) >> FPM_THR1_PLCR_SHIFT);
71611 + cfg->bmi_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_BMI_MASK ) >> FPM_THR1_BMI_SHIFT);
71612 +
71613 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist2);
71614 + cfg->qmi_enq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_ENQ_MASK ) >> FPM_THR2_QMI_ENQ_SHIFT);
71615 + cfg->qmi_deq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_DEQ_MASK ) >> FPM_THR2_QMI_DEQ_SHIFT);
71616 + cfg->fm_ctl1_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL1_MASK ) >> FPM_THR2_FM_CTL1_SHIFT);
71617 + cfg->fm_ctl2_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL2_MASK ) >> FPM_THR2_FM_CTL2_SHIFT);
71618 +
71619 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmsetr);
71620 + cfg->dma_sos_emergency = tmp_reg;
71621 +
71622 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmwcr);
71623 + cfg->dma_watchdog = tmp_reg/cfg->clk_freq;
71624 +
71625 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmemsr);
71626 + cfg->dma_en_emergency_smoother = (bool)((tmp_reg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE);
71627 + cfg->dma_emergency_switch_counter = (tmp_reg & DMA_EMSR_EMSTR_MASK);
71628 +}
71629 +
71630 +void fman_reset(struct fman_fpm_regs *fpm_rg)
71631 +{
71632 + iowrite32be(FPM_RSTC_FM_RESET, &fpm_rg->fm_rstc);
71633 +}
71634 +
71635 +/**************************************************************************//**
71636 + @Function FM_Init
71637 +
71638 + @Description Initializes the FM module
71639 +
71640 + @Param[in] h_Fm - FM module descriptor
71641 +
71642 + @Return E_OK on success; Error code otherwise.
71643 +*//***************************************************************************/
71644 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg)
71645 +{
71646 + uint32_t tmp_reg;
71647 +
71648 + /**********************/
71649 + /* Init DMA Registers */
71650 + /**********************/
71651 + /* clear status reg events */
71652 + /* oren - check!!! */
71653 + tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC |
71654 + DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
71655 + iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg,
71656 + &dma_rg->fmdmsr);
71657 +
71658 + /* configure mode register */
71659 + tmp_reg = 0;
71660 + tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT;
71661 + if (cfg->dma_aid_override)
71662 + tmp_reg |= DMA_MODE_AID_OR;
71663 + if (cfg->exceptions & FMAN_EX_DMA_BUS_ERROR)
71664 + tmp_reg |= DMA_MODE_BER;
71665 + if ((cfg->exceptions & FMAN_EX_DMA_SYSTEM_WRITE_ECC) |
71666 + (cfg->exceptions & FMAN_EX_DMA_READ_ECC) |
71667 + (cfg->exceptions & FMAN_EX_DMA_FM_WRITE_ECC))
71668 + tmp_reg |= DMA_MODE_ECC;
71669 + if (cfg->dma_stop_on_bus_error)
71670 + tmp_reg |= DMA_MODE_SBER;
71671 + if(cfg->dma_axi_dbg_num_of_beats)
71672 + tmp_reg |= (uint32_t)(DMA_MODE_AXI_DBG_MASK &
71673 + ((cfg->dma_axi_dbg_num_of_beats - 1) << DMA_MODE_AXI_DBG_SHIFT));
71674 +
71675 + if (cfg->dma_en_emergency) {
71676 + tmp_reg |= cfg->dma_emergency_bus_select;
71677 + tmp_reg |= cfg->dma_emergency_level << DMA_MODE_EMER_LVL_SHIFT;
71678 + if (cfg->dma_en_emergency_smoother)
71679 + iowrite32be(cfg->dma_emergency_switch_counter,
71680 + &dma_rg->fmdmemsr);
71681 + }
71682 + tmp_reg |= ((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) <<
71683 + DMA_MODE_CEN_SHIFT;
71684 + tmp_reg |= DMA_MODE_SECURE_PROT;
71685 + tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT;
71686 + tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT;
71687 +
71688 + if (cfg->pedantic_dma)
71689 + tmp_reg |= DMA_MODE_EMER_READ;
71690 +
71691 + iowrite32be(tmp_reg, &dma_rg->fmdmmr);
71692 +
71693 + /* configure thresholds register */
71694 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_asrt_emer <<
71695 + DMA_THRESH_COMMQ_SHIFT) |
71696 + ((uint32_t)cfg->dma_read_buf_tsh_asrt_emer <<
71697 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71698 + ((uint32_t)cfg->dma_write_buf_tsh_asrt_emer);
71699 +
71700 + iowrite32be(tmp_reg, &dma_rg->fmdmtr);
71701 +
71702 + /* configure hysteresis register */
71703 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_clr_emer <<
71704 + DMA_THRESH_COMMQ_SHIFT) |
71705 + ((uint32_t)cfg->dma_read_buf_tsh_clr_emer <<
71706 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71707 + ((uint32_t)cfg->dma_write_buf_tsh_clr_emer);
71708 +
71709 + iowrite32be(tmp_reg, &dma_rg->fmdmhy);
71710 +
71711 + /* configure emergency threshold */
71712 + iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr);
71713 +
71714 + /* configure Watchdog */
71715 + iowrite32be((cfg->dma_watchdog * cfg->clk_freq),
71716 + &dma_rg->fmdmwcr);
71717 +
71718 + iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr);
71719 +
71720 + return 0;
71721 +}
71722 +
71723 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg)
71724 +{
71725 + uint32_t tmp_reg;
71726 + int i;
71727 +
71728 + /**********************/
71729 + /* Init FPM Registers */
71730 + /**********************/
71731 + tmp_reg = (uint32_t)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT);
71732 + iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd);
71733 +
71734 + tmp_reg = (((uint32_t)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) |
71735 + ((uint32_t)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) |
71736 + ((uint32_t)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) |
71737 + ((uint32_t)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT));
71738 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1);
71739 +
71740 + tmp_reg = (((uint32_t)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) |
71741 + ((uint32_t)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) |
71742 + ((uint32_t)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) |
71743 + ((uint32_t)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT));
71744 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2);
71745 +
71746 + /* define exceptions and error behavior */
71747 + tmp_reg = 0;
71748 + /* Clear events */
71749 + tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC |
71750 + FPM_EV_MASK_SINGLE_ECC);
71751 + /* enable interrupts */
71752 + if (cfg->exceptions & FMAN_EX_FPM_STALL_ON_TASKS)
71753 + tmp_reg |= FPM_EV_MASK_STALL_EN;
71754 + if (cfg->exceptions & FMAN_EX_FPM_SINGLE_ECC)
71755 + tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN;
71756 + if (cfg->exceptions & FMAN_EX_FPM_DOUBLE_ECC)
71757 + tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN;
71758 + tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT);
71759 + tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT);
71760 + if (!cfg->halt_on_external_activ)
71761 + tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT;
71762 + if (!cfg->halt_on_unrecov_ecc_err)
71763 + tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT;
71764 + iowrite32be(tmp_reg, &fpm_rg->fmfp_ee);
71765 +
71766 + /* clear all fmCtls event registers */
71767 + for (i = 0; i < cfg->num_of_fman_ctrl_evnt_regs; i++)
71768 + iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]);
71769 +
71770 + /* RAM ECC - enable and clear events*/
71771 + /* first we need to clear all parser memory,
71772 + * as it is uninitialized and may cause ECC errors */
71773 + /* event bits */
71774 + tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC);
71775 + /* Rams enable not effected by RCR bit, but by a COP configuration */
71776 + if (cfg->external_ecc_rams_enable)
71777 + tmp_reg |= FPM_RAM_RAMS_ECC_EN_SRC_SEL;
71778 +
71779 + /* enable test mode */
71780 + if (cfg->en_muram_test_mode)
71781 + tmp_reg |= FPM_RAM_MURAM_TEST_ECC;
71782 + if (cfg->en_iram_test_mode)
71783 + tmp_reg |= FPM_RAM_IRAM_TEST_ECC;
71784 + iowrite32be(tmp_reg, &fpm_rg->fm_rcr);
71785 +
71786 + tmp_reg = 0;
71787 + if (cfg->exceptions & FMAN_EX_IRAM_ECC) {
71788 + tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN;
71789 + fman_enable_rams_ecc(fpm_rg);
71790 + }
71791 + if (cfg->exceptions & FMAN_EX_NURAM_ECC) {
71792 + tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN;
71793 + fman_enable_rams_ecc(fpm_rg);
71794 + }
71795 + iowrite32be(tmp_reg, &fpm_rg->fm_rie);
71796 +
71797 + return 0;
71798 +}
71799 +
71800 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg)
71801 +{
71802 + uint32_t tmp_reg;
71803 +
71804 + /**********************/
71805 + /* Init BMI Registers */
71806 + /**********************/
71807 +
71808 + /* define common resources */
71809 + tmp_reg = cfg->fifo_base_addr;
71810 + tmp_reg = tmp_reg / BMI_FIFO_ALIGN;
71811 +
71812 + tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) <<
71813 + BMI_CFG1_FIFO_SIZE_SHIFT);
71814 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1);
71815 +
71816 + tmp_reg = ((uint32_t)(cfg->total_num_of_tasks - 1) <<
71817 + BMI_CFG2_TASKS_SHIFT);
71818 + /* num of DMA's will be dynamically updated when each port is set */
71819 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2);
71820 +
71821 + /* define unmaskable exceptions, enable and clear events */
71822 + tmp_reg = 0;
71823 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC |
71824 + BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC |
71825 + BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
71826 + BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
71827 + &bmi_rg->fmbm_ievr);
71828 +
71829 + if (cfg->exceptions & FMAN_EX_BMI_LIST_RAM_ECC)
71830 + tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
71831 + if (cfg->exceptions & FMAN_EX_BMI_PIPELINE_ECC)
71832 + tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71833 + if (cfg->exceptions & FMAN_EX_BMI_STATISTICS_RAM_ECC)
71834 + tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71835 + if (cfg->exceptions & FMAN_EX_BMI_DISPATCH_RAM_ECC)
71836 + tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71837 + iowrite32be(tmp_reg, &bmi_rg->fmbm_ier);
71838 +
71839 + return 0;
71840 +}
71841 +
71842 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg)
71843 +{
71844 + uint32_t tmp_reg;
71845 + uint16_t period_in_fm_clocks;
71846 + uint8_t remainder;
71847 + /**********************/
71848 + /* Init QMI Registers */
71849 + /**********************/
71850 + /* Clear error interrupt events */
71851 +
71852 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF,
71853 + &qmi_rg->fmqm_eie);
71854 + tmp_reg = 0;
71855 + if (cfg->exceptions & FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
71856 + tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71857 + if (cfg->exceptions & FMAN_EX_QMI_DOUBLE_ECC)
71858 + tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71859 + /* enable events */
71860 + iowrite32be(tmp_reg, &qmi_rg->fmqm_eien);
71861 +
71862 + if (cfg->tnum_aging_period) {
71863 + /* tnum_aging_period is in units of usec, p_FmClockFreq in Mhz */
71864 + period_in_fm_clocks = (uint16_t)
71865 + (cfg->tnum_aging_period * cfg->clk_freq);
71866 + /* period_in_fm_clocks must be a 64 multiply */
71867 + remainder = (uint8_t)(period_in_fm_clocks % 64);
71868 + if (remainder)
71869 + tmp_reg = (uint32_t)((period_in_fm_clocks / 64) + 1);
71870 + else{
71871 + tmp_reg = (uint32_t)(period_in_fm_clocks / 64);
71872 + if (!tmp_reg)
71873 + tmp_reg = 1;
71874 + }
71875 + tmp_reg <<= QMI_TAPC_TAP;
71876 + iowrite32be(tmp_reg, &qmi_rg->fmqm_tapc);
71877 + }
71878 + tmp_reg = 0;
71879 + /* Clear interrupt events */
71880 + iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie);
71881 + if (cfg->exceptions & FMAN_EX_QMI_SINGLE_ECC)
71882 + tmp_reg |= QMI_INTR_EN_SINGLE_ECC;
71883 + /* enable events */
71884 + iowrite32be(tmp_reg, &qmi_rg->fmqm_ien);
71885 +
71886 + return 0;
71887 +}
71888 +
71889 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71890 +{
71891 + uint32_t cfg_reg = 0;
71892 +
71893 + /**********************/
71894 + /* Enable all modules */
71895 + /**********************/
71896 + /* clear & enable global counters - calculate reg and save for later,
71897 + because it's the same reg for QMI enable */
71898 + cfg_reg = QMI_CFG_EN_COUNTERS;
71899 + if (cfg->qmi_deq_option_support)
71900 + cfg_reg |= (uint32_t)(((cfg->qmi_def_tnums_thresh) << 8) |
71901 + (uint32_t)cfg->qmi_def_tnums_thresh);
71902 +
71903 + iowrite32be(BMI_INIT_START, &fman_rg->bmi_rg->fmbm_init);
71904 + iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN,
71905 + &fman_rg->qmi_rg->fmqm_gc);
71906 +
71907 + return 0;
71908 +}
71909 +
71910 +void fman_free_resources(struct fman_rg *fman_rg)
71911 +{
71912 + /* disable BMI and QMI */
71913 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_init);
71914 + iowrite32be(0, &fman_rg->qmi_rg->fmqm_gc);
71915 +
71916 + /* release BMI resources */
71917 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg2);
71918 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg1);
71919 +
71920 + /* disable ECC */
71921 + iowrite32be(0, &fman_rg->fpm_rg->fm_rcr);
71922 +}
71923 +
71924 +/****************************************************/
71925 +/* API Run-time Control uint functions */
71926 +/****************************************************/
71927 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg)
71928 +{
71929 + return ioread32be(&fpm_rg->fm_npi);
71930 +}
71931 +
71932 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, uint8_t reg_id)
71933 +{
71934 + uint32_t event;
71935 +
71936 + event = ioread32be(&fpm_rg->fmfp_fcev[reg_id]) &
71937 + ioread32be(&fpm_rg->fmfp_cee[reg_id]);
71938 + iowrite32be(event, &fpm_rg->fmfp_cev[reg_id]);
71939 +
71940 + return event;
71941 +}
71942 +
71943 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg)
71944 +{
71945 + return ioread32be(&fpm_rg->fm_epi);
71946 +}
71947 +
71948 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights)
71949 +{
71950 + int i;
71951 + uint8_t shift;
71952 + uint32_t tmp = 0;
71953 +
71954 + for (i = 0; i < 64; i++) {
71955 + if (weights[i] > 1) { /* no need to write 1 since it is 0 */
71956 + /* Add this port to tmp_reg */
71957 + /* (each 8 ports result in one register)*/
71958 + shift = (uint8_t)(32 - 4 * ((i % 8) + 1));
71959 + tmp |= ((weights[i] - 1) << shift);
71960 + }
71961 + if (i % 8 == 7) { /* last in this set */
71962 + iowrite32be(tmp, &bmi_rg->fmbm_arb[i / 8]);
71963 + tmp = 0;
71964 + }
71965 + }
71966 +}
71967 +
71968 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71969 +{
71970 + uint32_t tmp;
71971 +
71972 + tmp = ioread32be(&fpm_rg->fm_rcr);
71973 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71974 + iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN,
71975 + &fpm_rg->fm_rcr);
71976 + else
71977 + iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN |
71978 + FPM_RAM_IRAM_ECC_EN,
71979 + &fpm_rg->fm_rcr);
71980 +}
71981 +
71982 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71983 +{
71984 + uint32_t tmp;
71985 +
71986 + tmp = ioread32be(&fpm_rg->fm_rcr);
71987 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71988 + iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN,
71989 + &fpm_rg->fm_rcr);
71990 + else
71991 + iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN),
71992 + &fpm_rg->fm_rcr);
71993 +}
71994 +
71995 +int fman_set_exception(struct fman_rg *fman_rg,
71996 + enum fman_exceptions exception,
71997 + bool enable)
71998 +{
71999 + uint32_t tmp;
72000 +
72001 + switch (exception) {
72002 + case(E_FMAN_EX_DMA_BUS_ERROR):
72003 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
72004 + if (enable)
72005 + tmp |= DMA_MODE_BER;
72006 + else
72007 + tmp &= ~DMA_MODE_BER;
72008 + /* disable bus error */
72009 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
72010 + break;
72011 + case(E_FMAN_EX_DMA_READ_ECC):
72012 + case(E_FMAN_EX_DMA_SYSTEM_WRITE_ECC):
72013 + case(E_FMAN_EX_DMA_FM_WRITE_ECC):
72014 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
72015 + if (enable)
72016 + tmp |= DMA_MODE_ECC;
72017 + else
72018 + tmp &= ~DMA_MODE_ECC;
72019 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
72020 + break;
72021 + case(E_FMAN_EX_FPM_STALL_ON_TASKS):
72022 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
72023 + if (enable)
72024 + tmp |= FPM_EV_MASK_STALL_EN;
72025 + else
72026 + tmp &= ~FPM_EV_MASK_STALL_EN;
72027 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
72028 + break;
72029 + case(E_FMAN_EX_FPM_SINGLE_ECC):
72030 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
72031 + if (enable)
72032 + tmp |= FPM_EV_MASK_SINGLE_ECC_EN;
72033 + else
72034 + tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN;
72035 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
72036 + break;
72037 + case(E_FMAN_EX_FPM_DOUBLE_ECC):
72038 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
72039 + if (enable)
72040 + tmp |= FPM_EV_MASK_DOUBLE_ECC_EN;
72041 + else
72042 + tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
72043 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
72044 + break;
72045 + case(E_FMAN_EX_QMI_SINGLE_ECC):
72046 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_ien);
72047 + if (enable)
72048 + tmp |= QMI_INTR_EN_SINGLE_ECC;
72049 + else
72050 + tmp &= ~QMI_INTR_EN_SINGLE_ECC;
72051 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_ien);
72052 + break;
72053 + case(E_FMAN_EX_QMI_DOUBLE_ECC):
72054 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
72055 + if (enable)
72056 + tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC;
72057 + else
72058 + tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
72059 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
72060 + break;
72061 + case(E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
72062 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
72063 + if (enable)
72064 + tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
72065 + else
72066 + tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
72067 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
72068 + break;
72069 + case(E_FMAN_EX_BMI_LIST_RAM_ECC):
72070 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
72071 + if (enable)
72072 + tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
72073 + else
72074 + tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
72075 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
72076 + break;
72077 + case(E_FMAN_EX_BMI_STORAGE_PROFILE_ECC):
72078 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
72079 + if (enable)
72080 + tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
72081 + else
72082 + tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
72083 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
72084 + break;
72085 + case(E_FMAN_EX_BMI_STATISTICS_RAM_ECC):
72086 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
72087 + if (enable)
72088 + tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
72089 + else
72090 + tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
72091 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
72092 + break;
72093 + case(E_FMAN_EX_BMI_DISPATCH_RAM_ECC):
72094 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
72095 + if (enable)
72096 + tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
72097 + else
72098 + tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
72099 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
72100 + break;
72101 + case(E_FMAN_EX_IRAM_ECC):
72102 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
72103 + if (enable) {
72104 + /* enable ECC if not enabled */
72105 + fman_enable_rams_ecc(fman_rg->fpm_rg);
72106 + /* enable ECC interrupts */
72107 + tmp |= FPM_IRAM_ECC_ERR_EX_EN;
72108 + } else {
72109 + /* ECC mechanism may be disabled,
72110 + * depending on driver status */
72111 + fman_disable_rams_ecc(fman_rg->fpm_rg);
72112 + tmp &= ~FPM_IRAM_ECC_ERR_EX_EN;
72113 + }
72114 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
72115 + break;
72116 + case(E_FMAN_EX_MURAM_ECC):
72117 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
72118 + if (enable) {
72119 + /* enable ECC if not enabled */
72120 + fman_enable_rams_ecc(fman_rg->fpm_rg);
72121 + /* enable ECC interrupts */
72122 + tmp |= FPM_MURAM_ECC_ERR_EX_EN;
72123 + } else {
72124 + /* ECC mechanism may be disabled,
72125 + * depending on driver status */
72126 + fman_disable_rams_ecc(fman_rg->fpm_rg);
72127 + tmp &= ~FPM_MURAM_ECC_ERR_EX_EN;
72128 + }
72129 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
72130 + break;
72131 + default:
72132 + return -EINVAL;
72133 + }
72134 + return 0;
72135 +}
72136 +
72137 +void fman_get_revision(struct fman_fpm_regs *fpm_rg,
72138 + uint8_t *major,
72139 + uint8_t *minor)
72140 +{
72141 + uint32_t tmp;
72142 +
72143 + tmp = ioread32be(&fpm_rg->fm_ip_rev_1);
72144 + *major = (uint8_t)((tmp & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
72145 + *minor = (uint8_t)((tmp & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
72146 +
72147 +}
72148 +
72149 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
72150 + enum fman_counters reg_name)
72151 +{
72152 + uint32_t ret_val;
72153 +
72154 + switch (reg_name) {
72155 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
72156 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_etfc);
72157 + break;
72158 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
72159 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dtfc);
72160 + break;
72161 + case(E_FMAN_COUNTERS_DEQ_0):
72162 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc0);
72163 + break;
72164 + case(E_FMAN_COUNTERS_DEQ_1):
72165 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc1);
72166 + break;
72167 + case(E_FMAN_COUNTERS_DEQ_2):
72168 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc2);
72169 + break;
72170 + case(E_FMAN_COUNTERS_DEQ_3):
72171 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc3);
72172 + break;
72173 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
72174 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfdc);
72175 + break;
72176 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
72177 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfcc);
72178 + break;
72179 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
72180 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dffc);
72181 + break;
72182 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
72183 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dcc);
72184 + break;
72185 + default:
72186 + ret_val = 0;
72187 + }
72188 + return ret_val;
72189 +}
72190 +
72191 +int fman_modify_counter(struct fman_rg *fman_rg,
72192 + enum fman_counters reg_name,
72193 + uint32_t val)
72194 +{
72195 + /* When applicable (when there is an 'enable counters' bit,
72196 + * check that counters are enabled */
72197 + switch (reg_name) {
72198 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
72199 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
72200 + case(E_FMAN_COUNTERS_DEQ_0):
72201 + case(E_FMAN_COUNTERS_DEQ_1):
72202 + case(E_FMAN_COUNTERS_DEQ_2):
72203 + case(E_FMAN_COUNTERS_DEQ_3):
72204 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
72205 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
72206 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
72207 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
72208 + if (!(ioread32be(&fman_rg->qmi_rg->fmqm_gc) &
72209 + QMI_CFG_EN_COUNTERS))
72210 + return -EINVAL;
72211 + break;
72212 + default:
72213 + break;
72214 + }
72215 + /* Set counter */
72216 + switch (reg_name) {
72217 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
72218 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_etfc);
72219 + break;
72220 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
72221 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dtfc);
72222 + break;
72223 + case(E_FMAN_COUNTERS_DEQ_0):
72224 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc0);
72225 + break;
72226 + case(E_FMAN_COUNTERS_DEQ_1):
72227 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc1);
72228 + break;
72229 + case(E_FMAN_COUNTERS_DEQ_2):
72230 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc2);
72231 + break;
72232 + case(E_FMAN_COUNTERS_DEQ_3):
72233 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc3);
72234 + break;
72235 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
72236 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfdc);
72237 + break;
72238 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
72239 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfcc);
72240 + break;
72241 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
72242 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dffc);
72243 + break;
72244 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
72245 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dcc);
72246 + break;
72247 + case(E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
72248 + iowrite32be(val, &fman_rg->dma_rg->fmdmsefrc);
72249 + break;
72250 + case(E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
72251 + iowrite32be(val, &fman_rg->dma_rg->fmdmsqfrc);
72252 + break;
72253 + case(E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT):
72254 + iowrite32be(val, &fman_rg->dma_rg->fmdmssrc);
72255 + break;
72256 + default:
72257 + break;
72258 + }
72259 + return 0;
72260 +}
72261 +
72262 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg,
72263 + bool is_write,
72264 + bool enable)
72265 +{
72266 + uint32_t msk;
72267 +
72268 + msk = (uint32_t)(is_write ? DMA_MODE_EMER_WRITE : DMA_MODE_EMER_READ);
72269 +
72270 + if (enable)
72271 + iowrite32be(ioread32be(&dma_rg->fmdmmr) | msk,
72272 + &dma_rg->fmdmmr);
72273 + else /* disable */
72274 + iowrite32be(ioread32be(&dma_rg->fmdmmr) & ~msk,
72275 + &dma_rg->fmdmmr);
72276 +}
72277 +
72278 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri)
72279 +{
72280 + uint32_t tmp;
72281 +
72282 + tmp = ioread32be(&dma_rg->fmdmmr) |
72283 + (pri << DMA_MODE_BUS_PRI_SHIFT);
72284 +
72285 + iowrite32be(tmp, &dma_rg->fmdmmr);
72286 +}
72287 +
72288 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg)
72289 +{
72290 + return ioread32be(&dma_rg->fmdmsr);
72291 +}
72292 +
72293 +void fman_force_intr(struct fman_rg *fman_rg,
72294 + enum fman_exceptions exception)
72295 +{
72296 + switch (exception) {
72297 + case E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
72298 + iowrite32be(QMI_ERR_INTR_EN_DEQ_FROM_DEF,
72299 + &fman_rg->qmi_rg->fmqm_eif);
72300 + break;
72301 + case E_FMAN_EX_QMI_SINGLE_ECC:
72302 + iowrite32be(QMI_INTR_EN_SINGLE_ECC,
72303 + &fman_rg->qmi_rg->fmqm_if);
72304 + break;
72305 + case E_FMAN_EX_QMI_DOUBLE_ECC:
72306 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC,
72307 + &fman_rg->qmi_rg->fmqm_eif);
72308 + break;
72309 + case E_FMAN_EX_BMI_LIST_RAM_ECC:
72310 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC,
72311 + &fman_rg->bmi_rg->fmbm_ifr);
72312 + break;
72313 + case E_FMAN_EX_BMI_STORAGE_PROFILE_ECC:
72314 + iowrite32be(BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC,
72315 + &fman_rg->bmi_rg->fmbm_ifr);
72316 + break;
72317 + case E_FMAN_EX_BMI_STATISTICS_RAM_ECC:
72318 + iowrite32be(BMI_ERR_INTR_EN_STATISTICS_RAM_ECC,
72319 + &fman_rg->bmi_rg->fmbm_ifr);
72320 + break;
72321 + case E_FMAN_EX_BMI_DISPATCH_RAM_ECC:
72322 + iowrite32be(BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
72323 + &fman_rg->bmi_rg->fmbm_ifr);
72324 + break;
72325 + default:
72326 + break;
72327 + }
72328 +}
72329 +
72330 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg)
72331 +{
72332 + return (bool)!!(ioread32be(&qmi_rg->fmqm_gs) & QMI_GS_HALT_NOT_BUSY);
72333 +}
72334 +void fman_resume(struct fman_fpm_regs *fpm_rg)
72335 +{
72336 + uint32_t tmp;
72337 +
72338 + tmp = ioread32be(&fpm_rg->fmfp_ee);
72339 + /* clear tmp_reg event bits in order not to clear standing events */
72340 + tmp &= ~(FPM_EV_MASK_DOUBLE_ECC |
72341 + FPM_EV_MASK_STALL |
72342 + FPM_EV_MASK_SINGLE_ECC);
72343 + tmp |= FPM_EV_MASK_RELEASE_FM;
72344 +
72345 + iowrite32be(tmp, &fpm_rg->fmfp_ee);
72346 +}
72347 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
72348 new file mode 100644
72349 index 00000000..204840c9
72350 --- /dev/null
72351 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
72352 @@ -0,0 +1,1214 @@
72353 +/*
72354 + * Copyright 2008-2012 Freescale Semiconductor Inc.
72355 + *
72356 + * Redistribution and use in source and binary forms, with or without
72357 + * modification, are permitted provided that the following conditions are met:
72358 + * * Redistributions of source code must retain the above copyright
72359 + * notice, this list of conditions and the following disclaimer.
72360 + * * Redistributions in binary form must reproduce the above copyright
72361 + * notice, this list of conditions and the following disclaimer in the
72362 + * documentation and/or other materials provided with the distribution.
72363 + * * Neither the name of Freescale Semiconductor nor the
72364 + * names of its contributors may be used to endorse or promote products
72365 + * derived from this software without specific prior written permission.
72366 + *
72367 + *
72368 + * ALTERNATIVELY, this software may be distributed under the terms of the
72369 + * GNU General Public License ("GPL") as published by the Free Software
72370 + * Foundation, either version 2 of that License or (at your option) any
72371 + * later version.
72372 + *
72373 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
72374 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72375 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72376 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
72377 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72378 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72379 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72380 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72381 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72382 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72383 + */
72384 +
72385 +
72386 +/******************************************************************************
72387 + @File fm_common.h
72388 +
72389 + @Description FM internal structures and definitions.
72390 +*//***************************************************************************/
72391 +#ifndef __FM_COMMON_H
72392 +#define __FM_COMMON_H
72393 +
72394 +#include "error_ext.h"
72395 +#include "std_ext.h"
72396 +#include "fm_pcd_ext.h"
72397 +#include "fm_ext.h"
72398 +#include "fm_port_ext.h"
72399 +
72400 +
72401 +#define e_FM_PORT_TYPE_OH_HOST_COMMAND e_FM_PORT_TYPE_DUMMY
72402 +
72403 +#define CLS_PLAN_NUM_PER_GRP 8
72404 +
72405 +#define IP_OFFLOAD_PACKAGE_NUMBER 106
72406 +#define CAPWAP_OFFLOAD_PACKAGE_NUMBER 108
72407 +#define IS_OFFLOAD_PACKAGE(num) ((num == IP_OFFLOAD_PACKAGE_NUMBER) || (num == CAPWAP_OFFLOAD_PACKAGE_NUMBER))
72408 +
72409 +
72410 +
72411 +/**************************************************************************//**
72412 + @Description Modules registers offsets
72413 +*//***************************************************************************/
72414 +#define FM_MM_MURAM 0x00000000
72415 +#define FM_MM_BMI 0x00080000
72416 +#define FM_MM_QMI 0x00080400
72417 +#define FM_MM_PRS 0x000c7000
72418 +#define FM_MM_KG 0x000C1000
72419 +#define FM_MM_DMA 0x000C2000
72420 +#define FM_MM_FPM 0x000C3000
72421 +#define FM_MM_PLCR 0x000C0000
72422 +#define FM_MM_IMEM 0x000C4000
72423 +#define FM_MM_CGP 0x000DB000
72424 +#define FM_MM_TRB(i) (0x000D0200 + 0x400 * (i))
72425 +#if (DPAA_VERSION >= 11)
72426 +#define FM_MM_SP 0x000dc000
72427 +#endif /* (DPAA_VERSION >= 11) */
72428 +
72429 +
72430 +/**************************************************************************//**
72431 + @Description Enum for inter-module interrupts registration
72432 +*//***************************************************************************/
72433 +typedef enum e_FmEventModules{
72434 + e_FM_MOD_PRS, /**< Parser event */
72435 + e_FM_MOD_KG, /**< Keygen event */
72436 + e_FM_MOD_PLCR, /**< Policer event */
72437 + e_FM_MOD_10G_MAC, /**< 10G MAC event */
72438 + e_FM_MOD_1G_MAC, /**< 1G MAC event */
72439 + e_FM_MOD_TMR, /**< Timer event */
72440 + e_FM_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
72441 + e_FM_MOD_MACSEC,
72442 + e_FM_MOD_DUMMY_LAST
72443 +} e_FmEventModules;
72444 +
72445 +/**************************************************************************//**
72446 + @Description Enum for interrupts types
72447 +*//***************************************************************************/
72448 +typedef enum e_FmIntrType {
72449 + e_FM_INTR_TYPE_ERR,
72450 + e_FM_INTR_TYPE_NORMAL
72451 +} e_FmIntrType;
72452 +
72453 +/**************************************************************************//**
72454 + @Description Enum for inter-module interrupts registration
72455 +*//***************************************************************************/
72456 +typedef enum e_FmInterModuleEvent
72457 +{
72458 + e_FM_EV_PRS = 0, /**< Parser event */
72459 + e_FM_EV_ERR_PRS, /**< Parser error event */
72460 + e_FM_EV_KG, /**< Keygen event */
72461 + e_FM_EV_ERR_KG, /**< Keygen error event */
72462 + e_FM_EV_PLCR, /**< Policer event */
72463 + e_FM_EV_ERR_PLCR, /**< Policer error event */
72464 + e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
72465 + e_FM_EV_ERR_10G_MAC1, /**< 10G MAC 1 error event */
72466 + e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
72467 + e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
72468 + e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
72469 + e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
72470 + e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
72471 + e_FM_EV_ERR_1G_MAC5, /**< 1G MAC 5 error event */
72472 + e_FM_EV_ERR_1G_MAC6, /**< 1G MAC 6 error event */
72473 + e_FM_EV_ERR_1G_MAC7, /**< 1G MAC 7 error event */
72474 + e_FM_EV_ERR_MACSEC_MAC0,
72475 + e_FM_EV_TMR, /**< Timer event */
72476 + e_FM_EV_10G_MAC0, /**< 10G MAC 0 event (Magic packet detection)*/
72477 + e_FM_EV_10G_MAC1, /**< 10G MAC 1 event (Magic packet detection)*/
72478 + e_FM_EV_1G_MAC0, /**< 1G MAC 0 event (Magic packet detection)*/
72479 + e_FM_EV_1G_MAC1, /**< 1G MAC 1 event (Magic packet detection)*/
72480 + e_FM_EV_1G_MAC2, /**< 1G MAC 2 (Magic packet detection)*/
72481 + e_FM_EV_1G_MAC3, /**< 1G MAC 3 (Magic packet detection)*/
72482 + e_FM_EV_1G_MAC4, /**< 1G MAC 4 (Magic packet detection)*/
72483 + e_FM_EV_1G_MAC5, /**< 1G MAC 5 (Magic packet detection)*/
72484 + e_FM_EV_1G_MAC6, /**< 1G MAC 6 (Magic packet detection)*/
72485 + e_FM_EV_1G_MAC7, /**< 1G MAC 7 (Magic packet detection)*/
72486 + e_FM_EV_MACSEC_MAC0, /**< MACSEC MAC 0 event */
72487 + e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
72488 + e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
72489 + e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
72490 + e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
72491 + e_FM_EV_DUMMY_LAST
72492 +} e_FmInterModuleEvent;
72493 +
72494 +
72495 +#if defined(__MWERKS__) && !defined(__GNUC__)
72496 +#pragma pack(push,1)
72497 +#endif /* defined(__MWERKS__) && ... */
72498 +
72499 +/**************************************************************************//**
72500 + @Description PCD KG scheme registers
72501 +*//***************************************************************************/
72502 +typedef _Packed struct t_FmPcdPlcrProfileRegs {
72503 + volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/
72504 + volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/
72505 + volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/
72506 + volatile uint32_t fmpl_pernia; /* 0x09C FMPL_PERNIA - FM Policer Profile Entry RED Next Invoked Action*/
72507 + volatile uint32_t fmpl_pecir; /* 0x0A0 FMPL_PECIR - FM Policer Profile Entry Committed Information Rate*/
72508 + volatile uint32_t fmpl_pecbs; /* 0x0A4 FMPL_PECBS - FM Policer Profile Entry Committed Burst Size*/
72509 + volatile uint32_t fmpl_pepepir_eir; /* 0x0A8 FMPL_PEPIR_EIR - FM Policer Profile Entry Peak/Excess Information Rate*/
72510 + volatile uint32_t fmpl_pepbs_ebs; /* 0x0AC FMPL_PEPBS_EBS - FM Policer Profile Entry Peak/Excess Information Rate*/
72511 + volatile uint32_t fmpl_pelts; /* 0x0B0 FMPL_PELTS - FM Policer Profile Entry Last TimeStamp*/
72512 + volatile uint32_t fmpl_pects; /* 0x0B4 FMPL_PECTS - FM Policer Profile Entry Committed Token Status*/
72513 + volatile uint32_t fmpl_pepts_ets; /* 0x0B8 FMPL_PEPTS_ETS - FM Policer Profile Entry Peak/Excess Token Status*/
72514 + volatile uint32_t fmpl_pegpc; /* 0x0BC FMPL_PEGPC - FM Policer Profile Entry GREEN Packet Counter*/
72515 + volatile uint32_t fmpl_peypc; /* 0x0C0 FMPL_PEYPC - FM Policer Profile Entry YELLOW Packet Counter*/
72516 + volatile uint32_t fmpl_perpc; /* 0x0C4 FMPL_PERPC - FM Policer Profile Entry RED Packet Counter */
72517 + volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/
72518 + volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/
72519 + volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */
72520 +} _PackedType t_FmPcdPlcrProfileRegs;
72521 +
72522 +
72523 +typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams {
72524 + volatile uint32_t portIdAndCapwapReassmTbl;
72525 + volatile uint32_t fqidForTimeOutFrames;
72526 + volatile uint32_t timeoutRequestTime;
72527 +}_PackedType t_FmPcdCcCapwapReassmTimeoutParams;
72528 +
72529 +/**************************************************************************//**
72530 + @Description PCD CTRL Parameters Page
72531 +*//***************************************************************************/
72532 +typedef _Packed struct t_FmPcdCtrlParamsPage {
72533 + volatile uint8_t reserved0[16];
72534 + volatile uint32_t iprIpv4Nia;
72535 + volatile uint32_t iprIpv6Nia;
72536 + volatile uint8_t reserved1[24];
72537 + volatile uint32_t ipfOptionsCounter;
72538 + volatile uint8_t reserved2[12];
72539 + volatile uint32_t misc;
72540 + volatile uint32_t errorsDiscardMask;
72541 + volatile uint32_t discardMask;
72542 + volatile uint8_t reserved3[4];
72543 + volatile uint32_t postBmiFetchNia;
72544 + volatile uint8_t reserved4[172];
72545 +} _PackedType t_FmPcdCtrlParamsPage;
72546 +
72547 +
72548 +
72549 +#if defined(__MWERKS__) && !defined(__GNUC__)
72550 +#pragma pack(pop)
72551 +#endif /* defined(__MWERKS__) && ... */
72552 +
72553 +
72554 +/*for UNDER_CONSTRUCTION_FM_RMU_USE_SEC its defined in fm_ext.h*/
72555 +typedef uint32_t t_FmFmanCtrl;
72556 +
72557 +#define FPM_PORT_FM_CTL1 0x00000001
72558 +#define FPM_PORT_FM_CTL2 0x00000002
72559 +
72560 +
72561 +
72562 +typedef struct t_FmPcdCcFragScratchPoolCmdParams {
72563 + uint32_t numOfBuffers;
72564 + uint8_t bufferPoolId;
72565 +} t_FmPcdCcFragScratchPoolCmdParams;
72566 +
72567 +typedef struct t_FmPcdCcReassmTimeoutParams {
72568 + bool activate;
72569 + uint8_t tsbs;
72570 + uint32_t iprcpt;
72571 +} t_FmPcdCcReassmTimeoutParams;
72572 +
72573 +typedef struct {
72574 + uint8_t baseEntry;
72575 + uint16_t numOfClsPlanEntries;
72576 + uint32_t vectors[FM_PCD_MAX_NUM_OF_CLS_PLANS];
72577 +} t_FmPcdKgInterModuleClsPlanSet;
72578 +
72579 +/**************************************************************************//**
72580 + @Description Structure for binding a port to keygen schemes.
72581 +*//***************************************************************************/
72582 +typedef struct t_FmPcdKgInterModuleBindPortToSchemes {
72583 + uint8_t hardwarePortId;
72584 + uint8_t netEnvId;
72585 + bool useClsPlan; /**< TRUE if this port uses the clsPlan mechanism */
72586 + uint8_t numOfSchemes;
72587 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
72588 +} t_FmPcdKgInterModuleBindPortToSchemes;
72589 +
72590 +typedef struct {
72591 + uint32_t nextCcNodeInfo;
72592 + t_List node;
72593 +} t_CcNodeInfo;
72594 +
72595 +typedef struct
72596 +{
72597 + t_Handle h_CcNode;
72598 + uint16_t index;
72599 + t_List node;
72600 +}t_CcNodeInformation;
72601 +#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node)
72602 +
72603 +typedef enum e_ModifyState
72604 +{
72605 + e_MODIFY_STATE_ADD = 0,
72606 + e_MODIFY_STATE_REMOVE,
72607 + e_MODIFY_STATE_CHANGE
72608 +} e_ModifyState;
72609 +
72610 +typedef struct
72611 +{
72612 + t_Handle h_Manip;
72613 + t_List node;
72614 +}t_ManipInfo;
72615 +#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node)
72616 +
72617 +typedef struct {
72618 + uint32_t type;
72619 + uint8_t prOffset;
72620 + uint16_t dataOffset;
72621 + uint8_t internalBufferOffset;
72622 + uint8_t numOfTasks;
72623 + uint8_t numOfExtraTasks;
72624 + uint8_t hardwarePortId;
72625 + t_FmRevisionInfo revInfo;
72626 + uint32_t nia;
72627 + uint32_t discardMask;
72628 +} t_GetCcParams;
72629 +
72630 +typedef struct {
72631 + uint32_t type;
72632 + int psoSize;
72633 + uint32_t nia;
72634 + t_FmFmanCtrl orFmanCtrl;
72635 + bool overwrite;
72636 + uint8_t ofpDpde;
72637 +} t_SetCcParams;
72638 +
72639 +typedef struct {
72640 + t_GetCcParams getCcParams;
72641 + t_SetCcParams setCcParams;
72642 +} t_FmPortGetSetCcParams;
72643 +
72644 +typedef struct {
72645 + uint32_t type;
72646 + bool sleep;
72647 +} t_FmSetParams;
72648 +
72649 +typedef struct {
72650 + uint32_t type;
72651 + uint32_t fmqm_gs;
72652 + uint32_t fm_npi;
72653 + uint32_t fm_cld;
72654 + uint32_t fmfp_extc;
72655 +} t_FmGetParams;
72656 +
72657 +typedef struct {
72658 + t_FmSetParams setParams;
72659 + t_FmGetParams getParams;
72660 +} t_FmGetSetParams;
72661 +
72662 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params);
72663 +
72664 +static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
72665 +{
72666 + uint32_t intFlags;
72667 + if (h_Spinlock)
72668 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
72669 + else
72670 + intFlags = XX_DisableAllIntr();
72671 +
72672 + if (*p_Flag)
72673 + {
72674 + if (h_Spinlock)
72675 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72676 + else
72677 + XX_RestoreAllIntr(intFlags);
72678 + return FALSE;
72679 + }
72680 + *p_Flag = TRUE;
72681 +
72682 + if (h_Spinlock)
72683 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72684 + else
72685 + XX_RestoreAllIntr(intFlags);
72686 +
72687 + return TRUE;
72688 +}
72689 +
72690 +#define RELEASE_LOCK(_flag) _flag = FALSE;
72691 +
72692 +/**************************************************************************//**
72693 + @Collection Defines used for manipulation CC and BMI
72694 + @{
72695 +*//***************************************************************************/
72696 +#define INTERNAL_CONTEXT_OFFSET 0x80000000
72697 +#define OFFSET_OF_PR 0x40000000
72698 +#define MANIP_EXTRA_SPACE 0x20000000
72699 +#define NUM_OF_TASKS 0x10000000
72700 +#define OFFSET_OF_DATA 0x08000000
72701 +#define HW_PORT_ID 0x04000000
72702 +#define FM_REV 0x02000000
72703 +#define GET_NIA_FPNE 0x01000000
72704 +#define GET_NIA_PNDN 0x00800000
72705 +#define NUM_OF_EXTRA_TASKS 0x00400000
72706 +#define DISCARD_MASK 0x00200000
72707 +
72708 +#define UPDATE_NIA_PNEN 0x80000000
72709 +#define UPDATE_PSO 0x40000000
72710 +#define UPDATE_NIA_PNDN 0x20000000
72711 +#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000
72712 +#define UPDATE_OFP_DPTE 0x08000000
72713 +#define UPDATE_NIA_FENE 0x04000000
72714 +#define UPDATE_NIA_CMNE 0x02000000
72715 +#define UPDATE_NIA_FPNE 0x01000000
72716 +/* @} */
72717 +
72718 +/**************************************************************************//**
72719 + @Collection Defines used for manipulation CC and CC
72720 + @{
72721 +*//***************************************************************************/
72722 +#define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000
72723 +#define UPDATE_CC_WITH_TREE 0x40000000
72724 +#define UPDATE_CC_WITH_DELETE_TREE 0x20000000
72725 +#define UPDATE_KG_NIA_CC_WA 0x10000000
72726 +#define UPDATE_KG_OPT_MODE 0x08000000
72727 +#define UPDATE_KG_NIA 0x04000000
72728 +#define UPDATE_CC_SHADOW_CLEAR 0x02000000
72729 +/* @} */
72730 +
72731 +#define UPDATE_FPM_BRKC_SLP 0x80000000
72732 +#define UPDATE_FPM_EXTC 0x40000000
72733 +#define UPDATE_FPM_EXTC_CLEAR 0x20000000
72734 +#define GET_FMQM_GS 0x10000000
72735 +#define GET_FM_NPI 0x08000000
72736 +#define GET_FMFP_EXTC 0x04000000
72737 +#define CLEAR_IRAM_READY 0x02000000
72738 +#define UPDATE_FM_CLD 0x01000000
72739 +#define GET_FM_CLD 0x00800000
72740 +#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
72741 + FM_MAX_NUM_OF_1G_RX_PORTS + \
72742 + FM_MAX_NUM_OF_10G_RX_PORTS + \
72743 + FM_MAX_NUM_OF_1G_TX_PORTS + \
72744 + FM_MAX_NUM_OF_10G_TX_PORTS)
72745 +
72746 +#define MODULE_NAME_SIZE 30
72747 +#define DUMMY_PORT_ID 0
72748 +
72749 +#define FM_LIODN_OFFSET_MASK 0x3FF
72750 +
72751 +/**************************************************************************//**
72752 + @Description NIA Description
72753 +*//***************************************************************************/
72754 +#define NIA_ENG_MASK 0x007C0000
72755 +#define NIA_AC_MASK 0x0003ffff
72756 +
72757 +#define NIA_ORDER_RESTOR 0x00800000
72758 +#define NIA_ENG_FM_CTL 0x00000000
72759 +#define NIA_ENG_PRS 0x00440000
72760 +#define NIA_ENG_KG 0x00480000
72761 +#define NIA_ENG_PLCR 0x004C0000
72762 +#define NIA_ENG_BMI 0x00500000
72763 +#define NIA_ENG_QMI_ENQ 0x00540000
72764 +#define NIA_ENG_QMI_DEQ 0x00580000
72765 +
72766 +#define NIA_FM_CTL_AC_CC 0x00000006
72767 +#define NIA_FM_CTL_AC_HC 0x0000000C
72768 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
72769 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
72770 +#define NIA_FM_CTL_AC_POP_TO_N_STEP 0x0000000e
72771 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER 0x00000010
72772 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME 0x00000018
72773 +#define NIA_FM_CTL_AC_POST_BMI_FETCH 0x00000012
72774 +#define NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME 0x0000001A
72775 +#define NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME 0x0000001E
72776 +#define NIA_FM_CTL_AC_POST_BMI_ENQ_ORR 0x00000014
72777 +#define NIA_FM_CTL_AC_POST_BMI_ENQ 0x00000022
72778 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
72779 +#define NIA_FM_CTL_AC_POST_TX 0x00000024
72780 +/* V3 only */
72781 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
72782 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME 0x0000002A
72783 +#define NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP 0x0000002C
72784 +
72785 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
72786 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
72787 +#define NIA_BMI_AC_RELEASE 0x000000C0
72788 +#define NIA_BMI_AC_DISCARD 0x000000C1
72789 +#define NIA_BMI_AC_TX 0x00000274
72790 +#define NIA_BMI_AC_FETCH 0x00000208
72791 +#define NIA_BMI_AC_MASK 0x000003FF
72792 +
72793 +#define NIA_KG_DIRECT 0x00000100
72794 +#define NIA_KG_CC_EN 0x00000200
72795 +#define NIA_PLCR_ABSOLUTE 0x00008000
72796 +
72797 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
72798 +
72799 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
72800 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72801 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72802 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72803 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME))
72804 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72805 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72806 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72807 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME))
72808 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72809 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME)
72810 +#else
72811 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72812 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72813 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72814 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
72815 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72816 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72817 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72818 + (NIA_ENG_BMI | NIA_BMI_AC_DISCARD))
72819 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72820 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
72821 +#endif /* defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || ... */
72822 +
72823 +/**************************************************************************//**
72824 + @Description CTRL Parameters Page defines
72825 +*//***************************************************************************/
72826 +#define FM_CTL_PARAMS_PAGE_OP_FIX_EN 0x80000000
72827 +#define FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN 0x40000000
72828 +#define FM_CTL_PARAMS_PAGE_ALWAYS_ON 0x00000100
72829 +
72830 +#define FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK 0x0000003f
72831 +
72832 +/**************************************************************************//**
72833 + @Description Port Id defines
72834 +*//***************************************************************************/
72835 +#if (DPAA_VERSION == 10)
72836 +#define BASE_OH_PORTID 1
72837 +#else
72838 +#define BASE_OH_PORTID 2
72839 +#endif /* (DPAA_VERSION == 10) */
72840 +#define BASE_1G_RX_PORTID 8
72841 +#define BASE_10G_RX_PORTID 0x10
72842 +#define BASE_1G_TX_PORTID 0x28
72843 +#define BASE_10G_TX_PORTID 0x30
72844 +
72845 +#define FM_PCD_PORT_OH_BASE_INDX 0
72846 +#define FM_PCD_PORT_1G_RX_BASE_INDX (FM_PCD_PORT_OH_BASE_INDX+FM_MAX_NUM_OF_OH_PORTS)
72847 +#define FM_PCD_PORT_10G_RX_BASE_INDX (FM_PCD_PORT_1G_RX_BASE_INDX+FM_MAX_NUM_OF_1G_RX_PORTS)
72848 +#define FM_PCD_PORT_1G_TX_BASE_INDX (FM_PCD_PORT_10G_RX_BASE_INDX+FM_MAX_NUM_OF_10G_RX_PORTS)
72849 +#define FM_PCD_PORT_10G_TX_BASE_INDX (FM_PCD_PORT_1G_TX_BASE_INDX+FM_MAX_NUM_OF_1G_TX_PORTS)
72850 +
72851 +#if (FM_MAX_NUM_OF_OH_PORTS > 0)
72852 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72853 + if ((_relativePortId) >= FM_MAX_NUM_OF_OH_PORTS) \
72854 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72855 +#else
72856 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72857 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72858 +#endif
72859 +#if (FM_MAX_NUM_OF_1G_RX_PORTS > 0)
72860 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72861 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \
72862 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72863 +#else
72864 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72865 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72866 +#endif
72867 +#if (FM_MAX_NUM_OF_10G_RX_PORTS > 0)
72868 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72869 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \
72870 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72871 +#else
72872 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72873 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72874 +#endif
72875 +#if (FM_MAX_NUM_OF_1G_TX_PORTS > 0)
72876 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72877 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \
72878 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72879 +#else
72880 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72881 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72882 +#endif
72883 +#if (FM_MAX_NUM_OF_10G_TX_PORTS > 0)
72884 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72885 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \
72886 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72887 +#else
72888 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72889 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72890 +#endif
72891 +
72892 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev);
72893 +
72894 +#define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \
72895 +{ if (((hardwarePortId) >= BASE_OH_PORTID) && \
72896 + ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72897 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_OH_PORTID); \
72898 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72899 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72900 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID); \
72901 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72902 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72903 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID); \
72904 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72905 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72906 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID); \
72907 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72908 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72909 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID); \
72910 + else { \
72911 + _relativePortId = (uint8_t)DUMMY_PORT_ID; \
72912 + ASSERT_COND(TRUE); \
72913 + } \
72914 +}
72915 +
72916 +#define HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId) \
72917 +do { \
72918 + if (((hardwarePortId) >= BASE_OH_PORTID) && ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72919 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_OH_PORTID+FM_PCD_PORT_OH_BASE_INDX); \
72920 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72921 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72922 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID+FM_PCD_PORT_1G_RX_BASE_INDX); \
72923 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72924 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72925 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID+FM_PCD_PORT_10G_RX_BASE_INDX); \
72926 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72927 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72928 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID+FM_PCD_PORT_1G_TX_BASE_INDX); \
72929 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72930 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72931 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID+FM_PCD_PORT_10G_TX_BASE_INDX); \
72932 + else ASSERT_COND(FALSE); \
72933 +} while (0)
72934 +
72935 +#define SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, swPortIndex) \
72936 +do { \
72937 + if (((swPortIndex) >= FM_PCD_PORT_OH_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_1G_RX_BASE_INDX)) \
72938 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_OH_BASE_INDX+BASE_OH_PORTID); \
72939 + else if (((swPortIndex) >= FM_PCD_PORT_1G_RX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_RX_BASE_INDX)) \
72940 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_RX_BASE_INDX+BASE_1G_RX_PORTID); \
72941 + else if (((swPortIndex) >= FM_PCD_PORT_10G_RX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72942 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_RX_BASE_INDX+BASE_10G_RX_PORTID); \
72943 + else if (((swPortIndex) >= FM_PCD_PORT_1G_TX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_TX_BASE_INDX)) \
72944 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_TX_BASE_INDX+BASE_1G_TX_PORTID); \
72945 + else if (((swPortIndex) >= FM_PCD_PORT_10G_TX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72946 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_TX_BASE_INDX+BASE_10G_TX_PORTID); \
72947 + else ASSERT_COND(FALSE); \
72948 +} while (0)
72949 +
72950 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
72951 +#define BMI_FIFO_UNITS 0x100
72952 +
72953 +typedef struct {
72954 + void (*f_Isr) (t_Handle h_Arg);
72955 + t_Handle h_SrcHandle;
72956 + uint8_t guestId;
72957 +} t_FmIntrSrc;
72958 +
72959 +#define ILLEGAL_HDR_NUM 0xFF
72960 +#define NO_HDR_NUM FM_PCD_PRS_NUM_OF_HDRS
72961 +
72962 +#define IS_PRIVATE_HEADER(hdr) (((hdr) == HEADER_TYPE_USER_DEFINED_SHIM1) || \
72963 + ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2))
72964 +#define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC)
72965 +
72966 +static __inline__ uint8_t GetPrsHdrNum(e_NetHeaderType hdr)
72967 +{
72968 + switch (hdr)
72969 + { case (HEADER_TYPE_ETH): return 0;
72970 + case (HEADER_TYPE_LLC_SNAP): return 1;
72971 + case (HEADER_TYPE_VLAN): return 2;
72972 + case (HEADER_TYPE_PPPoE): return 3;
72973 + case (HEADER_TYPE_PPP): return 3;
72974 + case (HEADER_TYPE_MPLS): return 4;
72975 + case (HEADER_TYPE_IPv4): return 5;
72976 + case (HEADER_TYPE_IPv6): return 6;
72977 + case (HEADER_TYPE_GRE): return 7;
72978 + case (HEADER_TYPE_MINENCAP): return 8;
72979 + case (HEADER_TYPE_USER_DEFINED_L3): return 9;
72980 + case (HEADER_TYPE_TCP): return 10;
72981 + case (HEADER_TYPE_UDP): return 11;
72982 + case (HEADER_TYPE_IPSEC_AH):
72983 + case (HEADER_TYPE_IPSEC_ESP): return 12;
72984 + case (HEADER_TYPE_SCTP): return 13;
72985 + case (HEADER_TYPE_DCCP): return 14;
72986 + case (HEADER_TYPE_USER_DEFINED_L4): return 15;
72987 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
72988 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
72989 + case (HEADER_TYPE_MACSEC): return NO_HDR_NUM;
72990 + default:
72991 + return ILLEGAL_HDR_NUM;
72992 + }
72993 +}
72994 +
72995 +#define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0))))
72996 +
72997 +
72998 +/**************************************************************************//**
72999 + @Description A structure for initializing a keygen classification plan group
73000 +*//***************************************************************************/
73001 +typedef struct t_FmPcdKgInterModuleClsPlanGrpParams {
73002 + uint8_t netEnvId; /* IN */
73003 + bool grpExists; /* OUT (unused in FmPcdKgBuildClsPlanGrp)*/
73004 + uint8_t clsPlanGrpId; /* OUT */
73005 + bool emptyClsPlanGrp; /* OUT */
73006 + uint8_t numOfOptions; /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
73007 + protocolOpt_t options[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
73008 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
73009 + uint32_t optVectors[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
73010 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
73011 +} t_FmPcdKgInterModuleClsPlanGrpParams;
73012 +
73013 +typedef struct t_FmPcdLock {
73014 + t_Handle h_Spinlock;
73015 + volatile bool flag;
73016 + t_List node;
73017 +} t_FmPcdLock;
73018 +#define FM_PCD_LOCK_OBJ(ptr) LIST_OBJECT(ptr, t_FmPcdLock, node)
73019 +
73020 +
73021 +typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort,
73022 + t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
73023 +
73024 +
73025 +/***********************************************************************/
73026 +/* Common API for FM-PCD module */
73027 +/***********************************************************************/
73028 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd);
73029 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr);
73030 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum);
73031 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId);
73032 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
73033 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
73034 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv);
73035 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId);
73036 +uint32_t FmPcdLock(t_Handle h_FmPcd);
73037 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags);
73038 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
73039 +t_Error FmPcdFragHcScratchPoolInit(t_Handle h_FmPcd, uint8_t scratchBpid);
73040 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
73041 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
73042 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd);
73043 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd);
73044 +void FmPcdLockUnlockAll(t_Handle h_FmPcd);
73045 +t_Error FmPcdHcSync(t_Handle h_FmPcd);
73046 +t_Handle FmGetPcd(t_Handle h_Fm);
73047 +/***********************************************************************/
73048 +/* Common API for FM-PCD KG module */
73049 +/***********************************************************************/
73050 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp);
73051 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp);
73052 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet);
73053 +
73054 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme);
73055 +#if (DPAA_VERSION >= 11)
73056 +bool FmPcdKgGetVspe(t_Handle h_Scheme);
73057 +#endif /* (DPAA_VERSION >= 11) */
73058 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId);
73059 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId);
73060 +t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_Scheme);
73061 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add);
73062 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg);
73063 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter);
73064 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId);
73065 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId);
73066 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId);
73067 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId);
73068 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId);
73069 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme);
73070 +
73071 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
73072 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
73073 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId);
73074 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId);
73075 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId);
73076 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId);
73077 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction);
73078 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId);
73079 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId);
73080 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId);
73081 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId);
73082 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme);
73083 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
73084 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp);
73085 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId);
73086 +
73087 +/***********************************************************************/
73088 +/* Common API for FM-PCD parser module */
73089 +/***********************************************************************/
73090 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include);
73091 +
73092 +/***********************************************************************/
73093 +/* Common API for FM-PCD policer module */
73094 +/***********************************************************************/
73095 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles);
73096 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
73097 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73098 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId);
73099 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
73100 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId);
73101 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter);
73102 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId);
73103 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId);
73104 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile);
73105 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
73106 + e_FmPcdProfileTypeSelection profileType,
73107 + t_Handle h_FmPort,
73108 + uint16_t relativeProfile,
73109 + uint16_t *p_AbsoluteId);
73110 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73111 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73112 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg);
73113 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73114 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73115 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red);
73116 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction);
73117 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction);
73118 +
73119 +/***********************************************************************/
73120 +/* Common API for FM-PCD CC module */
73121 +/***********************************************************************/
73122 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
73123 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
73124 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex);
73125 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams);
73126 +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);
73127 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams);
73128 +t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
73129 +t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
73130 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer);
73131 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree);
73132 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams);
73133 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
73134 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
73135 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort);
73136 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree);
73137 +
73138 +/***********************************************************************/
73139 +/* Common API for FM-PCD Manip module */
73140 +/***********************************************************************/
73141 +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);
73142 +
73143 +/***********************************************************************/
73144 +/* Common API for FM-Port module */
73145 +/***********************************************************************/
73146 +#if (DPAA_VERSION >= 11)
73147 +typedef enum e_FmPortGprFuncType
73148 +{
73149 + e_FM_PORT_GPR_EMPTY = 0,
73150 + e_FM_PORT_GPR_MURAM_PAGE
73151 +} e_FmPortGprFuncType;
73152 +
73153 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, void **p_Value);
73154 +#endif /* DPAA_VERSION >= 11) */
73155 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_FmGetSetParams);
73156 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
73157 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort);
73158 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort);
73159 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort);
73160 +void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort);
73161 +
73162 +
73163 +#if (DPAA_VERSION >= 11)
73164 +t_Error FmPcdFrmReplicUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_FrmReplic);
73165 +#endif /* (DPAA_VERSION >= 11) */
73166 +
73167 +/**************************************************************************//**
73168 + @Function FmRegisterIntr
73169 +
73170 + @Description Used to register an inter-module event handler to be processed by FM
73171 +
73172 + @Param[in] h_Fm A handle to an FM Module.
73173 + @Param[in] mod The module that causes the event
73174 + @Param[in] modId Module id - if more than 1 instansiation of this
73175 + mode exists,0 otherwise.
73176 + @Param[in] intrType Interrupt type (error/normal) selection.
73177 + @Param[in] f_Isr The interrupt service routine.
73178 + @Param[in] h_Arg Argument to be passed to f_Isr.
73179 +
73180 + @Return None.
73181 +*//***************************************************************************/
73182 +void FmRegisterIntr(t_Handle h_Fm,
73183 + e_FmEventModules mod,
73184 + uint8_t modId,
73185 + e_FmIntrType intrType,
73186 + void (*f_Isr) (t_Handle h_Arg),
73187 + t_Handle h_Arg);
73188 +
73189 +/**************************************************************************//**
73190 + @Function FmUnregisterIntr
73191 +
73192 + @Description Used to un-register an inter-module event handler that was processed by FM
73193 +
73194 + @Param[in] h_Fm A handle to an FM Module.
73195 + @Param[in] mod The module that causes the event
73196 + @Param[in] modId Module id - if more than 1 instansiation of this
73197 + mode exists,0 otherwise.
73198 + @Param[in] intrType Interrupt type (error/normal) selection.
73199 +
73200 + @Return None.
73201 +*//***************************************************************************/
73202 +void FmUnregisterIntr(t_Handle h_Fm,
73203 + e_FmEventModules mod,
73204 + uint8_t modId,
73205 + e_FmIntrType intrType);
73206 +
73207 +/**************************************************************************//**
73208 + @Function FmRegisterFmCtlIntr
73209 +
73210 + @Description Used to register to one of the fmCtl events in the FM module
73211 +
73212 + @Param[in] h_Fm A handle to an FM Module.
73213 + @Param[in] eventRegId FmCtl event id (0-7).
73214 + @Param[in] f_Isr The interrupt service routine.
73215 +
73216 + @Return E_OK on success; Error code otherwise.
73217 +
73218 + @Cautions Allowed only following FM_Init().
73219 +*//***************************************************************************/
73220 +void FmRegisterFmCtlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event));
73221 +
73222 +
73223 +/**************************************************************************//**
73224 + @Description enum for defining MAC types
73225 +*//***************************************************************************/
73226 +typedef enum e_FmMacType {
73227 + e_FM_MAC_10G = 0, /**< 10G MAC */
73228 + e_FM_MAC_1G /**< 1G MAC */
73229 +} e_FmMacType;
73230 +
73231 +/**************************************************************************//**
73232 + @Description Structure for port-FM communication during FM_PORT_Init.
73233 + Fields commented 'IN' are passed by the port module to be used
73234 + by the FM module.
73235 + Fields commented 'OUT' will be filled by FM before returning to port.
73236 + Some fields are optional (depending on configuration) and
73237 + will be analized by the port and FM modules accordingly.
73238 +*//***************************************************************************/
73239 +typedef struct t_FmInterModulePortInitParams {
73240 + uint8_t hardwarePortId; /**< IN. port Id */
73241 + e_FmPortType portType; /**< IN. Port type */
73242 + bool independentMode; /**< IN. TRUE if FM Port operates in independent mode */
73243 + uint16_t liodnOffset; /**< IN. Port's requested resource */
73244 + uint8_t numOfTasks; /**< IN. Port's requested resource */
73245 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
73246 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
73247 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
73248 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
73249 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
73250 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
73251 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
73252 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
73253 + LIODN base for this port, to be
73254 + used together with LIODN offset. */
73255 + t_FmPhysAddr fmMuramPhysBaseAddr;/**< OUT. FM-MURAM physical address*/
73256 +} t_FmInterModulePortInitParams;
73257 +
73258 +/**************************************************************************//**
73259 + @Description Structure for port-FM communication during FM_PORT_Free.
73260 +*//***************************************************************************/
73261 +typedef struct t_FmInterModulePortFreeParams {
73262 + uint8_t hardwarePortId; /**< IN. port Id */
73263 + e_FmPortType portType; /**< IN. Port type */
73264 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
73265 +} t_FmInterModulePortFreeParams;
73266 +
73267 +/**************************************************************************//**
73268 + @Function FmGetPcdPrsBaseAddr
73269 +
73270 + @Description Get the base address of the Parser from the FM module
73271 +
73272 + @Param[in] h_Fm A handle to an FM Module.
73273 +
73274 + @Return Base address.
73275 +*//***************************************************************************/
73276 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm);
73277 +
73278 +/**************************************************************************//**
73279 + @Function FmGetPcdKgBaseAddr
73280 +
73281 + @Description Get the base address of the Keygen from the FM module
73282 +
73283 + @Param[in] h_Fm A handle to an FM Module.
73284 +
73285 + @Return Base address.
73286 +*//***************************************************************************/
73287 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm);
73288 +
73289 +/**************************************************************************//**
73290 + @Function FmGetPcdPlcrBaseAddr
73291 +
73292 + @Description Get the base address of the Policer from the FM module
73293 +
73294 + @Param[in] h_Fm A handle to an FM Module.
73295 +
73296 + @Return Base address.
73297 +*//***************************************************************************/
73298 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm);
73299 +
73300 +/**************************************************************************//**
73301 + @Function FmGetMuramHandle
73302 +
73303 + @Description Get the handle of the MURAM from the FM module
73304 +
73305 + @Param[in] h_Fm A handle to an FM Module.
73306 +
73307 + @Return MURAM module handle.
73308 +*//***************************************************************************/
73309 +t_Handle FmGetMuramHandle(t_Handle h_Fm);
73310 +
73311 +/**************************************************************************//**
73312 + @Function FmGetPhysicalMuramBase
73313 +
73314 + @Description Get the physical base address of the MURAM from the FM module
73315 +
73316 + @Param[in] h_Fm A handle to an FM Module.
73317 + @Param[in] fmPhysAddr Physical MURAM base
73318 +
73319 + @Return Physical base address.
73320 +*//***************************************************************************/
73321 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr);
73322 +
73323 +/**************************************************************************//**
73324 + @Function FmGetTimeStampScale
73325 +
73326 + @Description Used internally by other modules in order to get the timeStamp
73327 + period as requested by the application.
73328 +
73329 + This function returns bit number that is incremented every 1 usec.
73330 + To calculate timestamp period in nsec, use
73331 + 1000 / (1 << FmGetTimeStampScale()).
73332 +
73333 + @Param[in] h_Fm A handle to an FM Module.
73334 +
73335 + @Return Bit that counts 1 usec.
73336 +
73337 + @Cautions Allowed only following FM_Init().
73338 +*//***************************************************************************/
73339 +uint32_t FmGetTimeStampScale(t_Handle h_Fm);
73340 +
73341 +/**************************************************************************//**
73342 + @Function FmResumeStalledPort
73343 +
73344 + @Description Used internally by FM port to release a stalled port.
73345 +
73346 + @Param[in] h_Fm A handle to an FM Module.
73347 + @Param[in] hardwarePortId HW port id.
73348 +
73349 + @Return E_OK on success; Error code otherwise.
73350 +
73351 + @Cautions Allowed only following FM_Init().
73352 +*//***************************************************************************/
73353 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId);
73354 +
73355 +/**************************************************************************//**
73356 + @Function FmIsPortStalled
73357 +
73358 + @Description Used internally by FM port to read the port's status.
73359 +
73360 + @Param[in] h_Fm A handle to an FM Module.
73361 + @Param[in] hardwarePortId HW port id.
73362 + @Param[in] p_IsStalled A pointer to the boolean port stalled state
73363 +
73364 + @Return E_OK on success; Error code otherwise.
73365 +
73366 + @Cautions Allowed only following FM_Init().
73367 +*//***************************************************************************/
73368 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled);
73369 +
73370 +/**************************************************************************//**
73371 + @Function FmResetMac
73372 +
73373 + @Description Used by MAC driver to reset the MAC registers
73374 +
73375 + @Param[in] h_Fm A handle to an FM Module.
73376 + @Param[in] type MAC type.
73377 + @Param[in] macId MAC id - according to type.
73378 +
73379 + @Return E_OK on success; Error code otherwise.
73380 +
73381 + @Cautions Allowed only following FM_Init().
73382 +*//***************************************************************************/
73383 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId);
73384 +
73385 +/**************************************************************************//**
73386 + @Function FmGetClockFreq
73387 +
73388 + @Description Used by MAC driver to get the FM clock frequency
73389 +
73390 + @Param[in] h_Fm A handle to an FM Module.
73391 +
73392 + @Return clock-freq on success; 0 otherwise.
73393 +
73394 + @Cautions Allowed only following FM_Init().
73395 +*//***************************************************************************/
73396 +uint16_t FmGetClockFreq(t_Handle h_Fm);
73397 +
73398 +/**************************************************************************//**
73399 + @Function FmGetMacClockFreq
73400 +
73401 + @Description Used by MAC driver to get the MAC clock frequency
73402 +
73403 + @Param[in] h_Fm A handle to an FM Module.
73404 +
73405 + @Return clock-freq on success; 0 otherwise.
73406 +
73407 + @Cautions Allowed only following FM_Init().
73408 +*//***************************************************************************/
73409 +uint16_t FmGetMacClockFreq(t_Handle h_Fm);
73410 +
73411 +/**************************************************************************//**
73412 + @Function FmGetId
73413 +
73414 + @Description Used by PCD driver to read rhe FM id
73415 +
73416 + @Param[in] h_Fm A handle to an FM Module.
73417 +
73418 + @Return E_OK on success; Error code otherwise.
73419 +
73420 + @Cautions Allowed only following FM_Init().
73421 +*//***************************************************************************/
73422 +uint8_t FmGetId(t_Handle h_Fm);
73423 +
73424 +/**************************************************************************//**
73425 + @Function FmReset
73426 +
73427 + @Description Used to reset the FM
73428 +
73429 + @Param[in] h_Fm A handle to an FM Module.
73430 +
73431 + @Return E_OK on success; Error code otherwise.
73432 +*//***************************************************************************/
73433 +t_Error FmReset(t_Handle h_Fm);
73434 +
73435 +/**************************************************************************//**
73436 + @Function FmGetSetPortParams
73437 +
73438 + @Description Used by FM-PORT driver to pass and receive parameters between
73439 + PORT and FM modules.
73440 +
73441 + @Param[in] h_Fm A handle to an FM Module.
73442 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73443 +
73444 + @Return E_OK on success; Error code otherwise.
73445 +
73446 + @Cautions Allowed only following FM_Init().
73447 +*//***************************************************************************/
73448 +t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams);
73449 +
73450 +/**************************************************************************//**
73451 + @Function FmFreePortParams
73452 +
73453 + @Description Used by FM-PORT driver to free port's resources within the FM.
73454 +
73455 + @Param[in] h_Fm A handle to an FM Module.
73456 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73457 +
73458 + @Return None.
73459 +
73460 + @Cautions Allowed only following FM_Init().
73461 +*//***************************************************************************/
73462 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams);
73463 +
73464 +/**************************************************************************//**
73465 + @Function FmSetNumOfRiscsPerPort
73466 +
73467 + @Description Used by FM-PORT driver to pass parameter between
73468 + PORT and FM modules for working with number of RISC..
73469 +
73470 + @Param[in] h_Fm A handle to an FM Module.
73471 + @Param[in] hardwarePortId hardware port Id.
73472 + @Param[in] numOfFmanCtrls number of Fman Controllers.
73473 + @Param[in] orFmanCtrl Fman Controller for order restoration.
73474 +
73475 + @Return None.
73476 +
73477 + @Cautions Allowed only following FM_Init().
73478 +*//***************************************************************************/
73479 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls, t_FmFmanCtrl orFmanCtrl);
73480 +
73481 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73482 +/**************************************************************************//*
73483 + @Function FmDumpPortRegs
73484 +
73485 + @Description Dumps FM port registers which are part of FM common registers
73486 +
73487 + @Param[in] h_Fm A handle to an FM Module.
73488 + @Param[in] hardwarePortId HW port id.
73489 +
73490 + @Return E_OK on success; Error code otherwise.
73491 +
73492 + @Cautions Allowed only FM_Init().
73493 +*//***************************************************************************/
73494 +t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId);
73495 +#endif /* (defined(DEBUG_ERRORS) && ... */
73496 +
73497 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd);
73498 +void FmUnregisterPcd(t_Handle h_Fm);
73499 +t_Handle FmGetPcdHandle(t_Handle h_Fm);
73500 +t_Error FmEnableRamsEcc(t_Handle h_Fm);
73501 +t_Error FmDisableRamsEcc(t_Handle h_Fm);
73502 +void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
73503 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId);
73504 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId);
73505 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents);
73506 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73507 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event), t_Handle h_Arg);
73508 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73509 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu);
73510 +bool FmIsMaster(t_Handle h_Fm);
73511 +uint8_t FmGetGuestId(t_Handle h_Fm);
73512 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm);
73513 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool preFetchConfigured);
73514 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool *p_PortConfigured, bool *p_PreFetchConfigured);
73515 +
73516 +
73517 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
73518 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId);
73519 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
73520 +
73521 +void FmMuramClear(t_Handle h_FmMuram);
73522 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
73523 + uint8_t hardwarePortId,
73524 + uint8_t *p_NumOfOpenDmas,
73525 + uint8_t *p_NumOfExtraOpenDmas,
73526 + bool initialConfig);
73527 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
73528 + uint8_t hardwarePortId,
73529 + uint8_t *p_NumOfTasks,
73530 + uint8_t *p_NumOfExtraTasks,
73531 + bool initialConfig);
73532 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
73533 + uint8_t hardwarePortId,
73534 + uint32_t *p_SizeOfFifo,
73535 + uint32_t *p_ExtraSizeOfFifo,
73536 + bool initialConfig);
73537 +
73538 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
73539 + uint32_t congestionGroupId,
73540 + uint8_t priorityBitMap);
73541 +
73542 +#if (DPAA_VERSION >= 11)
73543 +t_Error FmVSPAllocForPort(t_Handle h_Fm,
73544 + e_FmPortType portType,
73545 + uint8_t portId,
73546 + uint8_t numOfStorageProfiles);
73547 +
73548 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
73549 + e_FmPortType portType,
73550 + uint8_t portId);
73551 +
73552 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
73553 + e_FmPortType portType,
73554 + uint8_t portId,
73555 + uint16_t relativeProfile,
73556 + uint16_t *p_AbsoluteId);
73557 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
73558 + e_FmPortType portType,
73559 + uint8_t portId,
73560 + uint16_t relativeProfile);
73561 +
73562 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm);
73563 +#endif /* (DPAA_VERSION >= 11) */
73564 +
73565 +
73566 +#endif /* __FM_COMMON_H */
73567 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
73568 new file mode 100644
73569 index 00000000..492aa8a3
73570 --- /dev/null
73571 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
73572 @@ -0,0 +1,93 @@
73573 +/*
73574 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73575 + *
73576 + * Redistribution and use in source and binary forms, with or without
73577 + * modification, are permitted provided that the following conditions are met:
73578 + * * Redistributions of source code must retain the above copyright
73579 + * notice, this list of conditions and the following disclaimer.
73580 + * * Redistributions in binary form must reproduce the above copyright
73581 + * notice, this list of conditions and the following disclaimer in the
73582 + * documentation and/or other materials provided with the distribution.
73583 + * * Neither the name of Freescale Semiconductor nor the
73584 + * names of its contributors may be used to endorse or promote products
73585 + * derived from this software without specific prior written permission.
73586 + *
73587 + *
73588 + * ALTERNATIVELY, this software may be distributed under the terms of the
73589 + * GNU General Public License ("GPL") as published by the Free Software
73590 + * Foundation, either version 2 of that License or (at your option) any
73591 + * later version.
73592 + *
73593 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73594 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73595 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73596 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73597 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73598 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73599 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73600 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73601 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73602 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73603 + */
73604 +
73605 +
73606 +#ifndef __FM_HC_H
73607 +#define __FM_HC_H
73608 +
73609 +#include "std_ext.h"
73610 +#include "error_ext.h"
73611 +#include "fsl_fman_kg.h"
73612 +
73613 +#define __ERR_MODULE__ MODULE_FM_PCD
73614 +
73615 +
73616 +typedef struct t_FmHcParams {
73617 + t_Handle h_Fm;
73618 + t_Handle h_FmPcd;
73619 + t_FmPcdHcParams params;
73620 +} t_FmHcParams;
73621 +
73622 +
73623 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams);
73624 +void FmHcFree(t_Handle h_FmHc);
73625 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
73626 + uint8_t memId);
73627 +t_Error FmHcDumpRegs(t_Handle h_FmHc);
73628 +
73629 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd);
73630 +
73631 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
73632 + t_Handle h_Scheme,
73633 + struct fman_kg_scheme_regs *p_SchemeRegs,
73634 + bool updateCounter);
73635 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme);
73636 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams );
73637 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams);
73638 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result);
73639 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set);
73640 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId);
73641 +
73642 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value);
73643 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme);
73644 +
73645 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset);
73646 +
73647 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs);
73648 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile);
73649 +
73650 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value);
73651 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter);
73652 +
73653 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add);
73654 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg);
73655 +
73656 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
73657 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction);
73658 +
73659 +t_Error FmHcPcdSync(t_Handle h_FmHc);
73660 +t_Handle FmHcGetPort(t_Handle h_FmHc);
73661 +
73662 +
73663 +
73664 +
73665 +#endif /* __FM_HC_H */
73666 diff --git a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
73667 new file mode 100644
73668 index 00000000..f9dd384b
73669 --- /dev/null
73670 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
73671 @@ -0,0 +1,117 @@
73672 +/*
73673 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73674 + *
73675 + * Redistribution and use in source and binary forms, with or without
73676 + * modification, are permitted provided that the following conditions are met:
73677 + * * Redistributions of source code must retain the above copyright
73678 + * notice, this list of conditions and the following disclaimer.
73679 + * * Redistributions in binary form must reproduce the above copyright
73680 + * notice, this list of conditions and the following disclaimer in the
73681 + * documentation and/or other materials provided with the distribution.
73682 + * * Neither the name of Freescale Semiconductor nor the
73683 + * names of its contributors may be used to endorse or promote products
73684 + * derived from this software without specific prior written permission.
73685 + *
73686 + *
73687 + * ALTERNATIVELY, this software may be distributed under the terms of the
73688 + * GNU General Public License ("GPL") as published by the Free Software
73689 + * Foundation, either version 2 of that License or (at your option) any
73690 + * later version.
73691 + *
73692 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73693 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73694 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73695 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73696 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73697 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73698 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73699 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73700 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73701 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73702 + */
73703 +
73704 +
73705 +/******************************************************************************
73706 + @File fm_sp_common.h
73707 +
73708 + @Description FM SP ...
73709 +*//***************************************************************************/
73710 +#ifndef __FM_SP_COMMON_H
73711 +#define __FM_SP_COMMON_H
73712 +
73713 +#include "std_ext.h"
73714 +#include "error_ext.h"
73715 +#include "list_ext.h"
73716 +
73717 +#include "fm_ext.h"
73718 +#include "fm_pcd_ext.h"
73719 +#include "fsl_fman.h"
73720 +
73721 +/**************************************************************************//**
73722 + @Description defaults
73723 +*//***************************************************************************/
73724 +#define DEFAULT_FM_SP_bufferPrefixContent_privDataSize 0
73725 +#define DEFAULT_FM_SP_bufferPrefixContent_passPrsResult FALSE
73726 +#define DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp FALSE
73727 +#define DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo FALSE
73728 +#define DEFAULT_FM_SP_bufferPrefixContent_dataAlign 64
73729 +
73730 +/**************************************************************************//**
73731 + @Description structure for defining internal context copying
73732 +*//***************************************************************************/
73733 +typedef struct
73734 +{
73735 + uint16_t extBufOffset; /**< Offset in External buffer to which internal
73736 + context is copied to (Rx) or taken from (Tx, Op). */
73737 + uint8_t intContextOffset; /**< Offset within internal context to copy from
73738 + (Rx) or to copy to (Tx, Op). */
73739 + uint16_t size; /**< Internal offset size to be copied */
73740 +} t_FmSpIntContextDataCopy;
73741 +
73742 +/**************************************************************************//**
73743 + @Description struct for defining external buffer margins
73744 +*//***************************************************************************/
73745 +typedef struct {
73746 + uint16_t startMargins; /**< Number of bytes to be left at the beginning
73747 + of the external buffer (must be divisible by 16) */
73748 + uint16_t endMargins; /**< number of bytes to be left at the end
73749 + of the external buffer(must be divisible by 16) */
73750 +} t_FmSpBufMargins;
73751 +
73752 +typedef struct {
73753 + uint32_t dataOffset;
73754 + uint32_t prsResultOffset;
73755 + uint32_t timeStampOffset;
73756 + uint32_t hashResultOffset;
73757 + uint32_t pcdInfoOffset;
73758 + uint32_t manipOffset;
73759 +} t_FmSpBufferOffsets;
73760 +
73761 +
73762 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmPortIntContextDataCopy,
73763 + t_FmBufferPrefixContent *p_BufferPrefixContent,
73764 + t_FmSpBufMargins *p_FmPortBufMargins,
73765 + t_FmSpBufferOffsets *p_FmPortBufferOffsets,
73766 + uint8_t *internalBufferOffset);
73767 +
73768 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy);
73769 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
73770 + t_FmBackupBmPools *p_FmBackupBmPools,
73771 + t_FmBufPoolDepletion *p_FmBufPoolDepletion);
73772 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins);
73773 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, uint8_t *orderedArray, uint16_t *sizesArray);
73774 +
73775 +t_Error FmPcdSpAllocProfiles(t_Handle h_FmPcd,
73776 + uint8_t hardwarePortId,
73777 + uint16_t numOfStorageProfiles,
73778 + uint16_t *base,
73779 + uint8_t *log2Num);
73780 +t_Error FmPcdSpGetAbsoluteProfileId(t_Handle h_FmPcd,
73781 + t_Handle h_FmPort,
73782 + uint16_t relativeProfile,
73783 + uint16_t *p_AbsoluteId);
73784 +void SpInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73785 +void SpValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73786 +
73787 +
73788 +#endif /* __FM_SP_COMMON_H */
73789 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
73790 new file mode 100644
73791 index 00000000..d03a519c
73792 --- /dev/null
73793 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
73794 @@ -0,0 +1,12 @@
73795 +#
73796 +# Makefile for the Freescale Ethernet controllers
73797 +#
73798 +ccflags-y += -DVERSION=\"\"
73799 +#
73800 +#Include netcomm SW specific definitions
73801 +
73802 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
73803 +
73804 +obj-y += fsl-ncsw-etc.o
73805 +
73806 +fsl-ncsw-etc-objs := mm.o memcpy.o sprint.o list.o error.o
73807 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/error.c b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c
73808 new file mode 100644
73809 index 00000000..fead7f50
73810 --- /dev/null
73811 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c
73812 @@ -0,0 +1,95 @@
73813 +/*
73814 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73815 + *
73816 + * Redistribution and use in source and binary forms, with or without
73817 + * modification, are permitted provided that the following conditions are met:
73818 + * * Redistributions of source code must retain the above copyright
73819 + * notice, this list of conditions and the following disclaimer.
73820 + * * Redistributions in binary form must reproduce the above copyright
73821 + * notice, this list of conditions and the following disclaimer in the
73822 + * documentation and/or other materials provided with the distribution.
73823 + * * Neither the name of Freescale Semiconductor nor the
73824 + * names of its contributors may be used to endorse or promote products
73825 + * derived from this software without specific prior written permission.
73826 + *
73827 + *
73828 + * ALTERNATIVELY, this software may be distributed under the terms of the
73829 + * GNU General Public License ("GPL") as published by the Free Software
73830 + * Foundation, either version 2 of that License or (at your option) any
73831 + * later version.
73832 + *
73833 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73834 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73835 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73836 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73837 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73838 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73839 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73840 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73841 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73842 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73843 + */
73844 +
73845 +
73846 +/*
73847 +
73848 + @File error.c
73849 +
73850 + @Description General errors and events reporting utilities.
73851 +*//***************************************************************************/
73852 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73853 +#include "error_ext.h"
73854 +
73855 +
73856 +const char *dbgLevelStrings[] =
73857 +{
73858 + "CRITICAL"
73859 + ,"MAJOR"
73860 + ,"MINOR"
73861 + ,"WARNING"
73862 + ,"INFO"
73863 + ,"TRACE"
73864 +};
73865 +
73866 +
73867 +char * ErrTypeStrings (e_ErrorType err)
73868 +{
73869 + switch (err)
73870 + {
73871 + case (E_OK): return "OK";
73872 + case (E_WRITE_FAILED): return "Write Access Failed";
73873 + case (E_NO_DEVICE): return "No Device";
73874 + case (E_NOT_AVAILABLE): return "Resource Is Unavailable";
73875 + case (E_NO_MEMORY): return "Memory Allocation Failed";
73876 + case (E_INVALID_ADDRESS): return "Invalid Address";
73877 + case (E_BUSY): return "Resource Is Busy";
73878 + case (E_ALREADY_EXISTS): return "Resource Already Exists";
73879 + case (E_INVALID_OPERATION): return "Invalid Operation";
73880 + case (E_INVALID_VALUE): return "Invalid Value";
73881 + case (E_NOT_IN_RANGE): return "Value Out Of Range";
73882 + case (E_NOT_SUPPORTED): return "Unsupported Operation";
73883 + case (E_INVALID_STATE): return "Invalid State";
73884 + case (E_INVALID_HANDLE): return "Invalid Handle";
73885 + case (E_INVALID_ID): return "Invalid ID";
73886 + case (E_NULL_POINTER): return "Unexpected NULL Pointer";
73887 + case (E_INVALID_SELECTION): return "Invalid Selection";
73888 + case (E_INVALID_COMM_MODE): return "Invalid Communication Mode";
73889 + case (E_INVALID_MEMORY_TYPE): return "Invalid Memory Type";
73890 + case (E_INVALID_CLOCK): return "Invalid Clock";
73891 + case (E_CONFLICT): return "Conflict In Settings";
73892 + case (E_NOT_ALIGNED): return "Incorrect Alignment";
73893 + case (E_NOT_FOUND): return "Resource Not Found";
73894 + case (E_FULL): return "Resource Is Full";
73895 + case (E_EMPTY): return "Resource Is Empty";
73896 + case (E_ALREADY_FREE): return "Resource Already Free";
73897 + case (E_READ_FAILED): return "Read Access Failed";
73898 + case (E_INVALID_FRAME): return "Invalid Frame";
73899 + case (E_SEND_FAILED): return "Send Operation Failed";
73900 + case (E_RECEIVE_FAILED): return "Receive Operation Failed";
73901 + case (E_TIMEOUT): return "Operation Timed Out";
73902 + default:
73903 + break;
73904 + }
73905 + return NULL;
73906 +}
73907 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
73908 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/list.c b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c
73909 new file mode 100644
73910 index 00000000..2d044be2
73911 --- /dev/null
73912 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c
73913 @@ -0,0 +1,71 @@
73914 +/*
73915 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73916 + *
73917 + * Redistribution and use in source and binary forms, with or without
73918 + * modification, are permitted provided that the following conditions are met:
73919 + * * Redistributions of source code must retain the above copyright
73920 + * notice, this list of conditions and the following disclaimer.
73921 + * * Redistributions in binary form must reproduce the above copyright
73922 + * notice, this list of conditions and the following disclaimer in the
73923 + * documentation and/or other materials provided with the distribution.
73924 + * * Neither the name of Freescale Semiconductor nor the
73925 + * names of its contributors may be used to endorse or promote products
73926 + * derived from this software without specific prior written permission.
73927 + *
73928 + *
73929 + * ALTERNATIVELY, this software may be distributed under the terms of the
73930 + * GNU General Public License ("GPL") as published by the Free Software
73931 + * Foundation, either version 2 of that License or (at your option) any
73932 + * later version.
73933 + *
73934 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73935 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73936 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73937 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73938 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73939 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73940 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73941 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73942 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73943 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73944 + */
73945 +
73946 +
73947 +/**************************************************************************//**
73948 +
73949 + @File list.c
73950 +
73951 + @Description Implementation of list.
73952 +*//***************************************************************************/
73953 +#include "std_ext.h"
73954 +#include "list_ext.h"
73955 +
73956 +
73957 +void LIST_Append(t_List *p_NewList, t_List *p_Head)
73958 +{
73959 + t_List *p_First = LIST_FIRST(p_NewList);
73960 +
73961 + if (p_First != p_NewList)
73962 + {
73963 + t_List *p_Last = LIST_LAST(p_NewList);
73964 + t_List *p_Cur = LIST_NEXT(p_Head);
73965 +
73966 + LIST_PREV(p_First) = p_Head;
73967 + LIST_FIRST(p_Head) = p_First;
73968 + LIST_NEXT(p_Last) = p_Cur;
73969 + LIST_LAST(p_Cur) = p_Last;
73970 + }
73971 +}
73972 +
73973 +
73974 +int LIST_NumOfObjs(t_List *p_List)
73975 +{
73976 + t_List *p_Tmp;
73977 + int numOfObjs = 0;
73978 +
73979 + if (!LIST_IsEmpty(p_List))
73980 + LIST_FOR_EACH(p_Tmp, p_List)
73981 + numOfObjs++;
73982 +
73983 + return numOfObjs;
73984 +}
73985 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
73986 new file mode 100644
73987 index 00000000..fa203ec7
73988 --- /dev/null
73989 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
73990 @@ -0,0 +1,620 @@
73991 +/*
73992 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73993 + *
73994 + * Redistribution and use in source and binary forms, with or without
73995 + * modification, are permitted provided that the following conditions are met:
73996 + * * Redistributions of source code must retain the above copyright
73997 + * notice, this list of conditions and the following disclaimer.
73998 + * * Redistributions in binary form must reproduce the above copyright
73999 + * notice, this list of conditions and the following disclaimer in the
74000 + * documentation and/or other materials provided with the distribution.
74001 + * * Neither the name of Freescale Semiconductor nor the
74002 + * names of its contributors may be used to endorse or promote products
74003 + * derived from this software without specific prior written permission.
74004 + *
74005 + *
74006 + * ALTERNATIVELY, this software may be distributed under the terms of the
74007 + * GNU General Public License ("GPL") as published by the Free Software
74008 + * Foundation, either version 2 of that License or (at your option) any
74009 + * later version.
74010 + *
74011 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
74012 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74013 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74014 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
74015 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74016 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74017 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
74018 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74019 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74020 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74021 + */
74022 +
74023 +
74024 +
74025 +#include "std_ext.h"
74026 +#include "xx_ext.h"
74027 +#include "memcpy_ext.h"
74028 +
74029 +void * MemCpy8(void* pDst, void* pSrc, uint32_t size)
74030 +{
74031 + int i;
74032 +
74033 + for(i = 0; i < size; ++i)
74034 + *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i);
74035 +
74036 + return pDst;
74037 +}
74038 +
74039 +void * MemSet8(void* pDst, int c, uint32_t size)
74040 +{
74041 + int i;
74042 +
74043 + for(i = 0; i < size; ++i)
74044 + *(((uint8_t*)(pDst)) + i) = (uint8_t)(c);
74045 +
74046 + return pDst;
74047 +}
74048 +
74049 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size)
74050 +{
74051 + uint32_t leftAlign;
74052 + uint32_t rightAlign;
74053 + uint32_t lastWord;
74054 + uint32_t currWord;
74055 + uint32_t *p_Src32;
74056 + uint32_t *p_Dst32;
74057 + uint8_t *p_Src8;
74058 + uint8_t *p_Dst8;
74059 +
74060 + p_Src8 = (uint8_t*)(pSrc);
74061 + p_Dst8 = (uint8_t*)(pDst);
74062 + /* first copy byte by byte till the source first alignment
74063 + * this step is necessary to ensure we do not even try to access
74064 + * data which is before the source buffer, hence it is not ours.
74065 + */
74066 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74067 + {
74068 + *p_Dst8++ = *p_Src8++;
74069 + size--;
74070 + }
74071 +
74072 + /* align destination (possibly disaligning source)*/
74073 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74074 + {
74075 + *p_Dst8++ = *p_Src8++;
74076 + size--;
74077 + }
74078 +
74079 + /* dest is aligned and source is not necessarily aligned */
74080 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74081 + rightAlign = 32 - leftAlign;
74082 +
74083 +
74084 + if (leftAlign == 0)
74085 + {
74086 + /* source is also aligned */
74087 + p_Src32 = (uint32_t*)(p_Src8);
74088 + p_Dst32 = (uint32_t*)(p_Dst8);
74089 + while (size >> 2) /* size >= 4 */
74090 + {
74091 + *p_Dst32++ = *p_Src32++;
74092 + size -= 4;
74093 + }
74094 + p_Src8 = (uint8_t*)(p_Src32);
74095 + p_Dst8 = (uint8_t*)(p_Dst32);
74096 + }
74097 + else
74098 + {
74099 + /* source is not aligned (destination is aligned)*/
74100 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74101 + p_Dst32 = (uint32_t*)(p_Dst8);
74102 + lastWord = *p_Src32++;
74103 + while(size >> 3) /* size >= 8 */
74104 + {
74105 + currWord = *p_Src32;
74106 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
74107 + lastWord = currWord;
74108 + p_Src32++;
74109 + p_Dst32++;
74110 + size -= 4;
74111 + }
74112 + p_Dst8 = (uint8_t*)(p_Dst32);
74113 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74114 + }
74115 +
74116 + /* complete the left overs */
74117 + while (size--)
74118 + *p_Dst8++ = *p_Src8++;
74119 +
74120 + return pDst;
74121 +}
74122 +
74123 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size)
74124 +{
74125 + uint32_t leftAlign;
74126 + uint32_t rightAlign;
74127 + uint32_t lastWord;
74128 + uint32_t currWord;
74129 + uint32_t *p_Src32;
74130 + uint32_t *p_Dst32;
74131 + uint8_t *p_Src8;
74132 + uint8_t *p_Dst8;
74133 +
74134 + p_Src8 = (uint8_t*)(pSrc);
74135 + p_Dst8 = (uint8_t*)(pDst);
74136 + /* first copy byte by byte till the source first alignment
74137 + * this step is necessary to ensure we do not even try to access
74138 + * data which is before the source buffer, hence it is not ours.
74139 + */
74140 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74141 + {
74142 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
74143 + p_Dst8++;p_Src8++;
74144 + size--;
74145 + }
74146 +
74147 + /* align destination (possibly disaligning source)*/
74148 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74149 + {
74150 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
74151 + p_Dst8++;p_Src8++;
74152 + size--;
74153 + }
74154 +
74155 + /* dest is aligned and source is not necessarily aligned */
74156 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74157 + rightAlign = 32 - leftAlign;
74158 +
74159 + if (leftAlign == 0)
74160 + {
74161 + /* source is also aligned */
74162 + p_Src32 = (uint32_t*)(p_Src8);
74163 + p_Dst32 = (uint32_t*)(p_Dst8);
74164 + while (size >> 2) /* size >= 4 */
74165 + {
74166 + WRITE_UINT32(*p_Dst32, GET_UINT32(*p_Src32));
74167 + p_Dst32++;p_Src32++;
74168 + size -= 4;
74169 + }
74170 + p_Src8 = (uint8_t*)(p_Src32);
74171 + p_Dst8 = (uint8_t*)(p_Dst32);
74172 + }
74173 + else
74174 + {
74175 + /* source is not aligned (destination is aligned)*/
74176 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74177 + p_Dst32 = (uint32_t*)(p_Dst8);
74178 + lastWord = GET_UINT32(*p_Src32);
74179 + p_Src32++;
74180 + while(size >> 3) /* size >= 8 */
74181 + {
74182 + currWord = GET_UINT32(*p_Src32);
74183 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
74184 + lastWord = currWord;
74185 + p_Src32++;p_Dst32++;
74186 + size -= 4;
74187 + }
74188 + p_Dst8 = (uint8_t*)(p_Dst32);
74189 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74190 + }
74191 +
74192 + /* complete the left overs */
74193 + while (size--)
74194 + {
74195 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
74196 + p_Dst8++;p_Src8++;
74197 + }
74198 +
74199 + return pDst;
74200 +}
74201 +
74202 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size)
74203 +{
74204 + uint32_t leftAlign;
74205 + uint32_t rightAlign;
74206 + uint32_t lastWord;
74207 + uint32_t currWord;
74208 + uint32_t *p_Src32;
74209 + uint32_t *p_Dst32;
74210 + uint8_t *p_Src8;
74211 + uint8_t *p_Dst8;
74212 +
74213 + p_Src8 = (uint8_t*)(pSrc);
74214 + p_Dst8 = (uint8_t*)(pDst);
74215 + /* first copy byte by byte till the source first alignment
74216 + * this step is necessary to ensure we do not even try to access
74217 + * data which is before the source buffer, hence it is not ours.
74218 + */
74219 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74220 + {
74221 + WRITE_UINT8(*p_Dst8, *p_Src8);
74222 + p_Dst8++;p_Src8++;
74223 + size--;
74224 + }
74225 +
74226 + /* align destination (possibly disaligning source)*/
74227 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74228 + {
74229 + WRITE_UINT8(*p_Dst8, *p_Src8);
74230 + p_Dst8++;p_Src8++;
74231 + size--;
74232 + }
74233 +
74234 + /* dest is aligned and source is not necessarily aligned */
74235 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74236 + rightAlign = 32 - leftAlign;
74237 +
74238 + if (leftAlign == 0)
74239 + {
74240 + /* source is also aligned */
74241 + p_Src32 = (uint32_t*)(p_Src8);
74242 + p_Dst32 = (uint32_t*)(p_Dst8);
74243 + while (size >> 2) /* size >= 4 */
74244 + {
74245 + WRITE_UINT32(*p_Dst32, *p_Src32);
74246 + p_Dst32++;p_Src32++;
74247 + size -= 4;
74248 + }
74249 + p_Src8 = (uint8_t*)(p_Src32);
74250 + p_Dst8 = (uint8_t*)(p_Dst32);
74251 + }
74252 + else
74253 + {
74254 + /* source is not aligned (destination is aligned)*/
74255 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74256 + p_Dst32 = (uint32_t*)(p_Dst8);
74257 + lastWord = *p_Src32++;
74258 + while(size >> 3) /* size >= 8 */
74259 + {
74260 + currWord = *p_Src32;
74261 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
74262 + lastWord = currWord;
74263 + p_Src32++;p_Dst32++;
74264 + size -= 4;
74265 + }
74266 + p_Dst8 = (uint8_t*)(p_Dst32);
74267 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74268 + }
74269 +
74270 + /* complete the left overs */
74271 + while (size--)
74272 + {
74273 + WRITE_UINT8(*p_Dst8, *p_Src8);
74274 + p_Dst8++;p_Src8++;
74275 + }
74276 +
74277 + return pDst;
74278 +}
74279 +
74280 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size)
74281 +{
74282 + uint32_t leftAlign;
74283 + uint32_t rightAlign;
74284 + uint32_t lastWord;
74285 + uint32_t currWord;
74286 + uint32_t *p_Src32;
74287 + uint32_t *p_Dst32;
74288 + uint8_t *p_Src8;
74289 + uint8_t *p_Dst8;
74290 +
74291 + p_Src8 = (uint8_t*)(pSrc);
74292 + p_Dst8 = (uint8_t*)(pDst);
74293 + /* first copy byte by byte till the source first alignment
74294 + * this step is necessary to ensure we do not even try to access
74295 + * data which is before the source buffer, hence it is not ours.
74296 + */
74297 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74298 + {
74299 + *p_Dst8 = GET_UINT8(*p_Src8);
74300 + p_Dst8++;p_Src8++;
74301 + size--;
74302 + }
74303 +
74304 + /* align destination (possibly disaligning source)*/
74305 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74306 + {
74307 + *p_Dst8 = GET_UINT8(*p_Src8);
74308 + p_Dst8++;p_Src8++;
74309 + size--;
74310 + }
74311 +
74312 + /* dest is aligned and source is not necessarily aligned */
74313 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74314 + rightAlign = 32 - leftAlign;
74315 +
74316 + if (leftAlign == 0)
74317 + {
74318 + /* source is also aligned */
74319 + p_Src32 = (uint32_t*)(p_Src8);
74320 + p_Dst32 = (uint32_t*)(p_Dst8);
74321 + while (size >> 2) /* size >= 4 */
74322 + {
74323 + *p_Dst32 = GET_UINT32(*p_Src32);
74324 + p_Dst32++;p_Src32++;
74325 + size -= 4;
74326 + }
74327 + p_Src8 = (uint8_t*)(p_Src32);
74328 + p_Dst8 = (uint8_t*)(p_Dst32);
74329 + }
74330 + else
74331 + {
74332 + /* source is not aligned (destination is aligned)*/
74333 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74334 + p_Dst32 = (uint32_t*)(p_Dst8);
74335 + lastWord = GET_UINT32(*p_Src32);
74336 + p_Src32++;
74337 + while(size >> 3) /* size >= 8 */
74338 + {
74339 + currWord = GET_UINT32(*p_Src32);
74340 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
74341 + lastWord = currWord;
74342 + p_Src32++;p_Dst32++;
74343 + size -= 4;
74344 + }
74345 + p_Dst8 = (uint8_t*)(p_Dst32);
74346 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74347 + }
74348 +
74349 + /* complete the left overs */
74350 + while (size--)
74351 + {
74352 + *p_Dst8 = GET_UINT8(*p_Src8);
74353 + p_Dst8++;p_Src8++;
74354 + }
74355 +
74356 + return pDst;
74357 +}
74358 +
74359 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size)
74360 +{
74361 + uint32_t leftAlign;
74362 + uint32_t rightAlign;
74363 + uint64_t lastWord;
74364 + uint64_t currWord;
74365 + uint64_t *pSrc64;
74366 + uint64_t *pDst64;
74367 + uint8_t *p_Src8;
74368 + uint8_t *p_Dst8;
74369 +
74370 + p_Src8 = (uint8_t*)(pSrc);
74371 + p_Dst8 = (uint8_t*)(pDst);
74372 + /* first copy byte by byte till the source first alignment
74373 + * this step is necessarily to ensure we do not even try to access
74374 + * data which is before the source buffer, hence it is not ours.
74375 + */
74376 + while((PTR_TO_UINT(p_Src8) & 7) && size) /* (pSrc mod 8) > 0 and size > 0 */
74377 + {
74378 + *p_Dst8++ = *p_Src8++;
74379 + size--;
74380 + }
74381 +
74382 + /* align destination (possibly disaligning source)*/
74383 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74384 + {
74385 + *p_Dst8++ = *p_Src8++;
74386 + size--;
74387 + }
74388 +
74389 + /* dest is aligned and source is not necessarily aligned */
74390 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 7) << 3); /* leftAlign = (pSrc mod 8)*8 */
74391 + rightAlign = 64 - leftAlign;
74392 +
74393 +
74394 + if (leftAlign == 0)
74395 + {
74396 + /* source is also aligned */
74397 + pSrc64 = (uint64_t*)(p_Src8);
74398 + pDst64 = (uint64_t*)(p_Dst8);
74399 + while (size >> 3) /* size >= 8 */
74400 + {
74401 + *pDst64++ = *pSrc64++;
74402 + size -= 8;
74403 + }
74404 + p_Src8 = (uint8_t*)(pSrc64);
74405 + p_Dst8 = (uint8_t*)(pDst64);
74406 + }
74407 + else
74408 + {
74409 + /* source is not aligned (destination is aligned)*/
74410 + pSrc64 = (uint64_t*)(p_Src8 - (leftAlign >> 3));
74411 + pDst64 = (uint64_t*)(p_Dst8);
74412 + lastWord = *pSrc64++;
74413 + while(size >> 4) /* size >= 16 */
74414 + {
74415 + currWord = *pSrc64;
74416 + *pDst64 = (lastWord << leftAlign) | (currWord >> rightAlign);
74417 + lastWord = currWord;
74418 + pSrc64++;
74419 + pDst64++;
74420 + size -= 8;
74421 + }
74422 + p_Dst8 = (uint8_t*)(pDst64);
74423 + p_Src8 = (uint8_t*)(pSrc64) - 8 + (leftAlign >> 3);
74424 + }
74425 +
74426 + /* complete the left overs */
74427 + while (size--)
74428 + *p_Dst8++ = *p_Src8++;
74429 +
74430 + return pDst;
74431 +}
74432 +
74433 +void * MemSet32(void* pDst, uint8_t val, uint32_t size)
74434 +{
74435 + uint32_t val32;
74436 + uint32_t *p_Dst32;
74437 + uint8_t *p_Dst8;
74438 +
74439 + p_Dst8 = (uint8_t*)(pDst);
74440 +
74441 + /* generate four 8-bit val's in 32-bit container */
74442 + val32 = (uint32_t) val;
74443 + val32 |= (val32 << 8);
74444 + val32 |= (val32 << 16);
74445 +
74446 + /* align destination to 32 */
74447 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74448 + {
74449 + *p_Dst8++ = val;
74450 + size--;
74451 + }
74452 +
74453 + /* 32-bit chunks */
74454 + p_Dst32 = (uint32_t*)(p_Dst8);
74455 + while (size >> 2) /* size >= 4 */
74456 + {
74457 + *p_Dst32++ = val32;
74458 + size -= 4;
74459 + }
74460 +
74461 + /* complete the leftovers */
74462 + p_Dst8 = (uint8_t*)(p_Dst32);
74463 + while (size--)
74464 + *p_Dst8++ = val;
74465 +
74466 + return pDst;
74467 +}
74468 +
74469 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size)
74470 +{
74471 + uint32_t val32;
74472 + uint32_t *p_Dst32;
74473 + uint8_t *p_Dst8;
74474 +
74475 + p_Dst8 = (uint8_t*)(pDst);
74476 +
74477 + /* generate four 8-bit val's in 32-bit container */
74478 + val32 = (uint32_t) val;
74479 + val32 |= (val32 << 8);
74480 + val32 |= (val32 << 16);
74481 +
74482 + /* align destination to 32 */
74483 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74484 + {
74485 + WRITE_UINT8(*p_Dst8, val);
74486 + p_Dst8++;
74487 + size--;
74488 + }
74489 +
74490 + /* 32-bit chunks */
74491 + p_Dst32 = (uint32_t*)(p_Dst8);
74492 + while (size >> 2) /* size >= 4 */
74493 + {
74494 + WRITE_UINT32(*p_Dst32, val32);
74495 + p_Dst32++;
74496 + size -= 4;
74497 + }
74498 +
74499 + /* complete the leftovers */
74500 + p_Dst8 = (uint8_t*)(p_Dst32);
74501 + while (size--)
74502 + {
74503 + WRITE_UINT8(*p_Dst8, val);
74504 + p_Dst8++;
74505 + }
74506 +
74507 + return pDst;
74508 +}
74509 +
74510 +void * MemSet64(void* pDst, uint8_t val, uint32_t size)
74511 +{
74512 + uint64_t val64;
74513 + uint64_t *pDst64;
74514 + uint8_t *p_Dst8;
74515 +
74516 + p_Dst8 = (uint8_t*)(pDst);
74517 +
74518 + /* generate four 8-bit val's in 32-bit container */
74519 + val64 = (uint64_t) val;
74520 + val64 |= (val64 << 8);
74521 + val64 |= (val64 << 16);
74522 + val64 |= (val64 << 24);
74523 + val64 |= (val64 << 32);
74524 +
74525 + /* align destination to 64 */
74526 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74527 + {
74528 + *p_Dst8++ = val;
74529 + size--;
74530 + }
74531 +
74532 + /* 64-bit chunks */
74533 + pDst64 = (uint64_t*)(p_Dst8);
74534 + while (size >> 4) /* size >= 8 */
74535 + {
74536 + *pDst64++ = val64;
74537 + size -= 8;
74538 + }
74539 +
74540 + /* complete the leftovers */
74541 + p_Dst8 = (uint8_t*)(pDst64);
74542 + while (size--)
74543 + *p_Dst8++ = val;
74544 +
74545 + return pDst;
74546 +}
74547 +
74548 +void MemDisp(uint8_t *p, int size)
74549 +{
74550 + uint32_t space = (uint32_t)(PTR_TO_UINT(p) & 0x3);
74551 + uint8_t *p_Limit;
74552 +
74553 + if (space)
74554 + {
74555 + p_Limit = (p - space + 4);
74556 +
74557 + XX_Print("0x%08X: ", (p - space));
74558 +
74559 + while (space--)
74560 + {
74561 + XX_Print("--");
74562 + }
74563 + while (size && (p < p_Limit))
74564 + {
74565 + XX_Print("%02x", *(uint8_t*)p);
74566 + size--;
74567 + p++;
74568 + }
74569 +
74570 + XX_Print(" ");
74571 + p_Limit += 12;
74572 +
74573 + while ((size > 3) && (p < p_Limit))
74574 + {
74575 + XX_Print("%08x ", *(uint32_t*)p);
74576 + size -= 4;
74577 + p += 4;
74578 + }
74579 + XX_Print("\r\n");
74580 + }
74581 +
74582 + while (size > 15)
74583 + {
74584 + XX_Print("0x%08X: %08x %08x %08x %08x\r\n",
74585 + p, *(uint32_t *)p, *(uint32_t *)(p + 4),
74586 + *(uint32_t *)(p + 8), *(uint32_t *)(p + 12));
74587 + size -= 16;
74588 + p += 16;
74589 + }
74590 +
74591 + if (size)
74592 + {
74593 + XX_Print("0x%08X: ", p);
74594 +
74595 + while (size > 3)
74596 + {
74597 + XX_Print("%08x ", *(uint32_t *)p);
74598 + size -= 4;
74599 + p += 4;
74600 + }
74601 + while (size)
74602 + {
74603 + XX_Print("%02x", *(uint8_t *)p);
74604 + size--;
74605 + p++;
74606 + }
74607 +
74608 + XX_Print("\r\n");
74609 + }
74610 +}
74611 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
74612 new file mode 100644
74613 index 00000000..9fcc46e0
74614 --- /dev/null
74615 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
74616 @@ -0,0 +1,1155 @@
74617 +/*
74618 + * Copyright 2008-2012 Freescale Semiconductor Inc.
74619 + *
74620 + * Redistribution and use in source and binary forms, with or without
74621 + * modification, are permitted provided that the following conditions are met:
74622 + * * Redistributions of source code must retain the above copyright
74623 + * notice, this list of conditions and the following disclaimer.
74624 + * * Redistributions in binary form must reproduce the above copyright
74625 + * notice, this list of conditions and the following disclaimer in the
74626 + * documentation and/or other materials provided with the distribution.
74627 + * * Neither the name of Freescale Semiconductor nor the
74628 + * names of its contributors may be used to endorse or promote products
74629 + * derived from this software without specific prior written permission.
74630 + *
74631 + *
74632 + * ALTERNATIVELY, this software may be distributed under the terms of the
74633 + * GNU General Public License ("GPL") as published by the Free Software
74634 + * Foundation, either version 2 of that License or (at your option) any
74635 + * later version.
74636 + *
74637 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
74638 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74639 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74640 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
74641 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74642 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74643 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
74644 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74645 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74646 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74647 + */
74648 +
74649 +
74650 +#include "string_ext.h"
74651 +#include "error_ext.h"
74652 +#include "std_ext.h"
74653 +#include "part_ext.h"
74654 +#include "xx_ext.h"
74655 +
74656 +#include "mm.h"
74657 +
74658 +
74659 +
74660 +
74661 +/**********************************************************************
74662 + * MM internal routines set *
74663 + **********************************************************************/
74664 +
74665 +/****************************************************************
74666 + * Routine: CreateBusyBlock
74667 + *
74668 + * Description:
74669 + * Initializes a new busy block of "size" bytes and started
74670 + * rom "base" address. Each busy block has a name that
74671 + * specified the purpose of the memory allocation.
74672 + *
74673 + * Arguments:
74674 + * base - base address of the busy block
74675 + * size - size of the busy block
74676 + * name - name that specified the busy block
74677 + *
74678 + * Return value:
74679 + * A pointer to new created structure returned on success;
74680 + * Otherwise, NULL.
74681 + ****************************************************************/
74682 +static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name)
74683 +{
74684 + t_BusyBlock *p_BusyBlock;
74685 + uint32_t n;
74686 +
74687 + p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock));
74688 + if ( !p_BusyBlock )
74689 + {
74690 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74691 + return NULL;
74692 + }
74693 +
74694 + p_BusyBlock->base = base;
74695 + p_BusyBlock->end = base + size;
74696 +
74697 + n = strlen(name);
74698 + if (n >= MM_MAX_NAME_LEN)
74699 + n = MM_MAX_NAME_LEN - 1;
74700 + strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1);
74701 + p_BusyBlock->name[n] = '\0';
74702 + p_BusyBlock->p_Next = 0;
74703 +
74704 + return p_BusyBlock;
74705 +}
74706 +
74707 +/****************************************************************
74708 + * Routine: CreateNewBlock
74709 + *
74710 + * Description:
74711 + * Initializes a new memory block of "size" bytes and started
74712 + * from "base" address.
74713 + *
74714 + * Arguments:
74715 + * base - base address of the memory block
74716 + * size - size of the memory block
74717 + *
74718 + * Return value:
74719 + * A pointer to new created structure returned on success;
74720 + * Otherwise, NULL.
74721 + ****************************************************************/
74722 +static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size)
74723 +{
74724 + t_MemBlock *p_MemBlock;
74725 +
74726 + p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock));
74727 + if ( !p_MemBlock )
74728 + {
74729 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74730 + return NULL;
74731 + }
74732 +
74733 + p_MemBlock->base = base;
74734 + p_MemBlock->end = base+size;
74735 + p_MemBlock->p_Next = 0;
74736 +
74737 + return p_MemBlock;
74738 +}
74739 +
74740 +/****************************************************************
74741 + * Routine: CreateFreeBlock
74742 + *
74743 + * Description:
74744 + * Initializes a new free block of of "size" bytes and
74745 + * started from "base" address.
74746 + *
74747 + * Arguments:
74748 + * base - base address of the free block
74749 + * size - size of the free block
74750 + *
74751 + * Return value:
74752 + * A pointer to new created structure returned on success;
74753 + * Otherwise, NULL.
74754 + ****************************************************************/
74755 +static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size)
74756 +{
74757 + t_FreeBlock *p_FreeBlock;
74758 +
74759 + p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock));
74760 + if ( !p_FreeBlock )
74761 + {
74762 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74763 + return NULL;
74764 + }
74765 +
74766 + p_FreeBlock->base = base;
74767 + p_FreeBlock->end = base + size;
74768 + p_FreeBlock->p_Next = 0;
74769 +
74770 + return p_FreeBlock;
74771 +}
74772 +
74773 +/****************************************************************
74774 + * Routine: AddFree
74775 + *
74776 + * Description:
74777 + * Adds a new free block to the free lists. It updates each
74778 + * free list to include a new free block.
74779 + * Note, that all free block in each free list are ordered
74780 + * by their base address.
74781 + *
74782 + * Arguments:
74783 + * p_MM - pointer to the MM object
74784 + * base - base address of a given free block
74785 + * end - end address of a given free block
74786 + *
74787 + * Return value:
74788 + *
74789 + *
74790 + ****************************************************************/
74791 +static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end)
74792 +{
74793 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74794 + uint64_t alignment;
74795 + uint64_t alignBase;
74796 + int i;
74797 +
74798 + /* Updates free lists to include a just released block */
74799 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74800 + {
74801 + p_PrevB = p_NewB = 0;
74802 + p_CurrB = p_MM->freeBlocks[i];
74803 +
74804 + alignment = (uint64_t)(0x1 << i);
74805 + alignBase = MAKE_ALIGNED(base, alignment);
74806 +
74807 + /* Goes to the next free list if there is no block to free */
74808 + if (alignBase >= end)
74809 + continue;
74810 +
74811 + /* Looks for a free block that should be updated */
74812 + while ( p_CurrB )
74813 + {
74814 + if ( alignBase <= p_CurrB->end )
74815 + {
74816 + if ( end > p_CurrB->end )
74817 + {
74818 + t_FreeBlock *p_NextB;
74819 + while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end )
74820 + {
74821 + p_NextB = p_CurrB->p_Next;
74822 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74823 + XX_Free(p_NextB);
74824 + }
74825 +
74826 + p_NextB = p_CurrB->p_Next;
74827 + if ( !p_NextB || (p_NextB && end < p_NextB->base) )
74828 + {
74829 + p_CurrB->end = end;
74830 + }
74831 + else
74832 + {
74833 + p_CurrB->end = p_NextB->end;
74834 + p_CurrB->p_Next = p_NextB->p_Next;
74835 + XX_Free(p_NextB);
74836 + }
74837 + }
74838 + else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) )
74839 + {
74840 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74841 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74842 +
74843 + p_NewB->p_Next = p_CurrB;
74844 + if (p_PrevB)
74845 + p_PrevB->p_Next = p_NewB;
74846 + else
74847 + p_MM->freeBlocks[i] = p_NewB;
74848 + break;
74849 + }
74850 +
74851 + if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base))
74852 + {
74853 + p_CurrB->base = alignBase;
74854 + }
74855 +
74856 + /* if size of the free block is less then alignment
74857 + * deletes that free block from the free list. */
74858 + if ( (p_CurrB->end - p_CurrB->base) < alignment)
74859 + {
74860 + if ( p_PrevB )
74861 + p_PrevB->p_Next = p_CurrB->p_Next;
74862 + else
74863 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74864 + XX_Free(p_CurrB);
74865 + p_CurrB = NULL;
74866 + }
74867 + break;
74868 + }
74869 + else
74870 + {
74871 + p_PrevB = p_CurrB;
74872 + p_CurrB = p_CurrB->p_Next;
74873 + }
74874 + }
74875 +
74876 + /* If no free block found to be updated, insert a new free block
74877 + * to the end of the free list.
74878 + */
74879 + if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) )
74880 + {
74881 + if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL)
74882 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74883 +
74884 + if (p_PrevB)
74885 + p_PrevB->p_Next = p_NewB;
74886 + else
74887 + p_MM->freeBlocks[i] = p_NewB;
74888 + }
74889 +
74890 + /* Update boundaries of the new free block */
74891 + if ((alignment == 1) && !p_NewB)
74892 + {
74893 + if ( p_CurrB && base > p_CurrB->base )
74894 + base = p_CurrB->base;
74895 + if ( p_CurrB && end < p_CurrB->end )
74896 + end = p_CurrB->end;
74897 + }
74898 + }
74899 +
74900 + return (E_OK);
74901 +}
74902 +
74903 +/****************************************************************
74904 + * Routine: CutFree
74905 + *
74906 + * Description:
74907 + * Cuts a free block from holdBase to holdEnd from the free lists.
74908 + * That is, it updates all free lists of the MM object do
74909 + * not include a block of memory from holdBase to holdEnd.
74910 + * For each free lists it seek for a free block that holds
74911 + * either holdBase or holdEnd. If such block is found it updates it.
74912 + *
74913 + * Arguments:
74914 + * p_MM - pointer to the MM object
74915 + * holdBase - base address of the allocated block
74916 + * holdEnd - end address of the allocated block
74917 + *
74918 + * Return value:
74919 + * E_OK is returned on success,
74920 + * otherwise returns an error code.
74921 + *
74922 + ****************************************************************/
74923 +static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd)
74924 +{
74925 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74926 + uint64_t alignBase, base, end;
74927 + uint64_t alignment;
74928 + int i;
74929 +
74930 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74931 + {
74932 + p_PrevB = p_NewB = 0;
74933 + p_CurrB = p_MM->freeBlocks[i];
74934 +
74935 + alignment = (uint64_t)(0x1 << i);
74936 + alignBase = MAKE_ALIGNED(holdEnd, alignment);
74937 +
74938 + while ( p_CurrB )
74939 + {
74940 + base = p_CurrB->base;
74941 + end = p_CurrB->end;
74942 +
74943 + if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) )
74944 + {
74945 + if ( alignBase >= end ||
74946 + (alignBase < end && ((end-alignBase) < alignment)) )
74947 + {
74948 + if (p_PrevB)
74949 + p_PrevB->p_Next = p_CurrB->p_Next;
74950 + else
74951 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74952 + XX_Free(p_CurrB);
74953 + }
74954 + else
74955 + {
74956 + p_CurrB->base = alignBase;
74957 + }
74958 + break;
74959 + }
74960 + else if ( (holdBase > base) && (holdEnd <= end) )
74961 + {
74962 + if ( (holdBase-base) >= alignment )
74963 + {
74964 + if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74965 + {
74966 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74967 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74968 + p_NewB->p_Next = p_CurrB->p_Next;
74969 + p_CurrB->p_Next = p_NewB;
74970 + }
74971 + p_CurrB->end = holdBase;
74972 + }
74973 + else if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74974 + {
74975 + p_CurrB->base = alignBase;
74976 + }
74977 + else
74978 + {
74979 + if (p_PrevB)
74980 + p_PrevB->p_Next = p_CurrB->p_Next;
74981 + else
74982 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74983 + XX_Free(p_CurrB);
74984 + }
74985 + break;
74986 + }
74987 + else
74988 + {
74989 + p_PrevB = p_CurrB;
74990 + p_CurrB = p_CurrB->p_Next;
74991 + }
74992 + }
74993 + }
74994 +
74995 + return (E_OK);
74996 +}
74997 +
74998 +/****************************************************************
74999 + * Routine: AddBusy
75000 + *
75001 + * Description:
75002 + * Adds a new busy block to the list of busy blocks. Note,
75003 + * that all busy blocks are ordered by their base address in
75004 + * the busy list.
75005 + *
75006 + * Arguments:
75007 + * MM - handler to the MM object
75008 + * p_NewBusyB - pointer to the a busy block
75009 + *
75010 + * Return value:
75011 + * None.
75012 + *
75013 + ****************************************************************/
75014 +static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB)
75015 +{
75016 + t_BusyBlock *p_CurrBusyB, *p_PrevBusyB;
75017 +
75018 + /* finds a place of a new busy block in the list of busy blocks */
75019 + p_PrevBusyB = 0;
75020 + p_CurrBusyB = p_MM->busyBlocks;
75021 +
75022 + while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base )
75023 + {
75024 + p_PrevBusyB = p_CurrBusyB;
75025 + p_CurrBusyB = p_CurrBusyB->p_Next;
75026 + }
75027 +
75028 + /* insert the new busy block into the list of busy blocks */
75029 + if ( p_CurrBusyB )
75030 + p_NewBusyB->p_Next = p_CurrBusyB;
75031 + if ( p_PrevBusyB )
75032 + p_PrevBusyB->p_Next = p_NewBusyB;
75033 + else
75034 + p_MM->busyBlocks = p_NewBusyB;
75035 +}
75036 +
75037 +/****************************************************************
75038 + * Routine: CutBusy
75039 + *
75040 + * Description:
75041 + * Cuts a block from base to end from the list of busy blocks.
75042 + * This is done by updating the list of busy blocks do not
75043 + * include a given block, that block is going to be free. If a
75044 + * given block is a part of some other busy block, so that
75045 + * busy block is updated. If there are number of busy blocks
75046 + * included in the given block, so all that blocks are removed
75047 + * from the busy list and the end blocks are updated.
75048 + * If the given block devides some block into two parts, a new
75049 + * busy block is added to the busy list.
75050 + *
75051 + * Arguments:
75052 + * p_MM - pointer to the MM object
75053 + * base - base address of a given busy block
75054 + * end - end address of a given busy block
75055 + *
75056 + * Return value:
75057 + * E_OK on success, E_NOMEMORY otherwise.
75058 + *
75059 + ****************************************************************/
75060 +static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end)
75061 +{
75062 + t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB;
75063 +
75064 + p_CurrB = p_MM->busyBlocks;
75065 + p_PrevB = p_NewB = 0;
75066 +
75067 + while ( p_CurrB )
75068 + {
75069 + if ( base < p_CurrB->end )
75070 + {
75071 + if ( end > p_CurrB->end )
75072 + {
75073 + t_BusyBlock *p_NextB;
75074 + while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end )
75075 + {
75076 + p_NextB = p_CurrB->p_Next;
75077 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
75078 + XX_Free(p_NextB);
75079 + }
75080 +
75081 + p_NextB = p_CurrB->p_Next;
75082 + if ( p_NextB && end > p_NextB->base )
75083 + {
75084 + p_NextB->base = end;
75085 + }
75086 + }
75087 +
75088 + if ( base <= p_CurrB->base )
75089 + {
75090 + if ( end < p_CurrB->end && end > p_CurrB->base )
75091 + {
75092 + p_CurrB->base = end;
75093 + }
75094 + else if ( end >= p_CurrB->end )
75095 + {
75096 + if ( p_PrevB )
75097 + p_PrevB->p_Next = p_CurrB->p_Next;
75098 + else
75099 + p_MM->busyBlocks = p_CurrB->p_Next;
75100 + XX_Free(p_CurrB);
75101 + }
75102 + }
75103 + else
75104 + {
75105 + if ( end < p_CurrB->end && end > p_CurrB->base )
75106 + {
75107 + if ((p_NewB = CreateBusyBlock(end,
75108 + p_CurrB->end-end,
75109 + p_CurrB->name)) == NULL)
75110 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75111 + p_NewB->p_Next = p_CurrB->p_Next;
75112 + p_CurrB->p_Next = p_NewB;
75113 + }
75114 + p_CurrB->end = base;
75115 + }
75116 + break;
75117 + }
75118 + else
75119 + {
75120 + p_PrevB = p_CurrB;
75121 + p_CurrB = p_CurrB->p_Next;
75122 + }
75123 + }
75124 +
75125 + return (E_OK);
75126 +}
75127 +
75128 +/****************************************************************
75129 + * Routine: MmGetGreaterAlignment
75130 + *
75131 + * Description:
75132 + * Allocates a block of memory according to the given size
75133 + * and the alignment. That routine is called from the MM_Get
75134 + * routine if the required alignment is greater then MM_MAX_ALIGNMENT.
75135 + * In that case, it goes over free blocks of 64 byte align list
75136 + * and checks if it has the required size of bytes of the required
75137 + * alignment. If no blocks found returns ILLEGAL_BASE.
75138 + * After the block is found and data is allocated, it calls
75139 + * the internal CutFree routine to update all free lists
75140 + * do not include a just allocated block. Of course, each
75141 + * free list contains a free blocks with the same alignment.
75142 + * It is also creates a busy block that holds
75143 + * information about an allocated block.
75144 + *
75145 + * Arguments:
75146 + * MM - handle to the MM object
75147 + * size - size of the MM
75148 + * alignment - index as a power of two defines
75149 + * a required alignment that is greater then 64.
75150 + * name - the name that specifies an allocated block.
75151 + *
75152 + * Return value:
75153 + * base address of an allocated block.
75154 + * ILLEGAL_BASE if can't allocate a block
75155 + *
75156 + ****************************************************************/
75157 +static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name)
75158 +{
75159 + t_FreeBlock *p_FreeB;
75160 + t_BusyBlock *p_NewBusyB;
75161 + uint64_t holdBase, holdEnd, alignBase = 0;
75162 +
75163 + /* goes over free blocks of the 64 byte alignment list
75164 + and look for a block of the suitable size and
75165 + base address according to the alignment. */
75166 + p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT];
75167 +
75168 + while ( p_FreeB )
75169 + {
75170 + alignBase = MAKE_ALIGNED(p_FreeB->base, alignment);
75171 +
75172 + /* the block is found if the aligned base inside the block
75173 + * and has the anough size. */
75174 + if ( alignBase >= p_FreeB->base &&
75175 + alignBase < p_FreeB->end &&
75176 + size <= (p_FreeB->end - alignBase) )
75177 + break;
75178 + else
75179 + p_FreeB = p_FreeB->p_Next;
75180 + }
75181 +
75182 + /* If such block isn't found */
75183 + if ( !p_FreeB )
75184 + return (uint64_t)(ILLEGAL_BASE);
75185 +
75186 + holdBase = alignBase;
75187 + holdEnd = alignBase + size;
75188 +
75189 + /* init a new busy block */
75190 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75191 + return (uint64_t)(ILLEGAL_BASE);
75192 +
75193 + /* calls Update routine to update a lists of free blocks */
75194 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
75195 + {
75196 + XX_Free(p_NewBusyB);
75197 + return (uint64_t)(ILLEGAL_BASE);
75198 + }
75199 +
75200 + /* insert the new busy block into the list of busy blocks */
75201 + AddBusy ( p_MM, p_NewBusyB );
75202 +
75203 + return (holdBase);
75204 +}
75205 +
75206 +
75207 +/**********************************************************************
75208 + * MM API routines set *
75209 + **********************************************************************/
75210 +
75211 +/*****************************************************************************/
75212 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size)
75213 +{
75214 + t_MM *p_MM;
75215 + uint64_t newBase, newSize;
75216 + int i;
75217 +
75218 + if (!size)
75219 + {
75220 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)"));
75221 + }
75222 +
75223 + /* Initializes a new MM object */
75224 + p_MM = (t_MM *)XX_Malloc(sizeof(t_MM));
75225 + if (!p_MM)
75226 + {
75227 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75228 + }
75229 +
75230 + p_MM->h_Spinlock = XX_InitSpinlock();
75231 + if (!p_MM->h_Spinlock)
75232 + {
75233 + XX_Free(p_MM);
75234 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!"));
75235 + }
75236 +
75237 + /* Initializes counter of free memory to total size */
75238 + p_MM->freeMemSize = size;
75239 +
75240 + /* A busy list is empty */
75241 + p_MM->busyBlocks = 0;
75242 +
75243 + /* Initializes a new memory block */
75244 + if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL)
75245 + {
75246 + MM_Free(p_MM);
75247 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75248 + }
75249 +
75250 + /* Initializes a new free block for each free list*/
75251 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75252 + {
75253 + newBase = MAKE_ALIGNED( base, (0x1 << i) );
75254 + newSize = size - (newBase - base);
75255 +
75256 + if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL)
75257 + {
75258 + MM_Free(p_MM);
75259 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75260 + }
75261 + }
75262 +
75263 + *h_MM = p_MM;
75264 +
75265 + return (E_OK);
75266 +}
75267 +
75268 +/*****************************************************************************/
75269 +void MM_Free(t_Handle h_MM)
75270 +{
75271 + t_MM *p_MM = (t_MM *)h_MM;
75272 + t_MemBlock *p_MemBlock;
75273 + t_BusyBlock *p_BusyBlock;
75274 + t_FreeBlock *p_FreeBlock;
75275 + void *p_Block;
75276 + int i;
75277 +
75278 + ASSERT_COND(p_MM);
75279 +
75280 + /* release memory allocated for busy blocks */
75281 + p_BusyBlock = p_MM->busyBlocks;
75282 + while ( p_BusyBlock )
75283 + {
75284 + p_Block = p_BusyBlock;
75285 + p_BusyBlock = p_BusyBlock->p_Next;
75286 + XX_Free(p_Block);
75287 + }
75288 +
75289 + /* release memory allocated for free blocks */
75290 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75291 + {
75292 + p_FreeBlock = p_MM->freeBlocks[i];
75293 + while ( p_FreeBlock )
75294 + {
75295 + p_Block = p_FreeBlock;
75296 + p_FreeBlock = p_FreeBlock->p_Next;
75297 + XX_Free(p_Block);
75298 + }
75299 + }
75300 +
75301 + /* release memory allocated for memory blocks */
75302 + p_MemBlock = p_MM->memBlocks;
75303 + while ( p_MemBlock )
75304 + {
75305 + p_Block = p_MemBlock;
75306 + p_MemBlock = p_MemBlock->p_Next;
75307 + XX_Free(p_Block);
75308 + }
75309 +
75310 + if (p_MM->h_Spinlock)
75311 + XX_FreeSpinlock(p_MM->h_Spinlock);
75312 +
75313 + /* release memory allocated for MM object itself */
75314 + XX_Free(p_MM);
75315 +}
75316 +
75317 +/*****************************************************************************/
75318 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name)
75319 +{
75320 + t_MM *p_MM = (t_MM *)h_MM;
75321 + t_FreeBlock *p_FreeB;
75322 + t_BusyBlock *p_NewBusyB;
75323 + uint64_t holdBase, holdEnd, j, i = 0;
75324 + uint32_t intFlags;
75325 +
75326 + SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE);
75327 +
75328 + /* checks that alignment value is greater then zero */
75329 + if (alignment == 0)
75330 + {
75331 + alignment = 1;
75332 + }
75333 +
75334 + j = alignment;
75335 +
75336 + /* checks if alignment is a power of two, if it correct and if the
75337 + required size is multiple of the given alignment. */
75338 + while ((j & 0x1) == 0)
75339 + {
75340 + i++;
75341 + j = j >> 1;
75342 + }
75343 +
75344 + /* if the given alignment isn't power of two, returns an error */
75345 + if (j != 1)
75346 + {
75347 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)"));
75348 + return (uint64_t)ILLEGAL_BASE;
75349 + }
75350 +
75351 + if (i > MM_MAX_ALIGNMENT)
75352 + {
75353 + return (MmGetGreaterAlignment(p_MM, size, alignment, name));
75354 + }
75355 +
75356 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75357 + /* look for a block of the size greater or equal to the required size. */
75358 + p_FreeB = p_MM->freeBlocks[i];
75359 + while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size )
75360 + p_FreeB = p_FreeB->p_Next;
75361 +
75362 + /* If such block is found */
75363 + if ( !p_FreeB )
75364 + {
75365 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75366 + return (uint64_t)(ILLEGAL_BASE);
75367 + }
75368 +
75369 + holdBase = p_FreeB->base;
75370 + holdEnd = holdBase + size;
75371 +
75372 + /* init a new busy block */
75373 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75374 + {
75375 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75376 + return (uint64_t)(ILLEGAL_BASE);
75377 + }
75378 +
75379 + /* calls Update routine to update a lists of free blocks */
75380 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
75381 + {
75382 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75383 + XX_Free(p_NewBusyB);
75384 + return (uint64_t)(ILLEGAL_BASE);
75385 + }
75386 +
75387 + /* Decreasing the allocated memory size from free memory size */
75388 + p_MM->freeMemSize -= size;
75389 +
75390 + /* insert the new busy block into the list of busy blocks */
75391 + AddBusy ( p_MM, p_NewBusyB );
75392 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75393 +
75394 + return (holdBase);
75395 +}
75396 +
75397 +/*****************************************************************************/
75398 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name)
75399 +{
75400 + t_MM *p_MM = (t_MM *)h_MM;
75401 + t_FreeBlock *p_FreeB;
75402 + t_BusyBlock *p_NewBusyB;
75403 + uint32_t intFlags;
75404 + bool blockIsFree = FALSE;
75405 +
75406 + ASSERT_COND(p_MM);
75407 +
75408 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75409 + p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the
75410 + free list with alignment 1 */
75411 +
75412 + while ( p_FreeB )
75413 + {
75414 + if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end )
75415 + {
75416 + blockIsFree = TRUE;
75417 + break;
75418 + }
75419 + else
75420 + p_FreeB = p_FreeB->p_Next;
75421 + }
75422 +
75423 + if ( !blockIsFree )
75424 + {
75425 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75426 + return (uint64_t)(ILLEGAL_BASE);
75427 + }
75428 +
75429 + /* init a new busy block */
75430 + if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL)
75431 + {
75432 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75433 + return (uint64_t)(ILLEGAL_BASE);
75434 + }
75435 +
75436 + /* calls Update routine to update a lists of free blocks */
75437 + if ( CutFree ( p_MM, base, base+size ) != E_OK )
75438 + {
75439 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75440 + XX_Free(p_NewBusyB);
75441 + return (uint64_t)(ILLEGAL_BASE);
75442 + }
75443 +
75444 + /* Decreasing the allocated memory size from free memory size */
75445 + p_MM->freeMemSize -= size;
75446 +
75447 + /* insert the new busy block into the list of busy blocks */
75448 + AddBusy ( p_MM, p_NewBusyB );
75449 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75450 +
75451 + return (base);
75452 +}
75453 +
75454 +/*****************************************************************************/
75455 +uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name)
75456 +{
75457 + t_MM *p_MM = (t_MM *)h_MM;
75458 + t_FreeBlock *p_FreeB;
75459 + t_BusyBlock *p_NewBusyB;
75460 + uint64_t holdBase, holdEnd, j = alignment, i=0;
75461 + uint32_t intFlags;
75462 +
75463 + ASSERT_COND(p_MM);
75464 +
75465 + /* checks if alignment is a power of two, if it correct and if the
75466 + required size is multiple of the given alignment. */
75467 + while ((j & 0x1) == 0)
75468 + {
75469 + i++;
75470 + j = j >> 1;
75471 + }
75472 +
75473 + if ( (j != 1) || (i > MM_MAX_ALIGNMENT) )
75474 + {
75475 + return (uint64_t)(ILLEGAL_BASE);
75476 + }
75477 +
75478 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75479 + p_FreeB = p_MM->freeBlocks[i];
75480 +
75481 + /* look for the first block that contains the minimum
75482 + base address. If the whole required size may be fit
75483 + into it, use that block, otherwise look for the next
75484 + block of size greater or equal to the required size. */
75485 + while ( p_FreeB && (min >= p_FreeB->end))
75486 + p_FreeB = p_FreeB->p_Next;
75487 +
75488 + /* If such block is found */
75489 + if ( !p_FreeB )
75490 + {
75491 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75492 + return (uint64_t)(ILLEGAL_BASE);
75493 + }
75494 +
75495 + /* if this block is large enough, use this block */
75496 + holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min;
75497 + if ((holdBase + size) <= p_FreeB->end )
75498 + {
75499 + holdEnd = holdBase + size;
75500 + }
75501 + else
75502 + {
75503 + p_FreeB = p_FreeB->p_Next;
75504 + while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) )
75505 + p_FreeB = p_FreeB->p_Next;
75506 +
75507 + /* If such block is found */
75508 + if ( !p_FreeB )
75509 + {
75510 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75511 + return (uint64_t)(ILLEGAL_BASE);
75512 + }
75513 +
75514 + holdBase = p_FreeB->base;
75515 + holdEnd = holdBase + size;
75516 + }
75517 +
75518 + /* init a new busy block */
75519 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75520 + {
75521 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75522 + return (uint64_t)(ILLEGAL_BASE);
75523 + }
75524 +
75525 + /* calls Update routine to update a lists of free blocks */
75526 + if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK )
75527 + {
75528 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75529 + XX_Free(p_NewBusyB);
75530 + return (uint64_t)(ILLEGAL_BASE);
75531 + }
75532 +
75533 + /* Decreasing the allocated memory size from free memory size */
75534 + p_MM->freeMemSize -= size;
75535 +
75536 + /* insert the new busy block into the list of busy blocks */
75537 + AddBusy( p_MM, p_NewBusyB );
75538 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75539 +
75540 + return (holdBase);
75541 +}
75542 +
75543 +/*****************************************************************************/
75544 +uint64_t MM_Put(t_Handle h_MM, uint64_t base)
75545 +{
75546 + t_MM *p_MM = (t_MM *)h_MM;
75547 + t_BusyBlock *p_BusyB, *p_PrevBusyB;
75548 + uint64_t size;
75549 + uint32_t intFlags;
75550 +
75551 + ASSERT_COND(p_MM);
75552 +
75553 + /* Look for a busy block that have the given base value.
75554 + * That block will be returned back to the memory.
75555 + */
75556 + p_PrevBusyB = 0;
75557 +
75558 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75559 + p_BusyB = p_MM->busyBlocks;
75560 + while ( p_BusyB && base != p_BusyB->base )
75561 + {
75562 + p_PrevBusyB = p_BusyB;
75563 + p_BusyB = p_BusyB->p_Next;
75564 + }
75565 +
75566 + if ( !p_BusyB )
75567 + {
75568 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75569 + return (uint64_t)(0);
75570 + }
75571 +
75572 + if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK )
75573 + {
75574 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75575 + return (uint64_t)(0);
75576 + }
75577 +
75578 + /* removes a busy block form the list of busy blocks */
75579 + if ( p_PrevBusyB )
75580 + p_PrevBusyB->p_Next = p_BusyB->p_Next;
75581 + else
75582 + p_MM->busyBlocks = p_BusyB->p_Next;
75583 +
75584 + size = p_BusyB->end - p_BusyB->base;
75585 +
75586 + /* Adding the deallocated memory size to free memory size */
75587 + p_MM->freeMemSize += size;
75588 +
75589 + XX_Free(p_BusyB);
75590 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75591 +
75592 + return (size);
75593 +}
75594 +
75595 +/*****************************************************************************/
75596 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size)
75597 +{
75598 + t_MM *p_MM = (t_MM *)h_MM;
75599 + uint64_t end = base + size;
75600 + uint32_t intFlags;
75601 +
75602 + ASSERT_COND(p_MM);
75603 +
75604 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75605 +
75606 + if ( CutBusy( p_MM, base, end ) != E_OK )
75607 + {
75608 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75609 + return (uint64_t)(0);
75610 + }
75611 +
75612 + if ( AddFree ( p_MM, base, end ) != E_OK )
75613 + {
75614 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75615 + return (uint64_t)(0);
75616 + }
75617 +
75618 + /* Adding the deallocated memory size to free memory size */
75619 + p_MM->freeMemSize += size;
75620 +
75621 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75622 +
75623 + return (size);
75624 +}
75625 +
75626 +/*****************************************************************************/
75627 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size)
75628 +{
75629 + t_MM *p_MM = (t_MM *)h_MM;
75630 + t_MemBlock *p_MemB, *p_NewMemB;
75631 + t_Error errCode;
75632 + uint32_t intFlags;
75633 +
75634 + ASSERT_COND(p_MM);
75635 +
75636 + /* find a last block in the list of memory blocks to insert a new
75637 + * memory block
75638 + */
75639 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75640 +
75641 + p_MemB = p_MM->memBlocks;
75642 + while ( p_MemB->p_Next )
75643 + {
75644 + if ( base >= p_MemB->base && base < p_MemB->end )
75645 + {
75646 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75647 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75648 + }
75649 + p_MemB = p_MemB->p_Next;
75650 + }
75651 + /* check for a last memory block */
75652 + if ( base >= p_MemB->base && base < p_MemB->end )
75653 + {
75654 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75655 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75656 + }
75657 +
75658 + /* create a new memory block */
75659 + if ((p_NewMemB = CreateNewBlock(base, size)) == NULL)
75660 + {
75661 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75662 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75663 + }
75664 +
75665 + /* append a new memory block to the end of the list of memory blocks */
75666 + p_MemB->p_Next = p_NewMemB;
75667 +
75668 + /* add a new free block to the free lists */
75669 + errCode = AddFree(p_MM, base, base+size);
75670 + if (errCode)
75671 + {
75672 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75673 + p_MemB->p_Next = 0;
75674 + XX_Free(p_NewMemB);
75675 + return ((t_Error)errCode);
75676 + }
75677 +
75678 + /* Adding the new block size to free memory size */
75679 + p_MM->freeMemSize += size;
75680 +
75681 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75682 +
75683 + return (E_OK);
75684 +}
75685 +
75686 +/*****************************************************************************/
75687 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index)
75688 +{
75689 + t_MM *p_MM = (t_MM*)h_MM;
75690 + t_MemBlock *p_MemBlock;
75691 + int i;
75692 +
75693 + ASSERT_COND(p_MM);
75694 +
75695 + p_MemBlock = p_MM->memBlocks;
75696 + for (i=0; i < index; i++)
75697 + p_MemBlock = p_MemBlock->p_Next;
75698 +
75699 + if ( p_MemBlock )
75700 + return (p_MemBlock->base);
75701 + else
75702 + return (uint64_t)ILLEGAL_BASE;
75703 +}
75704 +
75705 +/*****************************************************************************/
75706 +uint64_t MM_GetBase(t_Handle h_MM)
75707 +{
75708 + t_MM *p_MM = (t_MM*)h_MM;
75709 + t_MemBlock *p_MemBlock;
75710 +
75711 + ASSERT_COND(p_MM);
75712 +
75713 + p_MemBlock = p_MM->memBlocks;
75714 + return p_MemBlock->base;
75715 +}
75716 +
75717 +/*****************************************************************************/
75718 +bool MM_InRange(t_Handle h_MM, uint64_t addr)
75719 +{
75720 + t_MM *p_MM = (t_MM*)h_MM;
75721 + t_MemBlock *p_MemBlock;
75722 +
75723 + ASSERT_COND(p_MM);
75724 +
75725 + p_MemBlock = p_MM->memBlocks;
75726 +
75727 + if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end))
75728 + return TRUE;
75729 + else
75730 + return FALSE;
75731 +}
75732 +
75733 +/*****************************************************************************/
75734 +uint64_t MM_GetFreeMemSize(t_Handle h_MM)
75735 +{
75736 + t_MM *p_MM = (t_MM*)h_MM;
75737 +
75738 + ASSERT_COND(p_MM);
75739 +
75740 + return p_MM->freeMemSize;
75741 +}
75742 +
75743 +/*****************************************************************************/
75744 +void MM_Dump(t_Handle h_MM)
75745 +{
75746 + t_MM *p_MM = (t_MM *)h_MM;
75747 + t_FreeBlock *p_FreeB;
75748 + t_BusyBlock *p_BusyB;
75749 + int i;
75750 +
75751 + p_BusyB = p_MM->busyBlocks;
75752 + XX_Print("List of busy blocks:\n");
75753 + while (p_BusyB)
75754 + {
75755 + XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end );
75756 + p_BusyB = p_BusyB->p_Next;
75757 + }
75758 +
75759 + XX_Print("\nLists of free blocks according to alignment:\n");
75760 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75761 + {
75762 + XX_Print("%d alignment:\n", (0x1 << i));
75763 + p_FreeB = p_MM->freeBlocks[i];
75764 + while (p_FreeB)
75765 + {
75766 + XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end);
75767 + p_FreeB = p_FreeB->p_Next;
75768 + }
75769 + XX_Print("\n");
75770 + }
75771 +}
75772 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
75773 new file mode 100644
75774 index 00000000..43b2298f
75775 --- /dev/null
75776 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
75777 @@ -0,0 +1,105 @@
75778 +/*
75779 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75780 + *
75781 + * Redistribution and use in source and binary forms, with or without
75782 + * modification, are permitted provided that the following conditions are met:
75783 + * * Redistributions of source code must retain the above copyright
75784 + * notice, this list of conditions and the following disclaimer.
75785 + * * Redistributions in binary form must reproduce the above copyright
75786 + * notice, this list of conditions and the following disclaimer in the
75787 + * documentation and/or other materials provided with the distribution.
75788 + * * Neither the name of Freescale Semiconductor nor the
75789 + * names of its contributors may be used to endorse or promote products
75790 + * derived from this software without specific prior written permission.
75791 + *
75792 + *
75793 + * ALTERNATIVELY, this software may be distributed under the terms of the
75794 + * GNU General Public License ("GPL") as published by the Free Software
75795 + * Foundation, either version 2 of that License or (at your option) any
75796 + * later version.
75797 + *
75798 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75799 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75800 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75801 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75802 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75803 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75804 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75805 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75806 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75807 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75808 + */
75809 +
75810 +
75811 +/****************************************************************
75812 + *
75813 + * File: mm.h
75814 + *
75815 + *
75816 + * Description:
75817 + * MM (Memory Management) object definitions.
75818 + * It also includes definitions of the Free Block, Busy Block
75819 + * and Memory Block structures used by the MM object.
75820 + *
75821 + ****************************************************************/
75822 +
75823 +#ifndef __MM_H
75824 +#define __MM_H
75825 +
75826 +
75827 +#include "mm_ext.h"
75828 +
75829 +#define __ERR_MODULE__ MODULE_MM
75830 +
75831 +
75832 +#define MAKE_ALIGNED(addr, align) \
75833 + (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1)))
75834 +
75835 +
75836 +/* t_MemBlock data structure defines parameters of the Memory Block */
75837 +typedef struct t_MemBlock
75838 +{
75839 + struct t_MemBlock *p_Next; /* Pointer to the next memory block */
75840 +
75841 + uint64_t base; /* Base address of the memory block */
75842 + uint64_t end; /* End address of the memory block */
75843 +} t_MemBlock;
75844 +
75845 +
75846 +/* t_FreeBlock data structure defines parameters of the Free Block */
75847 +typedef struct t_FreeBlock
75848 +{
75849 + struct t_FreeBlock *p_Next; /* Pointer to the next free block */
75850 +
75851 + uint64_t base; /* Base address of the block */
75852 + uint64_t end; /* End address of the block */
75853 +} t_FreeBlock;
75854 +
75855 +
75856 +/* t_BusyBlock data structure defines parameters of the Busy Block */
75857 +typedef struct t_BusyBlock
75858 +{
75859 + struct t_BusyBlock *p_Next; /* Pointer to the next free block */
75860 +
75861 + uint64_t base; /* Base address of the block */
75862 + uint64_t end; /* End address of the block */
75863 + char name[MM_MAX_NAME_LEN]; /* That block of memory was allocated for
75864 + something specified by the Name */
75865 +} t_BusyBlock;
75866 +
75867 +
75868 +/* t_MM data structure defines parameters of the MM object */
75869 +typedef struct t_MM
75870 +{
75871 + t_Handle h_Spinlock;
75872 +
75873 + t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */
75874 + t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */
75875 + t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1];
75876 + /* Alignment lists of free blocks (Free lists) */
75877 +
75878 + uint64_t freeMemSize; /* Total size of free memory (in bytes) */
75879 +} t_MM;
75880 +
75881 +
75882 +#endif /* __MM_H */
75883 diff --git a/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
75884 new file mode 100644
75885 index 00000000..46d2956a
75886 --- /dev/null
75887 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
75888 @@ -0,0 +1,81 @@
75889 +/*
75890 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75891 + *
75892 + * Redistribution and use in source and binary forms, with or without
75893 + * modification, are permitted provided that the following conditions are met:
75894 + * * Redistributions of source code must retain the above copyright
75895 + * notice, this list of conditions and the following disclaimer.
75896 + * * Redistributions in binary form must reproduce the above copyright
75897 + * notice, this list of conditions and the following disclaimer in the
75898 + * documentation and/or other materials provided with the distribution.
75899 + * * Neither the name of Freescale Semiconductor nor the
75900 + * names of its contributors may be used to endorse or promote products
75901 + * derived from this software without specific prior written permission.
75902 + *
75903 + *
75904 + * ALTERNATIVELY, this software may be distributed under the terms of the
75905 + * GNU General Public License ("GPL") as published by the Free Software
75906 + * Foundation, either version 2 of that License or (at your option) any
75907 + * later version.
75908 + *
75909 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75910 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75911 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75912 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75913 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75914 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75915 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75916 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75917 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75918 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75919 + */
75920 +
75921 +
75922 +/*------------------------------------------------------*/
75923 +/* File: sprint.c */
75924 +/* */
75925 +/* Description: */
75926 +/* Debug routines (externals) */
75927 +/*------------------------------------------------------*/
75928 +#include "string_ext.h"
75929 +#include "stdlib_ext.h"
75930 +#include "stdarg_ext.h"
75931 +#include "sprint_ext.h"
75932 +#include "std_ext.h"
75933 +#include "xx_ext.h"
75934 +
75935 +
75936 +int Sprint(char * buf, const char *fmt, ...)
75937 +{
75938 + va_list args;
75939 + int i;
75940 +
75941 + va_start(args, fmt);
75942 + i=vsprintf(buf,fmt,args);
75943 + va_end(args);
75944 + return i;
75945 +}
75946 +
75947 +int Snprint(char * buf, uint32_t size, const char *fmt, ...)
75948 +{
75949 + va_list args;
75950 + int i;
75951 +
75952 + va_start(args, fmt);
75953 + i=vsnprintf(buf,size,fmt,args);
75954 + va_end(args);
75955 + return i;
75956 +}
75957 +
75958 +#ifndef NCSW_VXWORKS
75959 +int Sscan(const char * buf, const char * fmt, ...)
75960 +{
75961 + va_list args;
75962 + int i;
75963 +
75964 + va_start(args,fmt);
75965 + i = vsscanf(buf,fmt,args);
75966 + va_end(args);
75967 + return i;
75968 +}
75969 +#endif /* NCSW_VXWORKS */
75970 diff --git a/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
75971 new file mode 100644
75972 index 00000000..435b0d2b
75973 --- /dev/null
75974 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
75975 @@ -0,0 +1,57 @@
75976 +/*
75977 + * Copyright 2012 Freescale Semiconductor Inc.
75978 + *
75979 + * Redistribution and use in source and binary forms, with or without
75980 + * modification, are permitted provided that the following conditions are met:
75981 + * * Redistributions of source code must retain the above copyright
75982 + * notice, this list of conditions and the following disclaimer.
75983 + * * Redistributions in binary form must reproduce the above copyright
75984 + * notice, this list of conditions and the following disclaimer in the
75985 + * documentation and/or other materials provided with the distribution.
75986 + * * Neither the name of Freescale Semiconductor nor the
75987 + * names of its contributors may be used to endorse or promote products
75988 + * derived from this software without specific prior written permission.
75989 + *
75990 + *
75991 + * ALTERNATIVELY, this software may be distributed under the terms of the
75992 + * GNU General Public License ("GPL") as published by the Free Software
75993 + * Foundation, either version 2 of that License or (at your option) any
75994 + * later version.
75995 + *
75996 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75997 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75998 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75999 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76000 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76001 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76002 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76003 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76004 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76005 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76006 + */
76007 +
76008 +#ifndef __dflags_h
76009 +#define __dflags_h
76010 +
76011 +
76012 +#define NCSW_LINUX
76013 +
76014 +#define T4240
76015 +#define NCSW_PPC_CORE
76016 +
76017 +#define DEBUG_ERRORS 1
76018 +
76019 +#if defined(DEBUG)
76020 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
76021 +
76022 +#define DEBUG_XX_MALLOC
76023 +#define DEBUG_MEM_LEAKS
76024 +
76025 +#else
76026 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
76027 +#endif /* (DEBUG) */
76028 +
76029 +#define REPORT_EVENTS 1
76030 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
76031 +
76032 +#endif /* __dflags_h */
76033 diff --git a/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
76034 new file mode 100644
76035 index 00000000..789eb879
76036 --- /dev/null
76037 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
76038 @@ -0,0 +1,56 @@
76039 +/*
76040 + * Copyright 2012 Freescale Semiconductor Inc.
76041 + *
76042 + * Redistribution and use in source and binary forms, with or without
76043 + * modification, are permitted provided that the following conditions are met:
76044 + * * Redistributions of source code must retain the above copyright
76045 + * notice, this list of conditions and the following disclaimer.
76046 + * * Redistributions in binary form must reproduce the above copyright
76047 + * notice, this list of conditions and the following disclaimer in the
76048 + * documentation and/or other materials provided with the distribution.
76049 + * * Neither the name of Freescale Semiconductor nor the
76050 + * names of its contributors may be used to endorse or promote products
76051 + * derived from this software without specific prior written permission.
76052 + *
76053 + *
76054 + * ALTERNATIVELY, this software may be distributed under the terms of the
76055 + * GNU General Public License ("GPL") as published by the Free Software
76056 + * Foundation, either version 2 of that License or (at your option) any
76057 + * later version.
76058 + *
76059 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76060 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76061 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76062 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76063 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76064 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76065 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76066 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76067 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76068 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76069 + */
76070 +
76071 +#ifndef __dflags_h
76072 +#define __dflags_h
76073 +
76074 +
76075 +#define NCSW_LINUX
76076 +
76077 +#define NCSW_PPC_CORE
76078 +
76079 +#define DEBUG_ERRORS 1
76080 +
76081 +#if defined(DEBUG)
76082 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
76083 +
76084 +#define DEBUG_XX_MALLOC
76085 +#define DEBUG_MEM_LEAKS
76086 +
76087 +#else
76088 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
76089 +#endif /* (DEBUG) */
76090 +
76091 +#define REPORT_EVENTS 1
76092 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
76093 +
76094 +#endif /* __dflags_h */
76095 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
76096 new file mode 100644
76097 index 00000000..a84d5631
76098 --- /dev/null
76099 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
76100 @@ -0,0 +1,364 @@
76101 +/*
76102 + * Copyright 2008-2012 Freescale Semiconductor Inc.
76103 + *
76104 + * Redistribution and use in source and binary forms, with or without
76105 + * modification, are permitted provided that the following conditions are met:
76106 + * * Redistributions of source code must retain the above copyright
76107 + * notice, this list of conditions and the following disclaimer.
76108 + * * Redistributions in binary form must reproduce the above copyright
76109 + * notice, this list of conditions and the following disclaimer in the
76110 + * documentation and/or other materials provided with the distribution.
76111 + * * Neither the name of Freescale Semiconductor nor the
76112 + * names of its contributors may be used to endorse or promote products
76113 + * derived from this software without specific prior written permission.
76114 + *
76115 + *
76116 + * ALTERNATIVELY, this software may be distributed under the terms of the
76117 + * GNU General Public License ("GPL") as published by the Free Software
76118 + * Foundation, either version 2 of that License or (at your option) any
76119 + * later version.
76120 + *
76121 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76122 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76123 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76124 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76125 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76126 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76127 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76128 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76129 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76130 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76131 + */
76132 +
76133 +
76134 +/*------------------------------------------------------*/
76135 +/* */
76136 +/* File: crc_mac_addr_ext.h */
76137 +/* */
76138 +/* Description: */
76139 +/* Define a macro that calculate the crc value of */
76140 +/* an Ethernet MAC address (48 bitd address */
76141 +/*------------------------------------------------------*/
76142 +
76143 +#ifndef __crc_mac_addr_ext_h
76144 +#define __crc_mac_addr_ext_h
76145 +
76146 +#include "std_ext.h"
76147 +
76148 +
76149 +static uint32_t crc_table[256] =
76150 +{
76151 + 0x00000000,
76152 + 0x77073096,
76153 + 0xee0e612c,
76154 + 0x990951ba,
76155 + 0x076dc419,
76156 + 0x706af48f,
76157 + 0xe963a535,
76158 + 0x9e6495a3,
76159 + 0x0edb8832,
76160 + 0x79dcb8a4,
76161 + 0xe0d5e91e,
76162 + 0x97d2d988,
76163 + 0x09b64c2b,
76164 + 0x7eb17cbd,
76165 + 0xe7b82d07,
76166 + 0x90bf1d91,
76167 + 0x1db71064,
76168 + 0x6ab020f2,
76169 + 0xf3b97148,
76170 + 0x84be41de,
76171 + 0x1adad47d,
76172 + 0x6ddde4eb,
76173 + 0xf4d4b551,
76174 + 0x83d385c7,
76175 + 0x136c9856,
76176 + 0x646ba8c0,
76177 + 0xfd62f97a,
76178 + 0x8a65c9ec,
76179 + 0x14015c4f,
76180 + 0x63066cd9,
76181 + 0xfa0f3d63,
76182 + 0x8d080df5,
76183 + 0x3b6e20c8,
76184 + 0x4c69105e,
76185 + 0xd56041e4,
76186 + 0xa2677172,
76187 + 0x3c03e4d1,
76188 + 0x4b04d447,
76189 + 0xd20d85fd,
76190 + 0xa50ab56b,
76191 + 0x35b5a8fa,
76192 + 0x42b2986c,
76193 + 0xdbbbc9d6,
76194 + 0xacbcf940,
76195 + 0x32d86ce3,
76196 + 0x45df5c75,
76197 + 0xdcd60dcf,
76198 + 0xabd13d59,
76199 + 0x26d930ac,
76200 + 0x51de003a,
76201 + 0xc8d75180,
76202 + 0xbfd06116,
76203 + 0x21b4f4b5,
76204 + 0x56b3c423,
76205 + 0xcfba9599,
76206 + 0xb8bda50f,
76207 + 0x2802b89e,
76208 + 0x5f058808,
76209 + 0xc60cd9b2,
76210 + 0xb10be924,
76211 + 0x2f6f7c87,
76212 + 0x58684c11,
76213 + 0xc1611dab,
76214 + 0xb6662d3d,
76215 + 0x76dc4190,
76216 + 0x01db7106,
76217 + 0x98d220bc,
76218 + 0xefd5102a,
76219 + 0x71b18589,
76220 + 0x06b6b51f,
76221 + 0x9fbfe4a5,
76222 + 0xe8b8d433,
76223 + 0x7807c9a2,
76224 + 0x0f00f934,
76225 + 0x9609a88e,
76226 + 0xe10e9818,
76227 + 0x7f6a0dbb,
76228 + 0x086d3d2d,
76229 + 0x91646c97,
76230 + 0xe6635c01,
76231 + 0x6b6b51f4,
76232 + 0x1c6c6162,
76233 + 0x856530d8,
76234 + 0xf262004e,
76235 + 0x6c0695ed,
76236 + 0x1b01a57b,
76237 + 0x8208f4c1,
76238 + 0xf50fc457,
76239 + 0x65b0d9c6,
76240 + 0x12b7e950,
76241 + 0x8bbeb8ea,
76242 + 0xfcb9887c,
76243 + 0x62dd1ddf,
76244 + 0x15da2d49,
76245 + 0x8cd37cf3,
76246 + 0xfbd44c65,
76247 + 0x4db26158,
76248 + 0x3ab551ce,
76249 + 0xa3bc0074,
76250 + 0xd4bb30e2,
76251 + 0x4adfa541,
76252 + 0x3dd895d7,
76253 + 0xa4d1c46d,
76254 + 0xd3d6f4fb,
76255 + 0x4369e96a,
76256 + 0x346ed9fc,
76257 + 0xad678846,
76258 + 0xda60b8d0,
76259 + 0x44042d73,
76260 + 0x33031de5,
76261 + 0xaa0a4c5f,
76262 + 0xdd0d7cc9,
76263 + 0x5005713c,
76264 + 0x270241aa,
76265 + 0xbe0b1010,
76266 + 0xc90c2086,
76267 + 0x5768b525,
76268 + 0x206f85b3,
76269 + 0xb966d409,
76270 + 0xce61e49f,
76271 + 0x5edef90e,
76272 + 0x29d9c998,
76273 + 0xb0d09822,
76274 + 0xc7d7a8b4,
76275 + 0x59b33d17,
76276 + 0x2eb40d81,
76277 + 0xb7bd5c3b,
76278 + 0xc0ba6cad,
76279 + 0xedb88320,
76280 + 0x9abfb3b6,
76281 + 0x03b6e20c,
76282 + 0x74b1d29a,
76283 + 0xead54739,
76284 + 0x9dd277af,
76285 + 0x04db2615,
76286 + 0x73dc1683,
76287 + 0xe3630b12,
76288 + 0x94643b84,
76289 + 0x0d6d6a3e,
76290 + 0x7a6a5aa8,
76291 + 0xe40ecf0b,
76292 + 0x9309ff9d,
76293 + 0x0a00ae27,
76294 + 0x7d079eb1,
76295 + 0xf00f9344,
76296 + 0x8708a3d2,
76297 + 0x1e01f268,
76298 + 0x6906c2fe,
76299 + 0xf762575d,
76300 + 0x806567cb,
76301 + 0x196c3671,
76302 + 0x6e6b06e7,
76303 + 0xfed41b76,
76304 + 0x89d32be0,
76305 + 0x10da7a5a,
76306 + 0x67dd4acc,
76307 + 0xf9b9df6f,
76308 + 0x8ebeeff9,
76309 + 0x17b7be43,
76310 + 0x60b08ed5,
76311 + 0xd6d6a3e8,
76312 + 0xa1d1937e,
76313 + 0x38d8c2c4,
76314 + 0x4fdff252,
76315 + 0xd1bb67f1,
76316 + 0xa6bc5767,
76317 + 0x3fb506dd,
76318 + 0x48b2364b,
76319 + 0xd80d2bda,
76320 + 0xaf0a1b4c,
76321 + 0x36034af6,
76322 + 0x41047a60,
76323 + 0xdf60efc3,
76324 + 0xa867df55,
76325 + 0x316e8eef,
76326 + 0x4669be79,
76327 + 0xcb61b38c,
76328 + 0xbc66831a,
76329 + 0x256fd2a0,
76330 + 0x5268e236,
76331 + 0xcc0c7795,
76332 + 0xbb0b4703,
76333 + 0x220216b9,
76334 + 0x5505262f,
76335 + 0xc5ba3bbe,
76336 + 0xb2bd0b28,
76337 + 0x2bb45a92,
76338 + 0x5cb36a04,
76339 + 0xc2d7ffa7,
76340 + 0xb5d0cf31,
76341 + 0x2cd99e8b,
76342 + 0x5bdeae1d,
76343 + 0x9b64c2b0,
76344 + 0xec63f226,
76345 + 0x756aa39c,
76346 + 0x026d930a,
76347 + 0x9c0906a9,
76348 + 0xeb0e363f,
76349 + 0x72076785,
76350 + 0x05005713,
76351 + 0x95bf4a82,
76352 + 0xe2b87a14,
76353 + 0x7bb12bae,
76354 + 0x0cb61b38,
76355 + 0x92d28e9b,
76356 + 0xe5d5be0d,
76357 + 0x7cdcefb7,
76358 + 0x0bdbdf21,
76359 + 0x86d3d2d4,
76360 + 0xf1d4e242,
76361 + 0x68ddb3f8,
76362 + 0x1fda836e,
76363 + 0x81be16cd,
76364 + 0xf6b9265b,
76365 + 0x6fb077e1,
76366 + 0x18b74777,
76367 + 0x88085ae6,
76368 + 0xff0f6a70,
76369 + 0x66063bca,
76370 + 0x11010b5c,
76371 + 0x8f659eff,
76372 + 0xf862ae69,
76373 + 0x616bffd3,
76374 + 0x166ccf45,
76375 + 0xa00ae278,
76376 + 0xd70dd2ee,
76377 + 0x4e048354,
76378 + 0x3903b3c2,
76379 + 0xa7672661,
76380 + 0xd06016f7,
76381 + 0x4969474d,
76382 + 0x3e6e77db,
76383 + 0xaed16a4a,
76384 + 0xd9d65adc,
76385 + 0x40df0b66,
76386 + 0x37d83bf0,
76387 + 0xa9bcae53,
76388 + 0xdebb9ec5,
76389 + 0x47b2cf7f,
76390 + 0x30b5ffe9,
76391 + 0xbdbdf21c,
76392 + 0xcabac28a,
76393 + 0x53b39330,
76394 + 0x24b4a3a6,
76395 + 0xbad03605,
76396 + 0xcdd70693,
76397 + 0x54de5729,
76398 + 0x23d967bf,
76399 + 0xb3667a2e,
76400 + 0xc4614ab8,
76401 + 0x5d681b02,
76402 + 0x2a6f2b94,
76403 + 0xb40bbe37,
76404 + 0xc30c8ea1,
76405 + 0x5a05df1b,
76406 + 0x2d02ef8d
76407 +};
76408 +
76409 +
76410 +#define GET_MAC_ADDR_CRC(addr, crc) \
76411 +{ \
76412 + uint32_t i; \
76413 + uint8_t data; \
76414 + \
76415 + /* CRC calculation */ \
76416 + crc = 0xffffffff; \
76417 + for (i=0; i < 6; i++) \
76418 + { \
76419 + data = (uint8_t)(addr >> ((5-i)*8)); \
76420 + crc = crc^data; \
76421 + crc = crc_table[crc&0xff] ^ (crc>>8); \
76422 + } \
76423 +} \
76424 +
76425 +/* Define a macro for getting the mirrored value of */
76426 +/* a byte size number. (0x11010011 --> 0x11001011) */
76427 +/* Sometimes the mirrored value of the CRC is required */
76428 +static __inline__ uint8_t GetMirror(uint8_t n)
76429 +{
76430 + uint8_t mirror[16] =
76431 + {
76432 + 0x00,
76433 + 0x08,
76434 + 0x04,
76435 + 0x0c,
76436 + 0x02,
76437 + 0x0a,
76438 + 0x06,
76439 + 0x0e,
76440 + 0x01,
76441 + 0x09,
76442 + 0x05,
76443 + 0x0d,
76444 + 0x03,
76445 + 0x0b,
76446 + 0x07,
76447 + 0x0f
76448 + };
76449 + return ((uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))));
76450 +}
76451 +
76452 +static __inline__ uint32_t GetMirror32(uint32_t n)
76453 +{
76454 + return (((uint32_t)GetMirror((uint8_t)(n))<<24) |
76455 + ((uint32_t)GetMirror((uint8_t)(n>>8))<<16) |
76456 + ((uint32_t)GetMirror((uint8_t)(n>>16))<<8) |
76457 + ((uint32_t)GetMirror((uint8_t)(n>>24))));
76458 +}
76459 +
76460 +#define MIRROR GetMirror
76461 +#define MIRROR_32 GetMirror32
76462 +
76463 +
76464 +#endif /* __crc_mac_addr_ext_h */
76465 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
76466 new file mode 100644
76467 index 00000000..e6d9e932
76468 --- /dev/null
76469 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
76470 @@ -0,0 +1,210 @@
76471 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76472 + * All rights reserved.
76473 + *
76474 + * Redistribution and use in source and binary forms, with or without
76475 + * modification, are permitted provided that the following conditions are met:
76476 + * * Redistributions of source code must retain the above copyright
76477 + * notice, this list of conditions and the following disclaimer.
76478 + * * Redistributions in binary form must reproduce the above copyright
76479 + * notice, this list of conditions and the following disclaimer in the
76480 + * documentation and/or other materials provided with the distribution.
76481 + * * Neither the name of Freescale Semiconductor nor the
76482 + * names of its contributors may be used to endorse or promote products
76483 + * derived from this software without specific prior written permission.
76484 + *
76485 + *
76486 + * ALTERNATIVELY, this software may be distributed under the terms of the
76487 + * GNU General Public License ("GPL") as published by the Free Software
76488 + * Foundation, either version 2 of that License or (at your option) any
76489 + * later version.
76490 + *
76491 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76492 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76493 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76494 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76495 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76496 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76497 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76498 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76499 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76500 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76501 + */
76502 +
76503 +
76504 +/**************************************************************************//**
76505 + @File dpaa_ext.h
76506 +
76507 + @Description DPAA Application Programming Interface.
76508 +*//***************************************************************************/
76509 +#ifndef __DPAA_EXT_H
76510 +#define __DPAA_EXT_H
76511 +
76512 +#include "std_ext.h"
76513 +#include "error_ext.h"
76514 +
76515 +
76516 +/**************************************************************************//**
76517 + @Group DPAA_grp Data Path Acceleration Architecture API
76518 +
76519 + @Description DPAA API functions, definitions and enums.
76520 +
76521 + @{
76522 +*//***************************************************************************/
76523 +
76524 +#if defined(__MWERKS__) && !defined(__GNUC__)
76525 +#pragma pack(push,1)
76526 +#endif /* defined(__MWERKS__) && ... */
76527 +
76528 +/**************************************************************************//**
76529 + @Description Frame descriptor
76530 +*//***************************************************************************/
76531 +typedef _Packed struct t_DpaaFD {
76532 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
76533 + volatile uint8_t liodn;
76534 + volatile uint8_t bpid;
76535 + volatile uint8_t elion;
76536 + volatile uint8_t addrh;
76537 + volatile uint32_t addrl;
76538 +#else
76539 + volatile uint32_t addrl;
76540 + volatile uint8_t addrh;
76541 + volatile uint8_t elion;
76542 + volatile uint8_t bpid;
76543 + volatile uint8_t liodn;
76544 + #endif
76545 + volatile uint32_t length; /**< Frame length */
76546 + volatile uint32_t status; /**< FD status */
76547 +} _PackedType t_DpaaFD;
76548 +
76549 +/**************************************************************************//**
76550 + @Description enum for defining frame format
76551 +*//***************************************************************************/
76552 +typedef enum e_DpaaFDFormatType {
76553 + e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF = 0x0, /**< Simple frame Single buffer; Offset and
76554 + small length (9b OFFSET, 20b LENGTH) */
76555 + e_DPAA_FD_FORMAT_TYPE_LONG_SBSF = 0x2, /**< Simple frame, single buffer; big length
76556 + (29b LENGTH ,No OFFSET) */
76557 + e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF = 0x4, /**< Simple frame, Scatter Gather table; Offset
76558 + and small length (9b OFFSET, 20b LENGTH) */
76559 + e_DPAA_FD_FORMAT_TYPE_LONG_MBSF = 0x6, /**< Simple frame, Scatter Gather table;
76560 + big length (29b LENGTH ,No OFFSET) */
76561 + e_DPAA_FD_FORMAT_TYPE_COMPOUND = 0x1, /**< Compound Frame (29b CONGESTION-WEIGHT
76562 + No LENGTH or OFFSET) */
76563 + e_DPAA_FD_FORMAT_TYPE_DUMMY
76564 +} e_DpaaFDFormatType;
76565 +
76566 +/**************************************************************************//**
76567 + @Collection Frame descriptor macros
76568 +*//***************************************************************************/
76569 +#define DPAA_FD_DD_MASK 0xc0000000 /**< FD DD field mask */
76570 +#define DPAA_FD_PID_MASK 0x3f000000 /**< FD PID field mask */
76571 +#define DPAA_FD_ELIODN_MASK 0x0000f000 /**< FD ELIODN field mask */
76572 +#define DPAA_FD_BPID_MASK 0x00ff0000 /**< FD BPID field mask */
76573 +#define DPAA_FD_ADDRH_MASK 0x000000ff /**< FD ADDRH field mask */
76574 +#define DPAA_FD_ADDRL_MASK 0xffffffff /**< FD ADDRL field mask */
76575 +#define DPAA_FD_FORMAT_MASK 0xe0000000 /**< FD FORMAT field mask */
76576 +#define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */
76577 +#define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */
76578 +
76579 +#define DPAA_FD_GET_ADDRH(fd) ((t_DpaaFD *)fd)->addrh /**< Macro to get FD ADDRH field */
76580 +#define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */
76581 +#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 */
76582 +#define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */
76583 +#define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */
76584 +#define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */
76585 +#define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */
76586 +#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) /**< Macro to get FD ADDR (virtual) */
76587 +
76588 +#define DPAA_FD_SET_ADDRH(fd,val) ((t_DpaaFD *)fd)->addrh = (val) /**< Macro to set FD ADDRH field */
76589 +#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */
76590 +#define DPAA_FD_SET_ADDR(fd,val) \
76591 +do { \
76592 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76593 + DPAA_FD_SET_ADDRH(fd, ((uint32_t)(physAddr >> 32))); \
76594 + DPAA_FD_SET_ADDRL(fd, (uint32_t)physAddr); \
76595 +} while (0) /**< Macro to set FD ADDR field */
76596 +#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 */
76597 +#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 */
76598 +#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 */
76599 +#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */
76600 +/* @} */
76601 +
76602 +/**************************************************************************//**
76603 + @Description Frame Scatter/Gather Table Entry
76604 +*//***************************************************************************/
76605 +typedef _Packed struct t_DpaaSGTE {
76606 + volatile uint32_t addrh; /**< Buffer Address high */
76607 + volatile uint32_t addrl; /**< Buffer Address low */
76608 + volatile uint32_t length; /**< Buffer length */
76609 + volatile uint32_t offset; /**< SGTE offset */
76610 +} _PackedType t_DpaaSGTE;
76611 +
76612 +#define DPAA_NUM_OF_SG_TABLE_ENTRY 16
76613 +
76614 +/**************************************************************************//**
76615 + @Description Frame Scatter/Gather Table
76616 +*//***************************************************************************/
76617 +typedef _Packed struct t_DpaaSGT {
76618 + t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY];
76619 + /**< Structure that holds information about
76620 + a single S/G entry. */
76621 +} _PackedType t_DpaaSGT;
76622 +
76623 +/**************************************************************************//**
76624 + @Description Compound Frame Table
76625 +*//***************************************************************************/
76626 +typedef _Packed struct t_DpaaCompTbl {
76627 + t_DpaaSGTE outputBuffInfo; /**< Structure that holds information about
76628 + the compound-frame output buffer;
76629 + NOTE: this may point to a S/G table */
76630 + t_DpaaSGTE inputBuffInfo; /**< Structure that holds information about
76631 + the compound-frame input buffer;
76632 + NOTE: this may point to a S/G table */
76633 +} _PackedType t_DpaaCompTbl;
76634 +
76635 +/**************************************************************************//**
76636 + @Collection Frame Scatter/Gather Table Entry macros
76637 +*//***************************************************************************/
76638 +#define DPAA_SGTE_ADDRH_MASK 0x000000ff /**< SGTE ADDRH field mask */
76639 +#define DPAA_SGTE_ADDRL_MASK 0xffffffff /**< SGTE ADDRL field mask */
76640 +#define DPAA_SGTE_E_MASK 0x80000000 /**< SGTE Extension field mask */
76641 +#define DPAA_SGTE_F_MASK 0x40000000 /**< SGTE Final field mask */
76642 +#define DPAA_SGTE_LENGTH_MASK 0x3fffffff /**< SGTE LENGTH field mask */
76643 +#define DPAA_SGTE_BPID_MASK 0x00ff0000 /**< SGTE BPID field mask */
76644 +#define DPAA_SGTE_OFFSET_MASK 0x00001fff /**< SGTE OFFSET field mask */
76645 +
76646 +#define DPAA_SGTE_GET_ADDRH(sgte) (((t_DpaaSGTE *)sgte)->addrh & DPAA_SGTE_ADDRH_MASK) /**< Macro to get SGTE ADDRH field */
76647 +#define DPAA_SGTE_GET_ADDRL(sgte) ((t_DpaaSGTE *)sgte)->addrl /**< Macro to get SGTE ADDRL field */
76648 +#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 */
76649 +#define DPAA_SGTE_GET_EXTENSION(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_E_MASK) >> (31-0)) /**< Macro to get SGTE EXTENSION field */
76650 +#define DPAA_SGTE_GET_FINAL(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_F_MASK) >> (31-1)) /**< Macro to get SGTE FINAL field */
76651 +#define DPAA_SGTE_GET_LENGTH(sgte) (((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_LENGTH_MASK) /**< Macro to get SGTE LENGTH field */
76652 +#define DPAA_SGTE_GET_BPID(sgte) ((((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_BPID_MASK) >> (31-15)) /**< Macro to get SGTE BPID field */
76653 +#define DPAA_SGTE_GET_OFFSET(sgte) (((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_OFFSET_MASK) /**< Macro to get SGTE OFFSET field */
76654 +#define DPAA_SGTE_GET_ADDR(sgte) XX_PhysToVirt(DPAA_SGTE_GET_PHYS_ADDR(sgte))
76655 +
76656 +#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 */
76657 +#define DPAA_SGTE_SET_ADDRL(sgte,val) ((t_DpaaSGTE *)sgte)->addrl = (val) /**< Macro to set SGTE ADDRL field */
76658 +#define DPAA_SGTE_SET_ADDR(sgte,val) \
76659 +do { \
76660 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76661 + DPAA_SGTE_SET_ADDRH(sgte, ((uint32_t)(physAddr >> 32))); \
76662 + DPAA_SGTE_SET_ADDRL(sgte, (uint32_t)physAddr); \
76663 +} while (0) /**< Macro to set SGTE ADDR field */
76664 +#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 */
76665 +#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 */
76666 +#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 */
76667 +#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 */
76668 +#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 */
76669 +/* @} */
76670 +
76671 +#if defined(__MWERKS__) && !defined(__GNUC__)
76672 +#pragma pack(pop)
76673 +#endif /* defined(__MWERKS__) && ... */
76674 +
76675 +#define DPAA_LIODN_DONT_OVERRIDE (-1)
76676 +
76677 +/** @} */ /* end of DPAA_grp group */
76678 +
76679 +
76680 +#endif /* __DPAA_EXT_H */
76681 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
76682 new file mode 100644
76683 index 00000000..a8a64386
76684 --- /dev/null
76685 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
76686 @@ -0,0 +1,1731 @@
76687 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76688 + * All rights reserved.
76689 + *
76690 + * Redistribution and use in source and binary forms, with or without
76691 + * modification, are permitted provided that the following conditions are met:
76692 + * * Redistributions of source code must retain the above copyright
76693 + * notice, this list of conditions and the following disclaimer.
76694 + * * Redistributions in binary form must reproduce the above copyright
76695 + * notice, this list of conditions and the following disclaimer in the
76696 + * documentation and/or other materials provided with the distribution.
76697 + * * Neither the name of Freescale Semiconductor nor the
76698 + * names of its contributors may be used to endorse or promote products
76699 + * derived from this software without specific prior written permission.
76700 + *
76701 + *
76702 + * ALTERNATIVELY, this software may be distributed under the terms of the
76703 + * GNU General Public License ("GPL") as published by the Free Software
76704 + * Foundation, either version 2 of that License or (at your option) any
76705 + * later version.
76706 + *
76707 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76708 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76709 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76710 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76711 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76712 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76713 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76714 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76715 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76716 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76717 + */
76718 +
76719 +
76720 +/**************************************************************************//**
76721 + @File fm_ext.h
76722 +
76723 + @Description FM Application Programming Interface.
76724 +*//***************************************************************************/
76725 +#ifndef __FM_EXT
76726 +#define __FM_EXT
76727 +
76728 +#include "error_ext.h"
76729 +#include "std_ext.h"
76730 +#include "dpaa_ext.h"
76731 +#include "fsl_fman_sp.h"
76732 +
76733 +/**************************************************************************//**
76734 + @Group FM_grp Frame Manager API
76735 +
76736 + @Description FM API functions, definitions and enums.
76737 +
76738 + @{
76739 +*//***************************************************************************/
76740 +
76741 +/**************************************************************************//**
76742 + @Group FM_lib_grp FM library
76743 +
76744 + @Description FM API functions, definitions and enums.
76745 +
76746 + The FM module is the main driver module and is a mandatory module
76747 + for FM driver users. This module must be initialized first prior
76748 + to any other drivers modules.
76749 + The FM is a "singleton" module. It is responsible of the common
76750 + HW modules: FPM, DMA, common QMI and common BMI initializations and
76751 + run-time control routines. This module must be initialized always
76752 + when working with any of the FM modules.
76753 + NOTE - We assume that the FM library will be initialized only by core No. 0!
76754 +
76755 + @{
76756 +*//***************************************************************************/
76757 +
76758 +/**************************************************************************//**
76759 + @Description Enum for defining port types
76760 +*//***************************************************************************/
76761 +typedef enum e_FmPortType {
76762 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
76763 + e_FM_PORT_TYPE_RX, /**< 1G Rx port */
76764 + e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
76765 + e_FM_PORT_TYPE_TX, /**< 1G Tx port */
76766 + e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
76767 + e_FM_PORT_TYPE_DUMMY
76768 +} e_FmPortType;
76769 +
76770 +/**************************************************************************//**
76771 + @Collection General FM defines
76772 +*//***************************************************************************/
76773 +#define FM_MAX_NUM_OF_PARTITIONS 64 /**< Maximum number of partitions */
76774 +#define FM_PHYS_ADDRESS_SIZE 6 /**< FM Physical address size */
76775 +/* @} */
76776 +
76777 +
76778 +#if defined(__MWERKS__) && !defined(__GNUC__)
76779 +#pragma pack(push,1)
76780 +#endif /* defined(__MWERKS__) && ... */
76781 +
76782 +/**************************************************************************//**
76783 + @Description FM physical Address
76784 +*//***************************************************************************/
76785 +typedef _Packed struct t_FmPhysAddr {
76786 + volatile uint8_t high; /**< High part of the physical address */
76787 + volatile uint32_t low; /**< Low part of the physical address */
76788 +} _PackedType t_FmPhysAddr;
76789 +
76790 +/**************************************************************************//**
76791 + @Description Parse results memory layout
76792 +*//***************************************************************************/
76793 +typedef _Packed struct t_FmPrsResult {
76794 + volatile uint8_t lpid; /**< Logical port id */
76795 + volatile uint8_t shimr; /**< Shim header result */
76796 + volatile uint16_t l2r; /**< Layer 2 result */
76797 + volatile uint16_t l3r; /**< Layer 3 result */
76798 + volatile uint8_t l4r; /**< Layer 4 result */
76799 + volatile uint8_t cplan; /**< Classification plan id */
76800 + volatile uint16_t nxthdr; /**< Next Header */
76801 + volatile uint16_t cksum; /**< Running-sum */
76802 + volatile uint16_t flags_frag_off; /**< Flags & fragment-offset field of the last IP-header */
76803 + volatile uint8_t route_type; /**< Routing type field of a IPv6 routing extension header */
76804 + volatile uint8_t rhp_ip_valid; /**< Routing Extension Header Present; last bit is IP valid */
76805 + volatile uint8_t shim_off[2]; /**< Shim offset */
76806 + volatile uint8_t ip_pid_off; /**< IP PID (last IP-proto) offset */
76807 + volatile uint8_t eth_off; /**< ETH offset */
76808 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
76809 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
76810 + volatile uint8_t etype_off; /**< ETYPE offset */
76811 + volatile uint8_t pppoe_off; /**< PPP offset */
76812 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
76813 + volatile uint8_t ip_off[2]; /**< IP offset */
76814 + volatile uint8_t gre_off; /**< GRE offset */
76815 + volatile uint8_t l4_off; /**< Layer 4 offset */
76816 + volatile uint8_t nxthdr_off; /**< Parser end point */
76817 +} _PackedType t_FmPrsResult;
76818 +
76819 +/**************************************************************************//**
76820 + @Collection FM Parser results
76821 +*//***************************************************************************/
76822 +#define FM_PR_L2_VLAN_STACK 0x00000100 /**< Parse Result: VLAN stack */
76823 +#define FM_PR_L2_ETHERNET 0x00008000 /**< Parse Result: Ethernet*/
76824 +#define FM_PR_L2_VLAN 0x00004000 /**< Parse Result: VLAN */
76825 +#define FM_PR_L2_LLC_SNAP 0x00002000 /**< Parse Result: LLC_SNAP */
76826 +#define FM_PR_L2_MPLS 0x00001000 /**< Parse Result: MPLS */
76827 +#define FM_PR_L2_PPPoE 0x00000800 /**< Parse Result: PPPoE */
76828 +/* @} */
76829 +
76830 +/**************************************************************************//**
76831 + @Collection FM Frame descriptor macros
76832 +*//***************************************************************************/
76833 +#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */
76834 +#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */
76835 +#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */
76836 +#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */
76837 +#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */
76838 +#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */
76839 +
76840 +#define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Not for Rx-Port! Unsupported Format */
76841 +#define FM_FD_ERR_LENGTH 0x02000000 /**< Not for Rx-Port! Length Error */
76842 +#define FM_FD_ERR_DMA 0x01000000 /**< DMA Data error */
76843 +
76844 +#define FM_FD_IPR 0x00000001 /**< IPR frame (not error) */
76845 +
76846 +#define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) /**< IPR non-consistent-sp */
76847 +#define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) /**< IPR error */
76848 +#define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) /**< IPR timeout */
76849 +
76850 +#ifdef FM_CAPWAP_SUPPORT
76851 +#define FM_FD_ERR_CRE 0x00200000
76852 +#define FM_FD_ERR_CHE 0x00100000
76853 +#endif /* FM_CAPWAP_SUPPORT */
76854 +
76855 +#define FM_FD_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity
76856 + error (SGMII and TBI modes), FIFO parity error. PHY
76857 + Sequence error, PHY error control character detected. */
76858 +#define FM_FD_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */
76859 +#define FM_FD_ERR_CLS_DISCARD 0x00020000 /**< classification discard */
76860 +#define FM_FD_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */
76861 +#define FM_FD_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */
76862 +#define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */
76863 +#define FM_FD_ERR_COLOR_RED 0x00000800 /**< Frame color is red */
76864 +#define FM_FD_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */
76865 +#define FM_FD_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */
76866 +#define FM_FD_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */
76867 +#define FM_FD_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */
76868 +#define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */
76869 +#define FM_FD_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */
76870 +#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */
76871 +
76872 +#define FM_FD_TX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76873 + FM_FD_ERR_LENGTH | \
76874 + FM_FD_ERR_DMA) /**< TX Error FD bits */
76875 +
76876 +#define FM_FD_RX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76877 + FM_FD_ERR_LENGTH | \
76878 + FM_FD_ERR_DMA | \
76879 + FM_FD_ERR_IPR | \
76880 + FM_FD_ERR_IPR_TO | \
76881 + FM_FD_ERR_IPR_NCSP | \
76882 + FM_FD_ERR_PHYSICAL | \
76883 + FM_FD_ERR_SIZE | \
76884 + FM_FD_ERR_CLS_DISCARD | \
76885 + FM_FD_ERR_COLOR_RED | \
76886 + FM_FD_ERR_COLOR_YELLOW | \
76887 + FM_FD_ERR_ILL_PLCR | \
76888 + FM_FD_ERR_PLCR_FRAME_LEN | \
76889 + FM_FD_ERR_EXTRACTION | \
76890 + FM_FD_ERR_NO_SCHEME | \
76891 + FM_FD_ERR_KEYSIZE_OVERFLOW | \
76892 + FM_FD_ERR_PRS_TIMEOUT | \
76893 + FM_FD_ERR_PRS_ILL_INSTRUCT | \
76894 + FM_FD_ERR_PRS_HDR_ERR | \
76895 + FM_FD_ERR_BLOCK_LIMIT_EXCEEDED) /**< RX Error FD bits */
76896 +
76897 +#define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 /**< non Frame-Manager error */
76898 +/* @} */
76899 +
76900 +/**************************************************************************//**
76901 + @Description Context A
76902 +*//***************************************************************************/
76903 +typedef _Packed struct t_FmContextA {
76904 + volatile uint32_t command; /**< ContextA Command */
76905 + volatile uint8_t res0[4]; /**< ContextA Reserved bits */
76906 +} _PackedType t_FmContextA;
76907 +
76908 +/**************************************************************************//**
76909 + @Description Context B
76910 +*//***************************************************************************/
76911 +typedef uint32_t t_FmContextB;
76912 +
76913 +/**************************************************************************//**
76914 + @Collection Special Operation options
76915 +*//***************************************************************************/
76916 +typedef uint32_t fmSpecialOperations_t; /**< typedef for defining Special Operation options */
76917 +
76918 +#define FM_SP_OP_IPSEC 0x80000000 /**< activate features that related to IPSec (e.g fix Eth-type) */
76919 +#define FM_SP_OP_IPSEC_UPDATE_UDP_LEN 0x40000000 /**< update the UDP-Len after Encryption */
76920 +#define FM_SP_OP_IPSEC_MANIP 0x20000000 /**< handle the IPSec-manip options */
76921 +#define FM_SP_OP_RPD 0x10000000 /**< Set the RPD bit */
76922 +#define FM_SP_OP_DCL4C 0x08000000 /**< Set the DCL4C bit */
76923 +#define FM_SP_OP_CHECK_SEC_ERRORS 0x04000000 /**< Check SEC errors */
76924 +#define FM_SP_OP_CLEAR_RPD 0x02000000 /**< Clear the RPD bit */
76925 +#define FM_SP_OP_CAPWAP_DTLS_ENC 0x01000000 /**< activate features that related to CAPWAP-DTLS post Encryption */
76926 +#define FM_SP_OP_CAPWAP_DTLS_DEC 0x00800000 /**< activate features that related to CAPWAP-DTLS post Decryption */
76927 +#define FM_SP_OP_IPSEC_NO_ETH_HDR 0x00400000 /**< activate features that related to IPSec without Eth hdr */
76928 +/* @} */
76929 +
76930 +/**************************************************************************//**
76931 + @Collection Context A macros
76932 +*//***************************************************************************/
76933 +#define FM_CONTEXTA_OVERRIDE_MASK 0x80000000
76934 +#define FM_CONTEXTA_ICMD_MASK 0x40000000
76935 +#define FM_CONTEXTA_A1_VALID_MASK 0x20000000
76936 +#define FM_CONTEXTA_MACCMD_MASK 0x00ff0000
76937 +#define FM_CONTEXTA_MACCMD_VALID_MASK 0x00800000
76938 +#define FM_CONTEXTA_MACCMD_SECURED_MASK 0x00100000
76939 +#define FM_CONTEXTA_MACCMD_SC_MASK 0x000f0000
76940 +#define FM_CONTEXTA_A1_MASK 0x0000ffff
76941 +
76942 +#define FM_CONTEXTA_GET_OVERRIDE(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_OVERRIDE_MASK) >> (31-0))
76943 +#define FM_CONTEXTA_GET_ICMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_ICMD_MASK) >> (31-1))
76944 +#define FM_CONTEXTA_GET_A1_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_VALID_MASK) >> (31-2))
76945 +#define FM_CONTEXTA_GET_A1(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_MASK) >> (31-31))
76946 +#define FM_CONTEXTA_GET_MACCMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_MASK) >> (31-15))
76947 +#define FM_CONTEXTA_GET_MACCMD_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_VALID_MASK) >> (31-8))
76948 +#define FM_CONTEXTA_GET_MACCMD_SECURED(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SECURED_MASK) >> (31-11))
76949 +#define FM_CONTEXTA_GET_MACCMD_SECURE_CHANNEL(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SC_MASK) >> (31-15))
76950 +
76951 +#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) ))
76952 +#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) ))
76953 +#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) ))
76954 +#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) ))
76955 +#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) ))
76956 +#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) ))
76957 +#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) ))
76958 +#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) ))
76959 +/* @} */
76960 +
76961 +/**************************************************************************//**
76962 + @Collection Context B macros
76963 +*//***************************************************************************/
76964 +#define FM_CONTEXTB_FQID_MASK 0x00ffffff
76965 +
76966 +#define FM_CONTEXTB_GET_FQID(contextB) (*((t_FmContextB *)contextB) & FM_CONTEXTB_FQID_MASK)
76967 +#define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK)))
76968 +/* @} */
76969 +
76970 +#if defined(__MWERKS__) && !defined(__GNUC__)
76971 +#pragma pack(pop)
76972 +#endif /* defined(__MWERKS__) && ... */
76973 +
76974 +
76975 +/**************************************************************************//**
76976 + @Description FM Exceptions
76977 +*//***************************************************************************/
76978 +typedef enum e_FmExceptions {
76979 + e_FM_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
76980 + e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
76981 + e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
76982 + e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
76983 + e_FM_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
76984 + e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
76985 + e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
76986 + e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
76987 + e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
76988 + e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
76989 + e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
76990 + e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
76991 + e_FM_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
76992 + e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
76993 + e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
76994 + e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
76995 + e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
76996 +} e_FmExceptions;
76997 +
76998 +/**************************************************************************//**
76999 + @Description Enum for defining port DMA swap mode
77000 +*//***************************************************************************/
77001 +typedef enum e_FmDmaSwapOption {
77002 + e_FM_DMA_NO_SWP = FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
77003 + e_FM_DMA_SWP_PPC_LE = FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
77004 + in PowerPc Little Endian mode. */
77005 + e_FM_DMA_SWP_BE = FMAN_DMA_SWP_BE /**< The transferred data should be swapped
77006 + in Big Endian mode */
77007 +} e_FmDmaSwapOption;
77008 +
77009 +/**************************************************************************//**
77010 + @Description Enum for defining port DMA cache attributes
77011 +*//***************************************************************************/
77012 +typedef enum e_FmDmaCacheOption {
77013 + e_FM_DMA_NO_STASH = FMAN_DMA_NO_STASH, /**< Cacheable, no Allocate (No Stashing) */
77014 + e_FM_DMA_STASH = FMAN_DMA_STASH /**< Cacheable and Allocate (Stashing on) */
77015 +} e_FmDmaCacheOption;
77016 +
77017 +
77018 +/**************************************************************************//**
77019 + @Group FM_init_grp FM Initialization Unit
77020 +
77021 + @Description FM Initialization Unit
77022 +
77023 + Initialization Flow
77024 + Initialization of the FM Module will be carried out by the application
77025 + according to the following sequence:
77026 + - Calling the configuration routine with basic parameters.
77027 + - Calling the advance initialization routines to change driver's defaults.
77028 + - Calling the initialization routine.
77029 +
77030 + @{
77031 +*//***************************************************************************/
77032 +
77033 +/**************************************************************************//**
77034 + @Function t_FmExceptionsCallback
77035 +
77036 + @Description Exceptions user callback routine, will be called upon an
77037 + exception passing the exception identification.
77038 +
77039 + @Param[in] h_App - User's application descriptor.
77040 + @Param[in] exception - The exception.
77041 +*//***************************************************************************/
77042 +typedef void (t_FmExceptionsCallback)(t_Handle h_App,
77043 + e_FmExceptions exception);
77044 +
77045 +
77046 +/**************************************************************************//**
77047 + @Function t_FmBusErrorCallback
77048 +
77049 + @Description Bus error user callback routine, will be called upon a
77050 + bus error, passing parameters describing the errors and the owner.
77051 +
77052 + @Param[in] h_App - User's application descriptor.
77053 + @Param[in] portType - Port type (e_FmPortType)
77054 + @Param[in] portId - Port id - relative to type.
77055 + @Param[in] addr - Address that caused the error
77056 + @Param[in] tnum - Owner of error
77057 + @Param[in] liodn - Logical IO device number
77058 +*//***************************************************************************/
77059 +typedef void (t_FmBusErrorCallback) (t_Handle h_App,
77060 + e_FmPortType portType,
77061 + uint8_t portId,
77062 + uint64_t addr,
77063 + uint8_t tnum,
77064 + uint16_t liodn);
77065 +
77066 +/**************************************************************************//**
77067 + @Description A structure for defining buffer prefix area content.
77068 +*//***************************************************************************/
77069 +typedef struct t_FmBufferPrefixContent {
77070 + uint16_t privDataSize; /**< Number of bytes to be left at the beginning
77071 + of the external buffer; Note that the private-area will
77072 + start from the base of the buffer address. */
77073 + bool passPrsResult; /**< TRUE to pass the parse result to/from the FM;
77074 + User may use FM_PORT_GetBufferPrsResult() in order to
77075 + get the parser-result from a buffer. */
77076 + bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM
77077 + User may use FM_PORT_GetBufferTimeStamp() in order to
77078 + get the parser-result from a buffer. */
77079 + bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM
77080 + User may use FM_PORT_GetBufferHashResult() in order to
77081 + get the parser-result from a buffer. */
77082 + bool passAllOtherPCDInfo;/**< Add all other Internal-Context information:
77083 + AD, hash-result, key, etc. */
77084 + uint16_t dataAlign; /**< 0 to use driver's default alignment [DEFAULT_FM_SP_bufferPrefixContent_dataAlign],
77085 + other value for selecting a data alignment (must be a power of 2);
77086 + if write optimization is used, must be >= 16. */
77087 + uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size);
77088 + Note that this field impacts the size of the buffer-prefix
77089 + (i.e. it pushes the data offset);
77090 + This field is irrelevant if DPAA_VERSION==10 */
77091 +} t_FmBufferPrefixContent;
77092 +
77093 +/**************************************************************************//**
77094 + @Description A structure of information about each of the external
77095 + buffer pools used by a port or storage-profile.
77096 +*//***************************************************************************/
77097 +typedef struct t_FmExtPoolParams {
77098 + uint8_t id; /**< External buffer pool id */
77099 + uint16_t size; /**< External buffer pool buffer size */
77100 +} t_FmExtPoolParams;
77101 +
77102 +/**************************************************************************//**
77103 + @Description A structure for informing the driver about the external
77104 + buffer pools allocated in the BM and used by a port or a
77105 + storage-profile.
77106 +*//***************************************************************************/
77107 +typedef struct t_FmExtPools {
77108 + uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
77109 + t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
77110 + /**< Parameters for each port */
77111 +} t_FmExtPools;
77112 +
77113 +/**************************************************************************//**
77114 + @Description A structure for defining backup BM Pools.
77115 +*//***************************************************************************/
77116 +typedef struct t_FmBackupBmPools {
77117 + uint8_t numOfBackupPools; /**< Number of BM backup pools -
77118 + must be smaller than the total number of
77119 + pools defined for the specified port.*/
77120 + uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS];
77121 + /**< numOfBackupPools pool id's, specifying which
77122 + pools should be used only as backup. Pool
77123 + id's specified here must be a subset of the
77124 + pools used by the specified port.*/
77125 +} t_FmBackupBmPools;
77126 +
77127 +/**************************************************************************//**
77128 + @Description A structure for defining BM pool depletion criteria
77129 +*//***************************************************************************/
77130 +typedef struct t_FmBufPoolDepletion {
77131 + bool poolsGrpModeEnable; /**< select mode in which pause frames will be sent after
77132 + a number of pools (all together!) are depleted */
77133 + uint8_t numOfPools; /**< the number of depleted pools that will invoke
77134 + pause frames transmission. */
77135 + bool poolsToConsider[BM_MAX_NUM_OF_POOLS];
77136 + /**< For each pool, TRUE if it should be considered for
77137 + depletion (Note - this pool must be used by this port!). */
77138 + bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after
77139 + a single-pool is depleted; */
77140 + bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS];
77141 + /**< For each pool, TRUE if it should be considered for
77142 + depletion (Note - this pool must be used by this port!) */
77143 +#if (DPAA_VERSION >= 11)
77144 + bool pfcPrioritiesEn[FM_MAX_NUM_OF_PFC_PRIORITIES];
77145 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame which is transmitted */
77146 +#endif /* (DPAA_VERSION >= 11) */
77147 +} t_FmBufPoolDepletion;
77148 +
77149 +/**************************************************************************//**
77150 + @Description A Structure for defining Ucode patch for loading.
77151 +*//***************************************************************************/
77152 +typedef struct t_FmFirmwareParams {
77153 + uint32_t size; /**< Size of uCode */
77154 + uint32_t *p_Code; /**< A pointer to the uCode */
77155 +} t_FmFirmwareParams;
77156 +
77157 +/**************************************************************************//**
77158 + @Description A Structure for defining FM initialization parameters
77159 +*//***************************************************************************/
77160 +typedef struct t_FmParams {
77161 + uint8_t fmId; /**< Index of the FM */
77162 + uint8_t guestId; /**< FM Partition Id */
77163 + uintptr_t baseAddr; /**< A pointer to base of memory mapped FM registers (virtual);
77164 + this field is optional when the FM runs in "guest-mode"
77165 + (i.e. guestId != NCSW_MASTER_ID); in that case, the driver will
77166 + use the memory-map instead of calling the IPC where possible;
77167 + NOTE that this should include ALL common registers of the FM including
77168 + the PCD registers area (i.e. until the VSP pages - 880KB). */
77169 + t_Handle h_FmMuram; /**< A handle of an initialized MURAM object,
77170 + to be used by the FM. */
77171 + uint16_t fmClkFreq; /**< In Mhz;
77172 + Relevant when FM not runs in "guest-mode". */
77173 + uint16_t fmMacClkRatio; /**< FM MAC Clock ratio, for backward comparability:
77174 + when fmMacClkRatio = 0, ratio is 2:1
77175 + when fmMacClkRatio = 1, ratio is 1:1 */
77176 + t_FmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions;
77177 + Relevant when FM not runs in "guest-mode". */
77178 + t_FmBusErrorCallback *f_BusError; /**< An application callback routine to handle exceptions;
77179 + Relevant when FM not runs in "guest-mode". */
77180 + t_Handle h_App; /**< A handle to an application layer object; This handle will
77181 + be passed by the driver upon calling the above callbacks;
77182 + Relevant when FM not runs in "guest-mode". */
77183 + int irq; /**< FM interrupt source for normal events;
77184 + Relevant when FM not runs in "guest-mode". */
77185 + int errIrq; /**< FM interrupt source for errors;
77186 + Relevant when FM not runs in "guest-mode". */
77187 + t_FmFirmwareParams firmware; /**< The firmware parameters structure;
77188 + Relevant when FM not runs in "guest-mode". */
77189 +
77190 +#if (DPAA_VERSION >= 11)
77191 + uintptr_t vspBaseAddr; /**< A pointer to base of memory mapped FM VSP registers (virtual);
77192 + i.e. up to 24KB, depending on the specific chip. */
77193 + uint8_t partVSPBase; /**< The first Virtual-Storage-Profile-id dedicated to this partition.
77194 + NOTE: this parameter relevant only when working with multiple partitions. */
77195 + uint8_t partNumOfVSPs; /**< Number of VSPs dedicated to this partition.
77196 + NOTE: this parameter relevant only when working with multiple partitions. */
77197 +#endif /* (DPAA_VERSION >= 11) */
77198 +} t_FmParams;
77199 +
77200 +
77201 +/**************************************************************************//**
77202 + @Function FM_Config
77203 +
77204 + @Description Creates the FM module and returns its handle (descriptor).
77205 + This descriptor must be passed as first parameter to all other
77206 + FM function calls.
77207 +
77208 + No actual initialization or configuration of FM hardware is
77209 + done by this routine. All FM parameters get default values that
77210 + may be changed by calling one or more of the advance config routines.
77211 +
77212 + @Param[in] p_FmParams - A pointer to a data structure of mandatory FM parameters
77213 +
77214 + @Return A handle to the FM object, or NULL for Failure.
77215 +*//***************************************************************************/
77216 +t_Handle FM_Config(t_FmParams *p_FmParams);
77217 +
77218 +/**************************************************************************//**
77219 + @Function FM_Init
77220 +
77221 + @Description Initializes the FM module by defining the software structure
77222 + and configuring the hardware registers.
77223 +
77224 + @Param[in] h_Fm - FM module descriptor
77225 +
77226 + @Return E_OK on success; Error code otherwise.
77227 +*//***************************************************************************/
77228 +t_Error FM_Init(t_Handle h_Fm);
77229 +
77230 +/**************************************************************************//**
77231 + @Function FM_Free
77232 +
77233 + @Description Frees all resources that were assigned to FM module.
77234 +
77235 + Calling this routine invalidates the descriptor.
77236 +
77237 + @Param[in] h_Fm - FM module descriptor
77238 +
77239 + @Return E_OK on success; Error code otherwise.
77240 +*//***************************************************************************/
77241 +t_Error FM_Free(t_Handle h_Fm);
77242 +
77243 +
77244 +/**************************************************************************//**
77245 + @Group FM_advanced_init_grp FM Advanced Configuration Unit
77246 +
77247 + @Description Advanced configuration routines are optional routines that may
77248 + be called in order to change the default driver settings.
77249 +
77250 + Note: Advanced configuration routines are not available for guest partition.
77251 + @{
77252 +*//***************************************************************************/
77253 +
77254 +/**************************************************************************//**
77255 + @Description Enum for selecting DMA debug mode
77256 +*//***************************************************************************/
77257 +typedef enum e_FmDmaDbgCntMode {
77258 + e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */
77259 + e_FM_DMA_DBG_CNT_DONE, /**< Count DONE commands */
77260 + e_FM_DMA_DBG_CNT_COMM_Q_EM, /**< count command queue emergency signals */
77261 + e_FM_DMA_DBG_CNT_INT_READ_EM, /**< Count Internal Read buffer emergency signal */
77262 + e_FM_DMA_DBG_CNT_INT_WRITE_EM, /**< Count Internal Write buffer emergency signal */
77263 + e_FM_DMA_DBG_CNT_FPM_WAIT, /**< Count FPM WAIT signal */
77264 + e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors. */
77265 + e_FM_DMA_DBG_CNT_RAW_WAR_PROT /**< Number of times there was a need for RAW & WAR protection. */
77266 +} e_FmDmaDbgCntMode;
77267 +
77268 +/**************************************************************************//**
77269 + @Description Enum for selecting DMA Cache Override
77270 +*//***************************************************************************/
77271 +typedef enum e_FmDmaCacheOverride {
77272 + e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
77273 + e_FM_DMA_NO_STASH_DATA, /**< Data should not be stashed in system level cache */
77274 + e_FM_DMA_MAY_STASH_DATA, /**< Data may be stashed in system level cache */
77275 + e_FM_DMA_STASH_DATA /**< Data should be stashed in system level cache */
77276 +} e_FmDmaCacheOverride;
77277 +
77278 +/**************************************************************************//**
77279 + @Description Enum for selecting DMA External Bus Priority
77280 +*//***************************************************************************/
77281 +typedef enum e_FmDmaExtBusPri {
77282 + e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */
77283 + e_FM_DMA_EXT_BUS_EBS, /**< AXI extended bus service priority */
77284 + e_FM_DMA_EXT_BUS_SOS, /**< AXI sos priority */
77285 + e_FM_DMA_EXT_BUS_EBS_AND_SOS /**< AXI ebs + sos priority */
77286 +} e_FmDmaExtBusPri;
77287 +
77288 +/**************************************************************************//**
77289 + @Description Enum for choosing the field that will be output on AID
77290 +*//***************************************************************************/
77291 +typedef enum e_FmDmaAidMode {
77292 + e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
77293 + e_FM_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
77294 +} e_FmDmaAidMode;
77295 +
77296 +/**************************************************************************//**
77297 + @Description Enum for selecting FPM Catastrophic error behavior
77298 +*//***************************************************************************/
77299 +typedef enum e_FmCatastrophicErr {
77300 + e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */
77301 + e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only erroneous task is stalled */
77302 +} e_FmCatastrophicErr;
77303 +
77304 +/**************************************************************************//**
77305 + @Description Enum for selecting FPM DMA Error behavior
77306 +*//***************************************************************************/
77307 +typedef enum e_FmDmaErr {
77308 + e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic
77309 + error (e_FmCatastrophicErr)*/
77310 + e_FM_DMA_ERR_REPORT /**< Dma error is just reported */
77311 +} e_FmDmaErr;
77312 +
77313 +/**************************************************************************//**
77314 + @Description Enum for selecting DMA Emergency level by BMI emergency signal
77315 +*//***************************************************************************/
77316 +typedef enum e_FmDmaEmergencyLevel {
77317 + e_FM_DMA_EM_EBS = 0, /**< EBS emergency */
77318 + e_FM_DMA_EM_SOS /**< SOS emergency */
77319 +} e_FmDmaEmergencyLevel;
77320 +
77321 +/**************************************************************************//**
77322 + @Collection Enum for selecting DMA Emergency options
77323 +*//***************************************************************************/
77324 +typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */
77325 +
77326 +#define FM_DMA_MURAM_READ_EMERGENCY 0x00800000 /**< Enable emergency for MURAM1 */
77327 +#define FM_DMA_MURAM_WRITE_EMERGENCY 0x00400000 /**< Enable emergency for MURAM2 */
77328 +#define FM_DMA_EXT_BUS_EMERGENCY 0x00100000 /**< Enable emergency for external bus */
77329 +/* @} */
77330 +
77331 +/**************************************************************************//**
77332 + @Description A structure for defining DMA emergency level
77333 +*//***************************************************************************/
77334 +typedef struct t_FmDmaEmergency {
77335 + fmEmergencyBus_t emergencyBusSelect; /**< An OR of the busses where emergency
77336 + should be enabled */
77337 + e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */
77338 +} t_FmDmaEmergency;
77339 +
77340 +/**************************************************************************//*
77341 + @Description structure for defining FM threshold
77342 +*//***************************************************************************/
77343 +typedef struct t_FmThresholds {
77344 + uint8_t dispLimit; /**< The number of times a frames may
77345 + be passed in the FM before assumed to
77346 + be looping. */
77347 + uint8_t prsDispTh; /**< This is the number pf packets that may be
77348 + queued in the parser dispatch queue*/
77349 + uint8_t plcrDispTh; /**< This is the number pf packets that may be
77350 + queued in the policer dispatch queue*/
77351 + uint8_t kgDispTh; /**< This is the number pf packets that may be
77352 + queued in the keygen dispatch queue*/
77353 + uint8_t bmiDispTh; /**< This is the number pf packets that may be
77354 + queued in the BMI dispatch queue*/
77355 + uint8_t qmiEnqDispTh; /**< This is the number pf packets that may be
77356 + queued in the QMI enqueue dispatch queue*/
77357 + uint8_t qmiDeqDispTh; /**< This is the number pf packets that may be
77358 + queued in the QMI dequeue dispatch queue*/
77359 + uint8_t fmCtl1DispTh; /**< This is the number pf packets that may be
77360 + queued in fmCtl1 dispatch queue*/
77361 + uint8_t fmCtl2DispTh; /**< This is the number pf packets that may be
77362 + queued in fmCtl2 dispatch queue*/
77363 +} t_FmThresholds;
77364 +
77365 +/**************************************************************************//*
77366 + @Description structure for defining DMA thresholds
77367 +*//***************************************************************************/
77368 +typedef struct t_FmDmaThresholds {
77369 + uint8_t assertEmergency; /**< When this value is reached,
77370 + assert emergency (Threshold)*/
77371 + uint8_t clearEmergency; /**< After emergency is asserted, it is held
77372 + until this value is reached (Hystheresis) */
77373 +} t_FmDmaThresholds;
77374 +
77375 +/**************************************************************************//**
77376 + @Function t_FmResetOnInitOverrideCallback
77377 +
77378 + @Description FMan specific reset on init user callback routine,
77379 + will be used to override the standard FMan reset on init procedure
77380 +
77381 + @Param[in] h_Fm - FMan handler
77382 +*//***************************************************************************/
77383 +typedef void (t_FmResetOnInitOverrideCallback)(t_Handle h_Fm);
77384 +
77385 +/**************************************************************************//**
77386 + @Function FM_ConfigResetOnInit
77387 +
77388 + @Description Define whether to reset the FM before initialization.
77389 + Change the default configuration [DEFAULT_resetOnInit].
77390 +
77391 + @Param[in] h_Fm A handle to an FM Module.
77392 + @Param[in] enable When TRUE, FM will be reset before any initialization.
77393 +
77394 + @Return E_OK on success; Error code otherwise.
77395 +
77396 + @Cautions Allowed only following FM_Config() and before FM_Init().
77397 + This routine should NOT be called from guest-partition
77398 + (i.e. guestId != NCSW_MASTER_ID)
77399 +*//***************************************************************************/
77400 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable);
77401 +
77402 +/**************************************************************************//**
77403 + @Function FM_ConfigResetOnInitOverrideCallback
77404 +
77405 + @Description Define a special reset of FM before initialization.
77406 + Change the default configuration [DEFAULT_resetOnInitOverrideCallback].
77407 +
77408 + @Param[in] h_Fm A handle to an FM Module.
77409 + @Param[in] f_ResetOnInitOverride FM specific reset on init user callback routine.
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_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride);
77418 +
77419 +/**************************************************************************//**
77420 + @Function FM_ConfigTotalFifoSize
77421 +
77422 + @Description Define Total FIFO size for the whole FM.
77423 + Calling this routine changes the total Fifo size in the internal driver
77424 + data base from its default configuration [DEFAULT_totalFifoSize]
77425 +
77426 + @Param[in] h_Fm A handle to an FM Module.
77427 + @Param[in] totalFifoSize The selected new value.
77428 +
77429 + @Return E_OK on success; Error code otherwise.
77430 +
77431 + @Cautions Allowed only following FM_Config() and before FM_Init().
77432 + This routine should NOT be called from guest-partition
77433 + (i.e. guestId != NCSW_MASTER_ID)
77434 +*//***************************************************************************/
77435 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize);
77436 +
77437 + /**************************************************************************//**
77438 + @Function FM_ConfigDmaCacheOverride
77439 +
77440 + @Description Define cache override mode.
77441 + Calling this routine changes the cache override mode
77442 + in the internal driver data base from its default configuration [DEFAULT_cacheOverride]
77443 +
77444 + @Param[in] h_Fm A handle to an FM Module.
77445 + @Param[in] cacheOverride The selected new value.
77446 +
77447 + @Return E_OK on success; Error code otherwise.
77448 +
77449 + @Cautions Allowed only following FM_Config() and before FM_Init().
77450 + This routine should NOT be called from guest-partition
77451 + (i.e. guestId != NCSW_MASTER_ID)
77452 +*//***************************************************************************/
77453 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride);
77454 +
77455 +/**************************************************************************//**
77456 + @Function FM_ConfigDmaAidOverride
77457 +
77458 + @Description Define DMA AID override mode.
77459 + Calling this routine changes the AID override mode
77460 + in the internal driver data base from its default configuration [DEFAULT_aidOverride]
77461 +
77462 + @Param[in] h_Fm A handle to an FM Module.
77463 + @Param[in] aidOverride The selected new value.
77464 +
77465 + @Return E_OK on success; Error code otherwise.
77466 +
77467 + @Cautions Allowed only following FM_Config() and before FM_Init().
77468 + This routine should NOT be called from guest-partition
77469 + (i.e. guestId != NCSW_MASTER_ID)
77470 +*//***************************************************************************/
77471 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride);
77472 +
77473 +/**************************************************************************//**
77474 + @Function FM_ConfigDmaAidMode
77475 +
77476 + @Description Define DMA AID mode.
77477 + Calling this routine changes the AID mode in the internal
77478 + driver data base from its default configuration [DEFAULT_aidMode]
77479 +
77480 + @Param[in] h_Fm A handle to an FM Module.
77481 + @Param[in] aidMode The selected new value.
77482 +
77483 + @Return E_OK on success; Error code otherwise.
77484 +
77485 + @Cautions Allowed only following FM_Config() and before FM_Init().
77486 + This routine should NOT be called from guest-partition
77487 + (i.e. guestId != NCSW_MASTER_ID)
77488 +*//***************************************************************************/
77489 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode);
77490 +
77491 +/**************************************************************************//**
77492 + @Function FM_ConfigDmaAxiDbgNumOfBeats
77493 +
77494 + @Description Define DMA AXI number of beats.
77495 + Calling this routine changes the AXI number of beats in the internal
77496 + driver data base from its default configuration [DEFAULT_axiDbgNumOfBeats]
77497 +
77498 + @Param[in] h_Fm A handle to an FM Module.
77499 + @Param[in] axiDbgNumOfBeats The selected new value.
77500 +
77501 + @Return E_OK on success; Error code otherwise.
77502 +
77503 + @Cautions Allowed only following FM_Config() and before FM_Init().
77504 + This routine should NOT be called from guest-partition
77505 + (i.e. guestId != NCSW_MASTER_ID)
77506 +*//***************************************************************************/
77507 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats);
77508 +
77509 +/**************************************************************************//**
77510 + @Function FM_ConfigDmaCamNumOfEntries
77511 +
77512 + @Description Define number of CAM entries.
77513 + Calling this routine changes the number of CAM entries in the internal
77514 + driver data base from its default configuration [DEFAULT_dmaCamNumOfEntries].
77515 +
77516 + @Param[in] h_Fm A handle to an FM Module.
77517 + @Param[in] numOfEntries The selected new value.
77518 +
77519 + @Return E_OK on success; Error code otherwise.
77520 +
77521 + @Cautions Allowed only following FM_Config() and before FM_Init().
77522 + This routine should NOT be called from guest-partition
77523 + (i.e. guestId != NCSW_MASTER_ID)
77524 +*//***************************************************************************/
77525 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries);
77526 +
77527 +/**************************************************************************//**
77528 + @Function FM_ConfigEnableCounters
77529 +
77530 + @Description Obsolete, always return E_OK.
77531 +
77532 + @Param[in] h_Fm A handle to an FM Module.
77533 +
77534 + @Return E_OK on success; Error code otherwise.
77535 +*//***************************************************************************/
77536 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm);
77537 +
77538 +/**************************************************************************//**
77539 + @Function FM_ConfigDmaDbgCounter
77540 +
77541 + @Description Define DMA debug counter.
77542 + Calling this routine changes the number of the DMA debug counter in the internal
77543 + driver data base from its default configuration [DEFAULT_dmaDbgCntMode].
77544 +
77545 + @Param[in] h_Fm A handle to an FM Module.
77546 + @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode.
77547 +
77548 + @Return E_OK on success; Error code otherwise.
77549 +
77550 + @Cautions Allowed only following FM_Config() and before FM_Init().
77551 + This routine should NOT be called from guest-partition
77552 + (i.e. guestId != NCSW_MASTER_ID)
77553 +*//***************************************************************************/
77554 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode);
77555 +
77556 +/**************************************************************************//**
77557 + @Function FM_ConfigDmaStopOnBusErr
77558 +
77559 + @Description Define bus error behavior.
77560 + Calling this routine changes the bus error behavior definition
77561 + in the internal driver data base from its default
77562 + configuration [DEFAULT_dmaStopOnBusError].
77563 +
77564 + @Param[in] h_Fm A handle to an FM Module.
77565 + @Param[in] stop TRUE to stop on bus error, FALSE to continue.
77566 +
77567 + @Return E_OK on success; Error code otherwise.
77568 +
77569 + @Cautions Allowed only following FM_Config() and before FM_Init().
77570 + Only if bus error is enabled.
77571 + This routine should NOT be called from guest-partition
77572 + (i.e. guestId != NCSW_MASTER_ID)
77573 +*//***************************************************************************/
77574 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop);
77575 +
77576 +/**************************************************************************//**
77577 + @Function FM_ConfigDmaEmergency
77578 +
77579 + @Description Define DMA emergency.
77580 + Calling this routine changes the DMA emergency definition
77581 + in the internal driver data base from its default
77582 + configuration where's it's disabled.
77583 +
77584 + @Param[in] h_Fm A handle to an FM Module.
77585 + @Param[in] p_Emergency An OR mask of all required options.
77586 +
77587 + @Return E_OK on success; Error code otherwise.
77588 +
77589 + @Cautions Allowed only following FM_Config() and before FM_Init().
77590 + This routine should NOT be called from guest-partition
77591 + (i.e. guestId != NCSW_MASTER_ID)
77592 +*//***************************************************************************/
77593 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency);
77594 +
77595 +/**************************************************************************//**
77596 + @Function FM_ConfigDmaErr
77597 +
77598 + @Description DMA error treatment.
77599 + Calling this routine changes the DMA error treatment
77600 + in the internal driver data base from its default
77601 + configuration [DEFAULT_dmaErr].
77602 +
77603 + @Param[in] h_Fm A handle to an FM Module.
77604 + @Param[in] dmaErr The selected new choice.
77605 +
77606 + @Return E_OK on success; Error code otherwise.
77607 +
77608 + @Cautions Allowed only following FM_Config() and before FM_Init().
77609 + This routine should NOT be called from guest-partition
77610 + (i.e. guestId != NCSW_MASTER_ID)
77611 +*//***************************************************************************/
77612 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr);
77613 +
77614 +/**************************************************************************//**
77615 + @Function FM_ConfigCatastrophicErr
77616 +
77617 + @Description Define FM behavior on catastrophic error.
77618 + Calling this routine changes the FM behavior on catastrophic
77619 + error in the internal driver data base from its default
77620 + [DEFAULT_catastrophicErr].
77621 +
77622 + @Param[in] h_Fm A handle to an FM Module.
77623 + @Param[in] catastrophicErr The selected new choice.
77624 +
77625 + @Return E_OK on success; Error code otherwise.
77626 +
77627 + @Cautions Allowed only following FM_Config() and before FM_Init().
77628 + This routine should NOT be called from guest-partition
77629 + (i.e. guestId != NCSW_MASTER_ID)
77630 +*//***************************************************************************/
77631 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr);
77632 +
77633 +/**************************************************************************//**
77634 + @Function FM_ConfigEnableMuramTestMode
77635 +
77636 + @Description Enable MURAM test mode.
77637 + Calling this routine changes the internal driver data base
77638 + from its default selection of test mode where it's disabled.
77639 + This routine is only avaiable on old FM revisions (FMan v2).
77640 +
77641 + @Param[in] h_Fm A handle to an FM Module.
77642 +
77643 + @Return E_OK on success; Error code otherwise.
77644 +
77645 + @Cautions Allowed only following FM_Config() and before FM_Init().
77646 + This routine should NOT be called from guest-partition
77647 + (i.e. guestId != NCSW_MASTER_ID)
77648 +*//***************************************************************************/
77649 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm);
77650 +
77651 +/**************************************************************************//**
77652 + @Function FM_ConfigEnableIramTestMode
77653 +
77654 + @Description Enable IRAM test mode.
77655 + Calling this routine changes the internal driver data base
77656 + from its default selection of test mode where it's disabled.
77657 + This routine is only avaiable on old FM revisions (FMan v2).
77658 +
77659 + @Param[in] h_Fm A handle to an FM Module.
77660 +
77661 + @Return E_OK on success; Error code otherwise.
77662 +
77663 + @Cautions Allowed only following FM_Config() and before FM_Init().
77664 + This routine should NOT be called from guest-partition
77665 + (i.e. guestId != NCSW_MASTER_ID)
77666 +*//***************************************************************************/
77667 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm);
77668 +
77669 +/**************************************************************************//**
77670 + @Function FM_ConfigHaltOnExternalActivation
77671 +
77672 + @Description Define FM behavior on external halt activation.
77673 + Calling this routine changes the FM behavior on external halt
77674 + activation in the internal driver data base from its default
77675 + [DEFAULT_haltOnExternalActivation].
77676 +
77677 + @Param[in] h_Fm A handle to an FM Module.
77678 + @Param[in] enable TRUE to enable halt on external halt
77679 + activation.
77680 +
77681 + @Return E_OK on success; Error code otherwise.
77682 +
77683 + @Cautions Allowed only following FM_Config() and before FM_Init().
77684 + This routine should NOT be called from guest-partition
77685 + (i.e. guestId != NCSW_MASTER_ID)
77686 +*//***************************************************************************/
77687 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable);
77688 +
77689 +/**************************************************************************//**
77690 + @Function FM_ConfigHaltOnUnrecoverableEccError
77691 +
77692 + @Description Define FM behavior on external halt activation.
77693 + Calling this routine changes the FM behavior on unrecoverable
77694 + ECC error in the internal driver data base from its default
77695 + [DEFAULT_haltOnUnrecoverableEccError].
77696 + This routine is only avaiable on old FM revisions (FMan v2).
77697 +
77698 + @Param[in] h_Fm A handle to an FM Module.
77699 + @Param[in] enable TRUE to enable halt on unrecoverable Ecc error
77700 +
77701 + @Return E_OK on success; Error code otherwise.
77702 +
77703 + @Cautions Allowed only following FM_Config() and before FM_Init().
77704 + This routine should NOT be called from guest-partition
77705 + (i.e. guestId != NCSW_MASTER_ID)
77706 +*//***************************************************************************/
77707 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable);
77708 +
77709 +/**************************************************************************//**
77710 + @Function FM_ConfigException
77711 +
77712 + @Description Define FM exceptions.
77713 + Calling this routine changes the exceptions defaults in the
77714 + internal driver data base where all exceptions are enabled.
77715 +
77716 + @Param[in] h_Fm A handle to an FM Module.
77717 + @Param[in] exception The exception to be selected.
77718 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
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_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77727 +
77728 +/**************************************************************************//**
77729 + @Function FM_ConfigExternalEccRamsEnable
77730 +
77731 + @Description Select external ECC enabling.
77732 + Calling this routine changes the ECC enabling control in the internal
77733 + driver data base from its default [DEFAULT_externalEccRamsEnable].
77734 + When this option is enabled Rams ECC enabling is not effected
77735 + by FM_EnableRamsEcc/FM_DisableRamsEcc, but by a JTAG.
77736 +
77737 + @Param[in] h_Fm A handle to an FM Module.
77738 + @Param[in] enable TRUE to enable this option.
77739 +
77740 + @Return E_OK on success; Error code otherwise.
77741 +
77742 + @Cautions Allowed only following FM_Config() and before FM_Init().
77743 + This routine should NOT be called from guest-partition
77744 + (i.e. guestId != NCSW_MASTER_ID)
77745 +*//***************************************************************************/
77746 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable);
77747 +
77748 +/**************************************************************************//**
77749 + @Function FM_ConfigTnumAgingPeriod
77750 +
77751 + @Description Define Tnum aging period.
77752 + Calling this routine changes the Tnum aging of dequeue TNUMs
77753 + in the QMI in the internal driver data base from its default
77754 + [DEFAULT_tnumAgingPeriod].
77755 +
77756 + @Param[in] h_Fm A handle to an FM Module.
77757 + @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds.
77758 + Note that period is recalculated in units of
77759 + 64 FM clocks. Driver will pick the closest
77760 + possible period.
77761 +
77762 + @Return E_OK on success; Error code otherwise.
77763 +
77764 + @Cautions Allowed only following FM_Config() and before FM_Init().
77765 + This routine should NOT be called from guest-partition
77766 + (i.e. guestId != NCSW_MASTER_ID)
77767 + NOTE that if some MAC is configured for PFC, '0' value is NOT
77768 + allowed.
77769 +*//***************************************************************************/
77770 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod);
77771 +
77772 +/**************************************************************************//*
77773 + @Function FM_ConfigDmaEmergencySmoother
77774 +
77775 + @Description Define DMA emergency smoother.
77776 + Calling this routine changes the definition of the minimum
77777 + amount of DATA beats transferred on the AXI READ and WRITE
77778 + ports before lowering the emergency level.
77779 + By default smoother is disabled.
77780 +
77781 + @Param[in] h_Fm A handle to an FM Module.
77782 + @Param[in] emergencyCnt emergency switching counter.
77783 +
77784 + @Return E_OK on success; Error code otherwise.
77785 +
77786 + @Cautions Allowed only following FM_Config() and before FM_Init().
77787 + This routine should NOT be called from guest-partition
77788 + (i.e. guestId != NCSW_MASTER_ID)
77789 +*//***************************************************************************/
77790 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt);
77791 +
77792 +/**************************************************************************//*
77793 + @Function FM_ConfigThresholds
77794 +
77795 + @Description Calling this routine changes the internal driver data base
77796 + from its default FM threshold configuration:
77797 + dispLimit: [DEFAULT_dispLimit]
77798 + prsDispTh: [DEFAULT_prsDispTh]
77799 + plcrDispTh: [DEFAULT_plcrDispTh]
77800 + kgDispTh: [DEFAULT_kgDispTh]
77801 + bmiDispTh: [DEFAULT_bmiDispTh]
77802 + qmiEnqDispTh: [DEFAULT_qmiEnqDispTh]
77803 + qmiDeqDispTh: [DEFAULT_qmiDeqDispTh]
77804 + fmCtl1DispTh: [DEFAULT_fmCtl1DispTh]
77805 + fmCtl2DispTh: [DEFAULT_fmCtl2DispTh]
77806 +
77807 +
77808 + @Param[in] h_Fm A handle to an FM Module.
77809 + @Param[in] p_FmThresholds A structure of threshold parameters.
77810 +
77811 + @Return E_OK on success; Error code otherwise.
77812 +
77813 + @Cautions Allowed only following FM_Config() and before FM_Init().
77814 + This routine should NOT be called from guest-partition
77815 + (i.e. guestId != NCSW_MASTER_ID)
77816 +*//***************************************************************************/
77817 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds);
77818 +
77819 +/**************************************************************************//*
77820 + @Function FM_ConfigDmaSosEmergencyThreshold
77821 +
77822 + @Description Calling this routine changes the internal driver data base
77823 + from its default dma SOS emergency configuration [DEFAULT_dmaSosEmergency]
77824 +
77825 + @Param[in] h_Fm A handle to an FM Module.
77826 + @Param[in] dmaSosEmergency The selected new value.
77827 +
77828 + @Return E_OK on success; Error code otherwise.
77829 +
77830 + @Cautions Allowed only following FM_Config() and before FM_Init().
77831 + This routine should NOT be called from guest-partition
77832 + (i.e. guestId != NCSW_MASTER_ID)
77833 +*//***************************************************************************/
77834 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency);
77835 +
77836 +/**************************************************************************//*
77837 + @Function FM_ConfigDmaWriteBufThresholds
77838 +
77839 + @Description Calling this routine changes the internal driver data base
77840 + from its default configuration of DMA write buffer threshold
77841 + assertEmergency: [DEFAULT_dmaWriteIntBufLow]
77842 + clearEmergency: [DEFAULT_dmaWriteIntBufHigh]
77843 + This routine is only avaiable on old FM revisions (FMan v2).
77844 +
77845 + @Param[in] h_Fm A handle to an FM Module.
77846 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77847 + When 'assertEmergency' value is reached, emergency is asserted,
77848 + then it is held until 'clearEmergency' value is reached.
77849 +
77850 + @Return E_OK on success; Error code otherwise.
77851 +
77852 + @Cautions Allowed only following FM_Config() and before FM_Init().
77853 + This routine should NOT be called from guest-partition
77854 + (i.e. guestId != NCSW_MASTER_ID)
77855 +*//***************************************************************************/
77856 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77857 +
77858 + /**************************************************************************//*
77859 + @Function FM_ConfigDmaCommQThresholds
77860 +
77861 + @Description Calling this routine changes the internal driver data base
77862 + from its default configuration of DMA command queue threshold
77863 + assertEmergency: [DEFAULT_dmaCommQLow]
77864 + clearEmergency: [DEFAULT_dmaCommQHigh]
77865 +
77866 + @Param[in] h_Fm A handle to an FM Module.
77867 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77868 + When 'assertEmergency' value is reached, emergency is asserted,
77869 + then it is held until 'clearEmergency' value is reached..
77870 +
77871 + @Return E_OK on success; Error code otherwise.
77872 +
77873 + @Cautions Allowed only following FM_Config() and before FM_Init().
77874 + This routine should NOT be called from guest-partition
77875 + (i.e. guestId != NCSW_MASTER_ID)
77876 +*//***************************************************************************/
77877 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77878 +
77879 +/**************************************************************************//*
77880 + @Function FM_ConfigDmaReadBufThresholds
77881 +
77882 + @Description Calling this routine changes the internal driver data base
77883 + from its default configuration of DMA read buffer threshold
77884 + assertEmergency: [DEFAULT_dmaReadIntBufLow]
77885 + clearEmergency: [DEFAULT_dmaReadIntBufHigh]
77886 + This routine is only avaiable on old FM revisions (FMan v2).
77887 +
77888 + @Param[in] h_Fm A handle to an FM Module.
77889 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77890 + When 'assertEmergency' value is reached, emergency is asserted,
77891 + then it is held until 'clearEmergency' value is reached..
77892 +
77893 + @Return E_OK on success; Error code otherwise.
77894 +
77895 + @Cautions Allowed only following FM_Config() and before FM_Init().
77896 + This routine should NOT be called from guest-partition
77897 + (i.e. guestId != NCSW_MASTER_ID)
77898 +*//***************************************************************************/
77899 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77900 +
77901 +/**************************************************************************//*
77902 + @Function FM_ConfigDmaWatchdog
77903 +
77904 + @Description Calling this routine changes the internal driver data base
77905 + from its default watchdog configuration, which is disabled
77906 + [DEFAULT_dmaWatchdog].
77907 +
77908 + @Param[in] h_Fm A handle to an FM Module.
77909 + @Param[in] watchDogValue The selected new value - in microseconds.
77910 +
77911 + @Return E_OK on success; Error code otherwise.
77912 +
77913 + @Cautions Allowed only following FM_Config() and before FM_Init().
77914 + This routine should NOT be called from guest-partition
77915 + (i.e. guestId != NCSW_MASTER_ID)
77916 +*//***************************************************************************/
77917 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue);
77918 +
77919 +/** @} */ /* end of FM_advanced_init_grp group */
77920 +/** @} */ /* end of FM_init_grp group */
77921 +
77922 +
77923 +/**************************************************************************//**
77924 + @Group FM_runtime_control_grp FM Runtime Control Unit
77925 +
77926 + @Description FM Runtime control unit API functions, definitions and enums.
77927 + The FM driver provides a set of control routines.
77928 + These routines may only be called after the module was fully
77929 + initialized (both configuration and initialization routines were
77930 + called). They are typically used to get information from hardware
77931 + (status, counters/statistics, revision etc.), to modify a current
77932 + state or to force/enable a required action. Run-time control may
77933 + be called whenever necessary and as many times as needed.
77934 + @{
77935 +*//***************************************************************************/
77936 +
77937 +/**************************************************************************//**
77938 + @Collection General FM defines.
77939 +*//***************************************************************************/
77940 +#define FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
77941 + FM_MAX_NUM_OF_1G_RX_PORTS + \
77942 + FM_MAX_NUM_OF_10G_RX_PORTS + \
77943 + FM_MAX_NUM_OF_1G_TX_PORTS + \
77944 + FM_MAX_NUM_OF_10G_TX_PORTS) /**< Number of available FM ports */
77945 +/* @} */
77946 +
77947 +/**************************************************************************//*
77948 + @Description A Structure for Port bandwidth requirement. Port is identified
77949 + by type and relative id.
77950 +*//***************************************************************************/
77951 +typedef struct t_FmPortBandwidth {
77952 + e_FmPortType type; /**< FM port type */
77953 + uint8_t relativePortId; /**< Type relative port id */
77954 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
77955 +} t_FmPortBandwidth;
77956 +
77957 +/**************************************************************************//*
77958 + @Description A Structure containing an array of Port bandwidth requirements.
77959 + The user should state the ports requiring bandwidth in terms of
77960 + percentage - i.e. all port's bandwidths in the array must add
77961 + up to 100.
77962 +*//***************************************************************************/
77963 +typedef struct t_FmPortsBandwidthParams {
77964 + uint8_t numOfPorts; /**< The number of relevant ports, which is the
77965 + number of valid entries in the array below */
77966 + t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS];
77967 + /**< for each port, it's bandwidth (all port's
77968 + bandwidths must add up to 100.*/
77969 +} t_FmPortsBandwidthParams;
77970 +
77971 +/**************************************************************************//**
77972 + @Description DMA Emergency control on MURAM
77973 +*//***************************************************************************/
77974 +typedef enum e_FmDmaMuramPort {
77975 + e_FM_DMA_MURAM_PORT_WRITE, /**< MURAM write port */
77976 + e_FM_DMA_MURAM_PORT_READ /**< MURAM read port */
77977 +} e_FmDmaMuramPort;
77978 +
77979 +/**************************************************************************//**
77980 + @Description Enum for defining FM counters
77981 +*//***************************************************************************/
77982 +typedef enum e_FmCounters {
77983 + e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */
77984 + e_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
77985 + e_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
77986 + e_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
77987 + e_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
77988 + e_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
77989 + e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
77990 + e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
77991 + e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
77992 + e_FM_COUNTERS_DEQ_CONFIRM /**< QMI dequeue confirm counter */
77993 +} e_FmCounters;
77994 +
77995 +/**************************************************************************//**
77996 + @Description A Structure for returning FM revision information
77997 +*//***************************************************************************/
77998 +typedef struct t_FmRevisionInfo {
77999 + uint8_t majorRev; /**< Major revision */
78000 + uint8_t minorRev; /**< Minor revision */
78001 +} t_FmRevisionInfo;
78002 +
78003 +/**************************************************************************//**
78004 + @Description A Structure for returning FM ctrl code revision information
78005 +*//***************************************************************************/
78006 +typedef struct t_FmCtrlCodeRevisionInfo {
78007 + uint16_t packageRev; /**< Package revision */
78008 + uint8_t majorRev; /**< Major revision */
78009 + uint8_t minorRev; /**< Minor revision */
78010 +} t_FmCtrlCodeRevisionInfo;
78011 +
78012 +/**************************************************************************//**
78013 + @Description A Structure for defining DMA status
78014 +*//***************************************************************************/
78015 +typedef struct t_FmDmaStatus {
78016 + bool cmqNotEmpty; /**< Command queue is not empty */
78017 + bool busError; /**< Bus error occurred */
78018 + bool readBufEccError; /**< Double ECC error on buffer Read (Valid for FM rev < 6)*/
78019 + bool writeBufEccSysError; /**< Double ECC error on buffer write from system side (Valid for FM rev < 6)*/
78020 + bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side (Valid for FM rev < 6) */
78021 + bool singlePortEccError; /**< Single Port ECC error from FM side (Valid for FM rev >= 6)*/
78022 +} t_FmDmaStatus;
78023 +
78024 +/**************************************************************************//**
78025 + @Description A Structure for obtaining FM controller monitor values
78026 +*//***************************************************************************/
78027 +typedef struct t_FmCtrlMon {
78028 + uint8_t percentCnt[2]; /**< Percentage value */
78029 +} t_FmCtrlMon;
78030 +
78031 +
78032 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
78033 +/**************************************************************************//**
78034 + @Function FM_DumpRegs
78035 +
78036 + @Description Dumps all FM registers
78037 +
78038 + @Param[in] h_Fm A handle to an FM Module.
78039 +
78040 + @Return E_OK on success;
78041 +
78042 + @Cautions Allowed only following FM_Init().
78043 +*//***************************************************************************/
78044 +t_Error FM_DumpRegs(t_Handle h_Fm);
78045 +#endif /* (defined(DEBUG_ERRORS) && ... */
78046 +
78047 +/**************************************************************************//**
78048 + @Function FM_SetException
78049 +
78050 + @Description Calling this routine enables/disables the specified exception.
78051 +
78052 + @Param[in] h_Fm A handle to an FM Module.
78053 + @Param[in] exception The exception to be selected.
78054 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
78055 +
78056 + @Return E_OK on success; Error code otherwise.
78057 +
78058 + @Cautions Allowed only following FM_Init().
78059 + This routine should NOT be called from guest-partition
78060 + (i.e. guestId != NCSW_MASTER_ID)
78061 +*//***************************************************************************/
78062 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
78063 +
78064 +/**************************************************************************//**
78065 + @Function FM_EnableRamsEcc
78066 +
78067 + @Description Enables ECC mechanism for all the different FM RAM's; E.g. IRAM,
78068 + MURAM, Parser, Keygen, Policer, etc.
78069 + Note:
78070 + If FM_ConfigExternalEccRamsEnable was called to enable external
78071 + setting of ECC, this routine effects IRAM ECC only.
78072 + This routine is also called by the driver if an ECC exception is
78073 + enabled.
78074 +
78075 + @Param[in] h_Fm A handle to an FM Module.
78076 +
78077 + @Return E_OK on success; Error code otherwise.
78078 +
78079 + @Cautions Allowed only following FM_Config() and before FM_Init().
78080 + This routine should NOT be called from guest-partition
78081 + (i.e. guestId != NCSW_MASTER_ID)
78082 +*//***************************************************************************/
78083 +t_Error FM_EnableRamsEcc(t_Handle h_Fm);
78084 +
78085 +/**************************************************************************//**
78086 + @Function FM_DisableRamsEcc
78087 +
78088 + @Description Disables ECC mechanism for all the different FM RAM's; E.g. IRAM,
78089 + MURAM, Parser, Keygen, Policer, etc.
78090 + Note:
78091 + If FM_ConfigExternalEccRamsEnable was called to enable external
78092 + setting of ECC, this routine effects IRAM ECC only.
78093 + In opposed to FM_EnableRamsEcc, this routine must be called
78094 + explicitly to disable all Rams ECC.
78095 +
78096 + @Param[in] h_Fm A handle to an FM Module.
78097 +
78098 + @Return E_OK on success; Error code otherwise.
78099 +
78100 + @Cautions Allowed only following FM_Config() and before FM_Init().
78101 + This routine should NOT be called from guest-partition
78102 + (i.e. guestId != NCSW_MASTER_ID)
78103 +*//***************************************************************************/
78104 +t_Error FM_DisableRamsEcc(t_Handle h_Fm);
78105 +
78106 +/**************************************************************************//**
78107 + @Function FM_GetRevision
78108 +
78109 + @Description Returns the FM revision
78110 +
78111 + @Param[in] h_Fm A handle to an FM Module.
78112 + @Param[out] p_FmRevisionInfo A structure of revision information parameters.
78113 +
78114 + @Return E_OK on success; Error code otherwise.
78115 +
78116 + @Cautions Allowed only following FM_Init().
78117 +*//***************************************************************************/
78118 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
78119 +
78120 +/**************************************************************************//**
78121 + @Function FM_GetFmanCtrlCodeRevision
78122 +
78123 + @Description Returns the Fman controller code revision
78124 +
78125 + @Param[in] h_Fm A handle to an FM Module.
78126 + @Param[out] p_RevisionInfo A structure of revision information parameters.
78127 +
78128 + @Return E_OK on success; Error code otherwise.
78129 +
78130 + @Cautions Allowed only following FM_Init().
78131 +*//***************************************************************************/
78132 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo);
78133 +
78134 +/**************************************************************************//**
78135 + @Function FM_GetCounter
78136 +
78137 + @Description Reads one of the FM counters.
78138 +
78139 + @Param[in] h_Fm A handle to an FM Module.
78140 + @Param[in] counter The requested counter.
78141 +
78142 + @Return Counter's current value.
78143 +
78144 + @Cautions Allowed only following FM_Init().
78145 + Note that it is user's responsibility to call this routine only
78146 + for enabled counters, and there will be no indication if a
78147 + disabled counter is accessed.
78148 +*//***************************************************************************/
78149 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter);
78150 +
78151 +/**************************************************************************//**
78152 + @Function FM_ModifyCounter
78153 +
78154 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
78155 +
78156 + @Param[in] h_Fm A handle to an FM Module.
78157 + @Param[in] counter The requested counter.
78158 + @Param[in] val The requested value to be written into the counter.
78159 +
78160 + @Return E_OK on success; Error code otherwise.
78161 +
78162 + @Cautions Allowed only following FM_Init().
78163 + This routine should NOT be called from guest-partition
78164 + (i.e. guestId != NCSW_MASTER_ID)
78165 +*//***************************************************************************/
78166 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val);
78167 +
78168 +/**************************************************************************//**
78169 + @Function FM_Resume
78170 +
78171 + @Description Release FM after halt FM command or after unrecoverable ECC error.
78172 +
78173 + @Param[in] h_Fm A handle to an FM Module.
78174 +
78175 + @Return E_OK on success; Error code otherwise.
78176 +
78177 + @Cautions Allowed only following FM_Init().
78178 + This routine should NOT be called from guest-partition
78179 + (i.e. guestId != NCSW_MASTER_ID)
78180 +*//***************************************************************************/
78181 +void FM_Resume(t_Handle h_Fm);
78182 +
78183 +/**************************************************************************//**
78184 + @Function FM_SetDmaEmergency
78185 +
78186 + @Description Manual emergency set
78187 +
78188 + @Param[in] h_Fm A handle to an FM Module.
78189 + @Param[in] muramPort MURAM direction select.
78190 + @Param[in] enable TRUE to manually enable emergency, FALSE to disable.
78191 +
78192 + @Return None.
78193 +
78194 + @Cautions Allowed only following FM_Init().
78195 + This routine should NOT be called from guest-partition
78196 + (i.e. guestId != NCSW_MASTER_ID)
78197 +*//***************************************************************************/
78198 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable);
78199 +
78200 +/**************************************************************************//**
78201 + @Function FM_SetDmaExtBusPri
78202 +
78203 + @Description Set the DMA external bus priority
78204 +
78205 + @Param[in] h_Fm A handle to an FM Module.
78206 + @Param[in] pri External bus priority select
78207 +
78208 + @Return None.
78209 +
78210 + @Cautions Allowed only following FM_Init().
78211 + This routine should NOT be called from guest-partition
78212 + (i.e. guestId != NCSW_MASTER_ID)
78213 +*//***************************************************************************/
78214 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri);
78215 +
78216 +/**************************************************************************//**
78217 + @Function FM_GetDmaStatus
78218 +
78219 + @Description Reads the DMA current status
78220 +
78221 + @Param[in] h_Fm A handle to an FM Module.
78222 + @Param[out] p_FmDmaStatus A structure of DMA status parameters.
78223 +
78224 + @Cautions Allowed only following FM_Init().
78225 +*//***************************************************************************/
78226 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus);
78227 +
78228 +/**************************************************************************//**
78229 + @Function FM_ErrorIsr
78230 +
78231 + @Description FM interrupt-service-routine for errors.
78232 +
78233 + @Param[in] h_Fm A handle to an FM Module.
78234 +
78235 + @Return E_OK on success; E_EMPTY if no errors found in register, other
78236 + error code otherwise.
78237 +
78238 + @Cautions Allowed only following FM_Init().
78239 + This routine should NOT be called from guest-partition
78240 + (i.e. guestId != NCSW_MASTER_ID)
78241 +*//***************************************************************************/
78242 +t_Error FM_ErrorIsr(t_Handle h_Fm);
78243 +
78244 +/**************************************************************************//**
78245 + @Function FM_EventIsr
78246 +
78247 + @Description FM interrupt-service-routine for normal events.
78248 +
78249 + @Param[in] h_Fm A handle to an FM Module.
78250 +
78251 + @Cautions Allowed only following FM_Init().
78252 + This routine should NOT be called from guest-partition
78253 + (i.e. guestId != NCSW_MASTER_ID)
78254 +*//***************************************************************************/
78255 +void FM_EventIsr(t_Handle h_Fm);
78256 +
78257 +/**************************************************************************//**
78258 + @Function FM_GetSpecialOperationCoding
78259 +
78260 + @Description Return a specific coding according to the input mask.
78261 +
78262 + @Param[in] h_Fm A handle to an FM Module.
78263 + @Param[in] spOper special operation mask.
78264 + @Param[out] p_SpOperCoding special operation code.
78265 +
78266 + @Return E_OK on success; Error code otherwise.
78267 +
78268 + @Cautions Allowed only following FM_Init().
78269 +*//***************************************************************************/
78270 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
78271 + fmSpecialOperations_t spOper,
78272 + uint8_t *p_SpOperCoding);
78273 +
78274 +/**************************************************************************//**
78275 + @Function FM_CtrlMonStart
78276 +
78277 + @Description Start monitoring utilization of all available FM controllers.
78278 +
78279 + In order to obtain FM controllers utilization the following sequence
78280 + should be used:
78281 + -# FM_CtrlMonStart()
78282 + -# FM_CtrlMonStop()
78283 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78284 +
78285 + @Param[in] h_Fm A handle to an FM Module.
78286 +
78287 + @Return E_OK on success; Error code otherwise.
78288 +
78289 + @Cautions Allowed only following FM_Init().
78290 + This routine should NOT be called from guest-partition
78291 + (i.e. guestId != NCSW_MASTER_ID).
78292 +*//***************************************************************************/
78293 +t_Error FM_CtrlMonStart(t_Handle h_Fm);
78294 +
78295 +/**************************************************************************//**
78296 + @Function FM_CtrlMonStop
78297 +
78298 + @Description Stop monitoring utilization of all available FM controllers.
78299 +
78300 + In order to obtain FM controllers utilization the following sequence
78301 + should be used:
78302 + -# FM_CtrlMonStart()
78303 + -# FM_CtrlMonStop()
78304 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78305 +
78306 + @Param[in] h_Fm A handle to an FM Module.
78307 +
78308 + @Return E_OK on success; Error code otherwise.
78309 +
78310 + @Cautions Allowed only following FM_Init().
78311 + This routine should NOT be called from guest-partition
78312 + (i.e. guestId != NCSW_MASTER_ID).
78313 +*//***************************************************************************/
78314 +t_Error FM_CtrlMonStop(t_Handle h_Fm);
78315 +
78316 +/**************************************************************************//**
78317 + @Function FM_CtrlMonGetCounters
78318 +
78319 + @Description Obtain FM controller utilization parameters.
78320 +
78321 + In order to obtain FM controllers utilization the following sequence
78322 + should be used:
78323 + -# FM_CtrlMonStart()
78324 + -# FM_CtrlMonStop()
78325 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78326 +
78327 + @Param[in] h_Fm A handle to an FM Module.
78328 + @Param[in] fmCtrlIndex FM Controller index for that utilization results
78329 + are requested.
78330 + @Param[in] p_Mon Pointer to utilization results structure.
78331 +
78332 + @Return E_OK on success; Error code otherwise.
78333 +
78334 + @Cautions Allowed only following FM_Init().
78335 + This routine should NOT be called from guest-partition
78336 + (i.e. guestId != NCSW_MASTER_ID).
78337 +*//***************************************************************************/
78338 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon);
78339 +
78340 +
78341 +/**************************************************************************//*
78342 + @Function FM_ForceIntr
78343 +
78344 + @Description Causes an interrupt event on the requested source.
78345 +
78346 + @Param[in] h_Fm A handle to an FM Module.
78347 + @Param[in] exception An exception to be forced.
78348 +
78349 + @Return E_OK on success; Error code if the exception is not enabled,
78350 + or is not able to create interrupt.
78351 +
78352 + @Cautions Allowed only following FM_Init().
78353 + This routine should NOT be called from guest-partition
78354 + (i.e. guestId != NCSW_MASTER_ID)
78355 +*//***************************************************************************/
78356 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception);
78357 +
78358 +/**************************************************************************//*
78359 + @Function FM_SetPortsBandwidth
78360 +
78361 + @Description Sets relative weights between ports when accessing common resources.
78362 +
78363 + @Param[in] h_Fm A handle to an FM Module.
78364 + @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e.
78365 + total must equal 100.
78366 +
78367 + @Return E_OK on success; Error code otherwise.
78368 +
78369 + @Cautions Allowed only following FM_Init().
78370 + This routine should NOT be called from guest-partition
78371 + (i.e. guestId != NCSW_MASTER_ID)
78372 +*//***************************************************************************/
78373 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth);
78374 +
78375 +/**************************************************************************//*
78376 + @Function FM_GetMuramHandle
78377 +
78378 + @Description Gets the corresponding MURAM handle
78379 +
78380 + @Param[in] h_Fm A handle to an FM Module.
78381 +
78382 + @Return MURAM handle; NULL otherwise.
78383 +
78384 + @Cautions Allowed only following FM_Init().
78385 + This routine should NOT be called from guest-partition
78386 + (i.e. guestId != NCSW_MASTER_ID)
78387 +*//***************************************************************************/
78388 +t_Handle FM_GetMuramHandle(t_Handle h_Fm);
78389 +
78390 +/** @} */ /* end of FM_runtime_control_grp group */
78391 +/** @} */ /* end of FM_lib_grp group */
78392 +/** @} */ /* end of FM_grp group */
78393 +
78394 +
78395 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
78396 +typedef t_FmFirmwareParams t_FmPcdFirmwareParams;
78397 +typedef t_FmBufferPrefixContent t_FmPortBufferPrefixContent;
78398 +typedef t_FmExtPoolParams t_FmPortExtPoolParams;
78399 +typedef t_FmExtPools t_FmPortExtPools;
78400 +typedef t_FmBackupBmPools t_FmPortBackupBmPools;
78401 +typedef t_FmBufPoolDepletion t_FmPortBufPoolDepletion;
78402 +typedef e_FmDmaSwapOption e_FmPortDmaSwapOption;
78403 +typedef e_FmDmaCacheOption e_FmPortDmaCacheOption;
78404 +
78405 +#define FM_CONTEXTA_GET_OVVERIDE FM_CONTEXTA_GET_OVERRIDE
78406 +#define FM_CONTEXTA_SET_OVVERIDE FM_CONTEXTA_SET_OVERRIDE
78407 +
78408 +#define e_FM_EX_BMI_PIPELINE_ECC e_FM_EX_BMI_STORAGE_PROFILE_ECC
78409 +#define e_FM_PORT_DMA_NO_SWP e_FM_DMA_NO_SWP
78410 +#define e_FM_PORT_DMA_SWP_PPC_LE e_FM_DMA_SWP_PPC_LE
78411 +#define e_FM_PORT_DMA_SWP_BE e_FM_DMA_SWP_BE
78412 +#define e_FM_PORT_DMA_NO_STASH e_FM_DMA_NO_STASH
78413 +#define e_FM_PORT_DMA_STASH e_FM_DMA_STASH
78414 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
78415 +
78416 +
78417 +#endif /* __FM_EXT */
78418 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
78419 new file mode 100644
78420 index 00000000..be99b7c9
78421 --- /dev/null
78422 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
78423 @@ -0,0 +1,887 @@
78424 +/*
78425 + * Copyright 2008-2012 Freescale Semiconductor Inc.
78426 + *
78427 + * Redistribution and use in source and binary forms, with or without
78428 + * modification, are permitted provided that the following conditions are met:
78429 + * * Redistributions of source code must retain the above copyright
78430 + * notice, this list of conditions and the following disclaimer.
78431 + * * Redistributions in binary form must reproduce the above copyright
78432 + * notice, this list of conditions and the following disclaimer in the
78433 + * documentation and/or other materials provided with the distribution.
78434 + * * Neither the name of Freescale Semiconductor nor the
78435 + * names of its contributors may be used to endorse or promote products
78436 + * derived from this software without specific prior written permission.
78437 + *
78438 + *
78439 + * ALTERNATIVELY, this software may be distributed under the terms of the
78440 + * GNU General Public License ("GPL") as published by the Free Software
78441 + * Foundation, either version 2 of that License or (at your option) any
78442 + * later version.
78443 + *
78444 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
78445 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78446 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78447 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
78448 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78449 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78450 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
78451 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78452 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78453 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78454 + */
78455 +
78456 +
78457 +/**************************************************************************//**
78458 + @File fm_mac_ext.h
78459 +
78460 + @Description FM MAC ...
78461 +*//***************************************************************************/
78462 +#ifndef __FM_MAC_EXT_H
78463 +#define __FM_MAC_EXT_H
78464 +
78465 +#include "std_ext.h"
78466 +#include "enet_ext.h"
78467 +
78468 +
78469 +/**************************************************************************//**
78470 +
78471 + @Group FM_grp Frame Manager API
78472 +
78473 + @Description FM API functions, definitions and enums
78474 +
78475 + @{
78476 +*//***************************************************************************/
78477 +
78478 +/**************************************************************************//**
78479 + @Group FM_mac_grp FM MAC
78480 +
78481 + @Description FM MAC API functions, definitions and enums
78482 +
78483 + @{
78484 +*//***************************************************************************/
78485 +
78486 +#define FM_MAC_NO_PFC 0xff
78487 +
78488 +
78489 +/**************************************************************************//**
78490 + @Description FM MAC Exceptions
78491 +*//***************************************************************************/
78492 +typedef enum e_FmMacExceptions {
78493 + e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 /**< 10GEC MDIO scan event interrupt */
78494 + ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL /**< 10GEC MDIO command completion interrupt */
78495 + ,e_FM_MAC_EX_10G_REM_FAULT /**< 10GEC, mEMAC Remote fault interrupt */
78496 + ,e_FM_MAC_EX_10G_LOC_FAULT /**< 10GEC, mEMAC Local fault interrupt */
78497 + ,e_FM_MAC_EX_10G_1TX_ECC_ER /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
78498 + ,e_FM_MAC_EX_10G_TX_FIFO_UNFL /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
78499 + ,e_FM_MAC_EX_10G_TX_FIFO_OVFL /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
78500 + ,e_FM_MAC_EX_10G_TX_ER /**< 10GEC Transmit frame error interrupt */
78501 + ,e_FM_MAC_EX_10G_RX_FIFO_OVFL /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
78502 + ,e_FM_MAC_EX_10G_RX_ECC_ER /**< 10GEC, mEMAC Receive frame ECC error interrupt */
78503 + ,e_FM_MAC_EX_10G_RX_JAB_FRM /**< 10GEC Receive jabber frame interrupt */
78504 + ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM /**< 10GEC Receive oversized frame interrupt */
78505 + ,e_FM_MAC_EX_10G_RX_RUNT_FRM /**< 10GEC Receive runt frame interrupt */
78506 + ,e_FM_MAC_EX_10G_RX_FRAG_FRM /**< 10GEC Receive fragment frame interrupt */
78507 + ,e_FM_MAC_EX_10G_RX_LEN_ER /**< 10GEC Receive payload length error interrupt */
78508 + ,e_FM_MAC_EX_10G_RX_CRC_ER /**< 10GEC Receive CRC error interrupt */
78509 + ,e_FM_MAC_EX_10G_RX_ALIGN_ER /**< 10GEC Receive alignment error interrupt */
78510 + ,e_FM_MAC_EX_1G_BAB_RX /**< dTSEC Babbling receive error */
78511 + ,e_FM_MAC_EX_1G_RX_CTL /**< dTSEC Receive control (pause frame) interrupt */
78512 + ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET /**< dTSEC Graceful transmit stop complete */
78513 + ,e_FM_MAC_EX_1G_BAB_TX /**< dTSEC Babbling transmit error */
78514 + ,e_FM_MAC_EX_1G_TX_CTL /**< dTSEC Transmit control (pause frame) interrupt */
78515 + ,e_FM_MAC_EX_1G_TX_ERR /**< dTSEC Transmit error */
78516 + ,e_FM_MAC_EX_1G_LATE_COL /**< dTSEC Late collision */
78517 + ,e_FM_MAC_EX_1G_COL_RET_LMT /**< dTSEC Collision retry limit */
78518 + ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN /**< dTSEC Transmit FIFO underrun */
78519 + ,e_FM_MAC_EX_1G_MAG_PCKT /**< dTSEC Magic Packet detection */
78520 + ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET /**< dTSEC MII management read completion */
78521 + ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET /**< dTSEC MII management write completion */
78522 + ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET /**< dTSEC Graceful receive stop complete */
78523 + ,e_FM_MAC_EX_1G_TX_DATA_ERR /**< dTSEC Internal data error on transmit */
78524 + ,e_FM_MAC_EX_1G_RX_DATA_ERR /**< dTSEC Internal data error on receive */
78525 + ,e_FM_MAC_EX_1G_1588_TS_RX_ERR /**< dTSEC Time-Stamp Receive Error */
78526 + ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL /**< dTSEC MIB counter overflow */
78527 + ,e_FM_MAC_EX_TS_FIFO_ECC_ERR /**< mEMAC Time-stamp FIFO ECC error interrupt;
78528 + not supported on T4240/B4860 rev1 chips */
78529 + ,e_FM_MAC_EX_MAGIC_PACKET_INDICATION = e_FM_MAC_EX_1G_MAG_PCKT
78530 + /**< mEMAC Magic Packet Indication Interrupt */
78531 +} e_FmMacExceptions;
78532 +
78533 +/**************************************************************************//**
78534 + @Description TM MAC statistics level
78535 +*//***************************************************************************/
78536 +typedef enum e_FmMacStatisticsLevel {
78537 + e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */
78538 + e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; Optimized for performance */
78539 + e_FM_MAC_FULL_STATISTICS /**< All counters available; Not optimized for performance */
78540 +} e_FmMacStatisticsLevel;
78541 +
78542 +
78543 +#if (DPAA_VERSION >= 11)
78544 +/**************************************************************************//**
78545 + @Description Priority Flow Control Parameters
78546 +*//***************************************************************************/
78547 +typedef struct t_FmMacPfcParams {
78548 + bool pfcEnable; /**< Enable/Disable PFC */
78549 +
78550 + 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*/
78551 +
78552 + 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*/
78553 +
78554 +
78555 +} t_FmMacPfcParams;
78556 +#endif /* (DPAA_VERSION >= 11) */
78557 +
78558 +/**************************************************************************//**
78559 + @Function t_FmMacExceptionCallback
78560 +
78561 + @Description Fm Mac Exception Callback from FM MAC to the user
78562 +
78563 + @Param[in] h_App - Handle to the upper layer handler
78564 +
78565 + @Param[in] exceptions - The exception that occurred
78566 +
78567 + @Return void.
78568 +*//***************************************************************************/
78569 +typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions);
78570 +
78571 +
78572 +/**************************************************************************//**
78573 + @Description TM MAC statistics rfc3635
78574 +*//***************************************************************************/
78575 +typedef struct t_FmMacStatistics {
78576 +/* RMON */
78577 + uint64_t eStatPkts64; /**< r-10G tr-DT 64 byte frame counter */
78578 + uint64_t eStatPkts65to127; /**< r-10G 65 to 127 byte frame counter */
78579 + uint64_t eStatPkts128to255; /**< r-10G 128 to 255 byte frame counter */
78580 + uint64_t eStatPkts256to511; /**< r-10G 256 to 511 byte frame counter */
78581 + uint64_t eStatPkts512to1023; /**< r-10G 512 to 1023 byte frame counter */
78582 + uint64_t eStatPkts1024to1518; /**< r-10G 1024 to 1518 byte frame counter */
78583 + uint64_t eStatPkts1519to1522; /**< r-10G 1519 to 1522 byte good frame count */
78584 +/* */
78585 + uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
78586 + uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */
78587 + uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client (during receive). */
78588 + uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/
78589 + uint64_t eStatUndersizePkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
78590 + This count does not include range length errors */
78591 + uint64_t eStatOversizePkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
78592 + a valid FCS and otherwise well formed */
78593 +/* Pause */
78594 + uint64_t teStatPause; /**< Pause MAC Control received */
78595 + uint64_t reStatPause; /**< Pause MAC Control sent */
78596 +/* MIB II */
78597 + uint64_t ifInOctets; /**< Total number of byte received. */
78598 + uint64_t ifInPkts; /**< Total number of packets received.*/
78599 + uint64_t ifInUcastPkts; /**< Total number of unicast frame received;
78600 + NOTE: this counter is not supported on dTSEC MAC */
78601 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/
78602 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
78603 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */
78604 + uint64_t ifInErrors; /**< Number of frames received with error:
78605 + - FIFO Overflow Error
78606 + - CRC Error
78607 + - Frame Too Long Error
78608 + - Alignment Error
78609 + - The dedicated Error Code (0xfe, not a code error) was received */
78610 + uint64_t ifOutOctets; /**< Total number of byte sent. */
78611 + uint64_t ifOutPkts; /**< Total number of packets sent .*/
78612 + uint64_t ifOutUcastPkts; /**< Total number of unicast frame sent;
78613 + NOTE: this counter is not supported on dTSEC MAC */
78614 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
78615 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
78616 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
78617 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
78618 + - FIFO Overflow Error
78619 + - FIFO Underflow Error
78620 + - Other */
78621 +} t_FmMacStatistics;
78622 +
78623 +/**************************************************************************//**
78624 + @Description FM MAC Frame Size Counters
78625 +*//***************************************************************************/
78626 +typedef struct t_FmMacFrameSizeCounters {
78627 +
78628 + uint64_t count_pkts_64; /**< 64 byte frame counter */
78629 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
78630 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
78631 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
78632 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
78633 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
78634 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
78635 +} t_FmMacFrameSizeCounters;
78636 +
78637 +/**************************************************************************//**
78638 + @Group FM_mac_init_grp FM MAC Initialization Unit
78639 +
78640 + @Description FM MAC Initialization Unit
78641 +
78642 + @{
78643 +*//***************************************************************************/
78644 +
78645 +/**************************************************************************//**
78646 + @Description FM MAC config input
78647 +*//***************************************************************************/
78648 +typedef struct t_FmMacParams {
78649 + uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */
78650 + t_EnetAddr addr; /**< MAC address of device; First octet is sent first */
78651 + uint8_t macId; /**< MAC ID;
78652 + numbering of dTSEC and 1G-mEMAC:
78653 + 0 - FM_MAX_NUM_OF_1G_MACS;
78654 + numbering of 10G-MAC (TGEC) and 10G-mEMAC:
78655 + 0 - FM_MAX_NUM_OF_10G_MACS */
78656 + e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed);
78657 + Note that the speed should indicate the maximum rate that
78658 + this MAC should support rather than the actual speed;
78659 + i.e. user should use the FM_MAC_AdjustLink() routine to
78660 + provide accurate speed;
78661 + In case of mEMAC RGMII mode, the MAC is configured to RGMII
78662 + automatic mode, where actual speed/duplex mode information
78663 + is provided by PHY automatically in-band; FM_MAC_AdjustLink()
78664 + function should be used to switch to manual RGMII speed/duplex mode
78665 + configuration if RGMII PHY doesn't support in-band status signaling;
78666 + In addition, in mEMAC, in case where user is using the higher MACs
78667 + (i.e. the MACs that should support 10G), user should pass here
78668 + speed=10000 even if the interface is not allowing that (e.g. SGMII). */
78669 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
78670 + int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all
78671 + MACs; MUST be set to 'NO_IRQ' for MACs that don't have
78672 + mdio-irq, or for polling */
78673 + t_FmMacExceptionCallback *f_Event; /**< MDIO Events Callback Routine */
78674 + t_FmMacExceptionCallback *f_Exception; /**< Exception Callback Routine */
78675 + t_Handle h_App; /**< A handle to an application layer object; This handle will
78676 + be passed by the driver upon calling the above callbacks */
78677 +} t_FmMacParams;
78678 +
78679 +
78680 +/**************************************************************************//**
78681 + @Function FM_MAC_Config
78682 +
78683 + @Description Creates descriptor for the FM MAC module.
78684 +
78685 + The routine returns a handle (descriptor) to the FM MAC object.
78686 + This descriptor must be passed as first parameter to all other
78687 + FM MAC function calls.
78688 +
78689 + No actual initialization or configuration of FM MAC hardware is
78690 + done by this routine.
78691 +
78692 + @Param[in] p_FmMacParam - Pointer to data structure of parameters
78693 +
78694 + @Retval Handle to FM MAC object, or NULL for Failure.
78695 +*//***************************************************************************/
78696 +t_Handle FM_MAC_Config(t_FmMacParams *p_FmMacParam);
78697 +
78698 +/**************************************************************************//**
78699 + @Function FM_MAC_Init
78700 +
78701 + @Description Initializes the FM MAC module
78702 +
78703 + @Param[in] h_FmMac - FM module descriptor
78704 +
78705 + @Return E_OK on success; Error code otherwise.
78706 +*//***************************************************************************/
78707 +t_Error FM_MAC_Init(t_Handle h_FmMac);
78708 +
78709 +/**************************************************************************//**
78710 + @Function FM_Free
78711 +
78712 + @Description Frees all resources that were assigned to FM MAC module.
78713 +
78714 + Calling this routine invalidates the descriptor.
78715 +
78716 + @Param[in] h_FmMac - FM module descriptor
78717 +
78718 + @Return E_OK on success; Error code otherwise.
78719 +*//***************************************************************************/
78720 +t_Error FM_MAC_Free(t_Handle h_FmMac);
78721 +
78722 +
78723 +/**************************************************************************//**
78724 + @Group FM_mac_advanced_init_grp FM MAC Advanced Configuration Unit
78725 +
78726 + @Description Configuration functions used to change default values.
78727 +
78728 + @{
78729 +*//***************************************************************************/
78730 +
78731 +/**************************************************************************//**
78732 + @Function FM_MAC_ConfigResetOnInit
78733 +
78734 + @Description Tell the driver whether to reset the FM MAC before initialization or
78735 + not. It changes the default configuration [DEFAULT_resetOnInit].
78736 +
78737 + @Param[in] h_FmMac A handle to a FM MAC Module.
78738 + @Param[in] enable When TRUE, FM will be reset before any initialization.
78739 +
78740 + @Return E_OK on success; Error code otherwise.
78741 +
78742 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78743 +*//***************************************************************************/
78744 +t_Error FM_MAC_ConfigResetOnInit(t_Handle h_FmMac, bool enable);
78745 +
78746 +/**************************************************************************//**
78747 + @Function FM_MAC_ConfigLoopback
78748 +
78749 + @Description Enable/Disable internal loopback mode
78750 +
78751 + @Param[in] h_FmMac A handle to a FM MAC Module.
78752 + @Param[in] enable TRUE to enable or FALSE to disable.
78753 +
78754 + @Return E_OK on success; Error code otherwise.
78755 +
78756 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78757 +*//***************************************************************************/
78758 +t_Error FM_MAC_ConfigLoopback(t_Handle h_FmMac, bool enable);
78759 +
78760 +/**************************************************************************//**
78761 + @Function FM_MAC_ConfigMaxFrameLength
78762 +
78763 + @Description Setup maximum Rx Frame Length (in 1G MAC, effects also Tx)
78764 +
78765 + @Param[in] h_FmMac A handle to a FM MAC Module.
78766 + @Param[in] newVal MAX Frame length
78767 +
78768 + @Return E_OK on success; Error code otherwise.
78769 +
78770 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78771 +*//***************************************************************************/
78772 +t_Error FM_MAC_ConfigMaxFrameLength(t_Handle h_FmMac, uint16_t newVal);
78773 +
78774 +/**************************************************************************//**
78775 + @Function FM_MAC_ConfigWan
78776 +
78777 + @Description ENABLE WAN mode in 10G-MAC
78778 +
78779 + @Param[in] h_FmMac A handle to a FM MAC Module.
78780 + @Param[in] enable TRUE to enable or FALSE to disable.
78781 +
78782 + @Return E_OK on success; Error code otherwise.
78783 +
78784 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78785 +*//***************************************************************************/
78786 +t_Error FM_MAC_ConfigWan(t_Handle h_FmMac, bool enable);
78787 +
78788 +/**************************************************************************//**
78789 + @Function FM_MAC_ConfigPadAndCrc
78790 +
78791 + @Description Config PAD and CRC mode
78792 +
78793 + @Param[in] h_FmMac A handle to a FM MAC Module.
78794 + @Param[in] enable TRUE to enable or FALSE to disable.
78795 +
78796 + @Return E_OK on success; Error code otherwise.
78797 +
78798 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78799 + Not supported on 10G-MAC (i.e. CRC & PAD are added automatically
78800 + by HW); on mEMAC, this routine supports only PAD (i.e. CRC is
78801 + added automatically by HW).
78802 +*//***************************************************************************/
78803 +t_Error FM_MAC_ConfigPadAndCrc(t_Handle h_FmMac, bool enable);
78804 +
78805 +/**************************************************************************//**
78806 + @Function FM_MAC_ConfigHalfDuplex
78807 +
78808 + @Description Config Half Duplex Mode
78809 +
78810 + @Param[in] h_FmMac A handle to a FM MAC Module.
78811 + @Param[in] enable TRUE to enable or FALSE to disable.
78812 +
78813 + @Return E_OK on success; Error code otherwise.
78814 +
78815 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78816 +*//***************************************************************************/
78817 +t_Error FM_MAC_ConfigHalfDuplex(t_Handle h_FmMac, bool enable);
78818 +
78819 +/**************************************************************************//**
78820 + @Function FM_MAC_ConfigTbiPhyAddr
78821 +
78822 + @Description Configures the address of internal TBI PHY.
78823 +
78824 + @Param[in] h_FmMac A handle to a FM MAC Module.
78825 + @Param[in] newVal TBI PHY address (1-31).
78826 +
78827 + @Return E_OK on success; Error code otherwise.
78828 +
78829 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78830 +*//***************************************************************************/
78831 +t_Error FM_MAC_ConfigTbiPhyAddr(t_Handle h_FmMac, uint8_t newVal);
78832 +
78833 +/**************************************************************************//**
78834 + @Function FM_MAC_ConfigLengthCheck
78835 +
78836 + @Description Configure the frame length checking.
78837 +
78838 + @Param[in] h_FmMac A handle to a FM MAC Module.
78839 + @Param[in] enable TRUE to enable or FALSE to disable.
78840 +
78841 + @Return E_OK on success; Error code otherwise.
78842 +
78843 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78844 +*//***************************************************************************/
78845 +t_Error FM_MAC_ConfigLengthCheck(t_Handle h_FmMac, bool enable);
78846 +
78847 +/**************************************************************************//**
78848 + @Function FM_MAC_ConfigException
78849 +
78850 + @Description Change Exception selection from default
78851 +
78852 + @Param[in] h_FmMac A handle to a FM MAC Module.
78853 + @Param[in] ex Type of the desired exceptions
78854 + @Param[in] enable TRUE to enable the specified exception, FALSE to disable it.
78855 +
78856 + @Return E_OK on success; Error code otherwise.
78857 +
78858 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78859 +*//***************************************************************************/
78860 +t_Error FM_MAC_ConfigException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78861 +
78862 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
78863 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac);
78864 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
78865 +/** @} */ /* end of FM_mac_advanced_init_grp group */
78866 +/** @} */ /* end of FM_mac_init_grp group */
78867 +
78868 +
78869 +/**************************************************************************//**
78870 + @Group FM_mac_runtime_control_grp FM MAC Runtime Control Unit
78871 +
78872 + @Description FM MAC Runtime control unit API functions, definitions and enums.
78873 +
78874 + @{
78875 +*//***************************************************************************/
78876 +
78877 +/**************************************************************************//**
78878 + @Function FM_MAC_Enable
78879 +
78880 + @Description Enable the MAC
78881 +
78882 + @Param[in] h_FmMac A handle to a FM MAC Module.
78883 + @Param[in] mode Mode of operation (RX, TX, Both)
78884 +
78885 + @Return E_OK on success; Error code otherwise.
78886 +
78887 + @Cautions Allowed only following FM_MAC_Init().
78888 +*//***************************************************************************/
78889 +t_Error FM_MAC_Enable(t_Handle h_FmMac, e_CommMode mode);
78890 +
78891 +/**************************************************************************//**
78892 + @Function FM_MAC_Disable
78893 +
78894 + @Description DISABLE the MAC
78895 +
78896 + @Param[in] h_FmMac A handle to a FM MAC Module.
78897 + @Param[in] mode Define what part to Disable (RX, TX or BOTH)
78898 +
78899 + @Return E_OK on success; Error code otherwise.
78900 +
78901 + @Cautions Allowed only following FM_MAC_Init().
78902 +*//***************************************************************************/
78903 +t_Error FM_MAC_Disable(t_Handle h_FmMac, e_CommMode mode);
78904 +
78905 +/**************************************************************************//**
78906 + @Function FM_MAC_Resume
78907 +
78908 + @Description Re-init the MAC after suspend
78909 +
78910 + @Param[in] h_FmMac A handle to a FM MAC Module.
78911 +
78912 + @Return E_OK on success; Error code otherwise.
78913 +
78914 + @Cautions Allowed only following FM_MAC_Init().
78915 +*//***************************************************************************/
78916 +t_Error FM_MAC_Resume(t_Handle h_FmMac);
78917 +
78918 +/**************************************************************************//**
78919 + @Function FM_MAC_Enable1588TimeStamp
78920 +
78921 + @Description Enables the TSU operation.
78922 +
78923 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78924 +
78925 + @Return E_OK on success; Error code otherwise.
78926 +
78927 + @Cautions Allowed only following FM_MAC_Init().
78928 +*//***************************************************************************/
78929 +t_Error FM_MAC_Enable1588TimeStamp(t_Handle h_Fm);
78930 +
78931 +/**************************************************************************//**
78932 + @Function FM_MAC_Disable1588TimeStamp
78933 +
78934 + @Description Disables the TSU operation.
78935 +
78936 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78937 +
78938 + @Return E_OK on success; Error code otherwise.
78939 +
78940 + @Cautions Allowed only following FM_MAC_Init().
78941 +*//***************************************************************************/
78942 +t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm);
78943 +
78944 +/**************************************************************************//**
78945 + @Function FM_MAC_SetTxAutoPauseFrames
78946 +
78947 + @Description Enable/Disable transmission of Pause-Frames.
78948 + The routine changes the default configuration [DEFAULT_TX_PAUSE_TIME].
78949 +
78950 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78951 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78952 + Each quanta represents a 512 bit-times; Note that '0'
78953 + as an input here will be used as disabling the
78954 + transmission of the pause-frames.
78955 +
78956 + @Return E_OK on success; Error code otherwise.
78957 +
78958 + @Cautions Allowed only following FM_MAC_Init().
78959 +*//***************************************************************************/
78960 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
78961 + uint16_t pauseTime);
78962 +
78963 + /**************************************************************************//**
78964 + @Function FM_MAC_SetTxPauseFrames
78965 +
78966 + @Description Enable/Disable transmission of Pause-Frames.
78967 + The routine changes the default configuration:
78968 + pause-time - [DEFAULT_TX_PAUSE_TIME]
78969 + threshold-time - [0]
78970 +
78971 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78972 + @Param[in] priority - the PFC class of service; use 'FM_MAC_NO_PFC'
78973 + to indicate legacy pause support (i.e. no PFC).
78974 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78975 + Each quanta represents a 512 bit-times;
78976 + Note that '0' as an input here will be used as disabling the
78977 + transmission of the pause-frames.
78978 + @Param[in] threshTime - Pause Threshold equanta value used by the MAC to retransmit pause frame.
78979 + if the situation causing a pause frame to be sent didn't finish when the timer
78980 + reached the threshold quanta, the MAC will retransmit the pause frame.
78981 + Each quanta represents a 512 bit-times.
78982 +
78983 + @Return E_OK on success; Error code otherwise.
78984 +
78985 + @Cautions Allowed only following FM_MAC_Init().
78986 + In order for PFC to work properly the user must configure
78987 + TNUM-aging in the tx-port it is recommended that pre-fetch and
78988 + rate limit in the tx port should be disabled;
78989 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
78990 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
78991 + in the 'priority' field.
78992 +*//***************************************************************************/
78993 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
78994 + uint8_t priority,
78995 + uint16_t pauseTime,
78996 + uint16_t threshTime);
78997 +
78998 +/**************************************************************************//**
78999 + @Function FM_MAC_SetRxIgnorePauseFrames
79000 +
79001 + @Description Enable/Disable ignoring of Pause-Frames.
79002 +
79003 + @Param[in] h_FmMac - A handle to a FM MAC Module.
79004 + @Param[in] en - boolean indicates whether to ignore the incoming pause
79005 + frames or not.
79006 +
79007 + @Return E_OK on success; Error code otherwise.
79008 +
79009 + @Cautions Allowed only following FM_MAC_Init().
79010 +*//***************************************************************************/
79011 +t_Error FM_MAC_SetRxIgnorePauseFrames(t_Handle h_FmMac, bool en);
79012 +
79013 +/**************************************************************************//**
79014 + @Function FM_MAC_SetWakeOnLan
79015 +
79016 + @Description Enable/Disable Wake On Lan support
79017 +
79018 + @Param[in] h_FmMac - A handle to a FM MAC Module.
79019 + @Param[in] en - boolean indicates whether to enable Wake On Lan
79020 + support or not.
79021 +
79022 + @Return E_OK on success; Error code otherwise.
79023 +
79024 + @Cautions Allowed only following FM_MAC_Init().
79025 +*//***************************************************************************/
79026 +t_Error FM_MAC_SetWakeOnLan(t_Handle h_FmMac, bool en);
79027 +
79028 +/**************************************************************************//**
79029 + @Function FM_MAC_ResetCounters
79030 +
79031 + @Description reset all statistics counters
79032 +
79033 + @Param[in] h_FmMac - A handle to a FM MAC Module.
79034 +
79035 + @Return E_OK on success; Error code otherwise.
79036 +
79037 + @Cautions Allowed only following FM_MAC_Init().
79038 +*//***************************************************************************/
79039 +t_Error FM_MAC_ResetCounters(t_Handle h_FmMac);
79040 +
79041 +/**************************************************************************//**
79042 + @Function FM_MAC_SetException
79043 +
79044 + @Description Enable/Disable a specific Exception
79045 +
79046 + @Param[in] h_FmMac - A handle to a FM MAC Module.
79047 + @Param[in] ex - Type of the desired exceptions
79048 + @Param[in] enable - TRUE to enable the specified exception, FALSE to disable it.
79049 +
79050 +
79051 + @Return E_OK on success; Error code otherwise.
79052 +
79053 + @Cautions Allowed only following FM_MAC_Init().
79054 +*//***************************************************************************/
79055 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
79056 +
79057 +/**************************************************************************//**
79058 + @Function FM_MAC_SetStatistics
79059 +
79060 + @Description Define Statistics level.
79061 + Where applicable, the routine also enables the MIB counters
79062 + overflow interrupt in order to keep counters accurate
79063 + and account for overflows.
79064 + This routine is relevant only for dTSEC.
79065 +
79066 + @Param[in] h_FmMac - A handle to a FM MAC Module.
79067 + @Param[in] statisticsLevel - Full statistics level provides all standard counters but may
79068 + reduce performance. Partial statistics provides only special
79069 + event counters (errors etc.). If selected, regular counters (such as
79070 + byte/packet) will be invalid and will return -1.
79071 +
79072 + @Return E_OK on success; Error code otherwise.
79073 +
79074 + @Cautions Allowed only following FM_MAC_Init().
79075 +*//***************************************************************************/
79076 +t_Error FM_MAC_SetStatistics(t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
79077 +
79078 +/**************************************************************************//**
79079 + @Function FM_MAC_GetStatistics
79080 +
79081 + @Description get all statistics counters
79082 +
79083 + @Param[in] h_FmMac - A handle to a FM MAC Module.
79084 + @Param[in] p_Statistics - Structure with statistics
79085 +
79086 + @Return E_OK on success; Error code otherwise.
79087 +
79088 + @Cautions Allowed only following FM_Init().
79089 +*//***************************************************************************/
79090 +t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
79091 +
79092 +/**************************************************************************//**
79093 + @Function FM_MAC_GetFrameSizeCounters
79094 +
79095 + @Description get MAC statistics counters for different frame size
79096 +
79097 + @Param[in] h_FmMac - A handle to a FM MAC Module.
79098 + @Param[in] p_FrameSizeCounters - Structure with counters
79099 + @Param[in] type - Type of counters to be read
79100 +
79101 + @Return E_OK on success; Error code otherwise.
79102 +
79103 + @Cautions Allowed only following FM_Init().
79104 +*//***************************************************************************/
79105 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
79106 +
79107 +/**************************************************************************//**
79108 + @Function FM_MAC_ModifyMacAddr
79109 +
79110 + @Description Replace the main MAC Address
79111 +
79112 + @Param[in] h_FmMac - A handle to a FM Module.
79113 + @Param[in] p_EnetAddr - Ethernet Mac address
79114 +
79115 + @Return E_OK on success; Error code otherwise.
79116 +
79117 + @Cautions Allowed only after FM_MAC_Init().
79118 +*//***************************************************************************/
79119 +t_Error FM_MAC_ModifyMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79120 +
79121 +/**************************************************************************//**
79122 + @Function FM_MAC_AddHashMacAddr
79123 +
79124 + @Description Add an Address to the hash table. This is for filter purpose only.
79125 +
79126 + @Param[in] h_FmMac - A handle to a FM Module.
79127 + @Param[in] p_EnetAddr - Ethernet Mac address
79128 +
79129 + @Return E_OK on success; Error code otherwise.
79130 +
79131 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
79132 + @Cautions Some address need to be filterd out in upper FM blocks.
79133 +*//***************************************************************************/
79134 +t_Error FM_MAC_AddHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79135 +
79136 +/**************************************************************************//**
79137 + @Function FM_MAC_RemoveHashMacAddr
79138 +
79139 + @Description Delete an Address to the hash table. This is for filter purpose only.
79140 +
79141 + @Param[in] h_FmMac - A handle to a FM Module.
79142 + @Param[in] p_EnetAddr - Ethernet Mac address
79143 +
79144 + @Return E_OK on success; Error code otherwise.
79145 +
79146 + @Cautions Allowed only following FM_MAC_Init().
79147 +*//***************************************************************************/
79148 +t_Error FM_MAC_RemoveHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79149 +
79150 +/**************************************************************************//**
79151 + @Function FM_MAC_AddExactMatchMacAddr
79152 +
79153 + @Description Add a unicast or multicast mac address for exact-match filtering
79154 + (8 on dTSEC, 2 for 10G-MAC)
79155 +
79156 + @Param[in] h_FmMac - A handle to a FM Module.
79157 + @Param[in] p_EnetAddr - MAC Address to ADD
79158 +
79159 + @Return E_OK on success; Error code otherwise.
79160 +
79161 + @Cautions Allowed only after FM_MAC_Init().
79162 +*//***************************************************************************/
79163 +t_Error FM_MAC_AddExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79164 +
79165 +/**************************************************************************//**
79166 + @Function FM_MAC_RemovelExactMatchMacAddr
79167 +
79168 + @Description Remove a uni cast or multi cast mac address.
79169 +
79170 + @Param[in] h_FmMac - A handle to a FM Module.
79171 + @Param[in] p_EnetAddr - MAC Address to remove
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_RemovelExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79178 +
79179 +/**************************************************************************//**
79180 + @Function FM_MAC_SetPromiscuous
79181 +
79182 + @Description Enable/Disable MAC Promiscuous mode for ALL mac addresses.
79183 +
79184 + @Param[in] h_FmMac - A handle to a FM MAC Module.
79185 + @Param[in] enable - TRUE to enable or FALSE to disable.
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_SetPromiscuous(t_Handle h_FmMac, bool enable);
79192 +
79193 +/**************************************************************************//**
79194 + @Function FM_MAC_AdjustLink
79195 +
79196 + @Description Adjusts the Ethernet link with new speed/duplex setup.
79197 + This routine is relevant for dTSEC and mEMAC.
79198 + In case of mEMAC, this routine is also used for manual
79199 + re-configuration of RGMII speed and duplex mode for
79200 + RGMII PHYs not supporting in-band status information
79201 + to MAC.
79202 +
79203 + @Param[in] h_FmMac - A handle to a FM Module.
79204 + @Param[in] speed - Ethernet speed.
79205 + @Param[in] fullDuplex - TRUE for full-duplex mode;
79206 + FALSE for half-duplex mode.
79207 +
79208 + @Return E_OK on success; Error code otherwise.
79209 +*//***************************************************************************/
79210 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
79211 +
79212 +/**************************************************************************//**
79213 + @Function FM_MAC_RestartAutoneg
79214 +
79215 + @Description Restarts the auto-negotiation process.
79216 + When auto-negotiation process is invoked under traffic the
79217 + auto-negotiation process between the internal SGMII PHY and the
79218 + external PHY does not always complete successfully. Calling this
79219 + function will restart the auto-negotiation process that will end
79220 + successfully. It is recommended to call this function after issuing
79221 + auto-negotiation restart command to the Eth Phy.
79222 + This routine is relevant only for dTSEC.
79223 +
79224 + @Param[in] h_FmMac - A handle to a FM Module.
79225 +
79226 + @Return E_OK on success; Error code otherwise.
79227 +*//***************************************************************************/
79228 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac);
79229 +
79230 +/**************************************************************************//**
79231 + @Function FM_MAC_GetId
79232 +
79233 + @Description Return the MAC ID
79234 +
79235 + @Param[in] h_FmMac - A handle to a FM Module.
79236 + @Param[out] p_MacId - MAC ID of device
79237 +
79238 + @Return E_OK on success; Error code otherwise.
79239 +
79240 + @Cautions Allowed only after FM_MAC_Init().
79241 +*//***************************************************************************/
79242 +t_Error FM_MAC_GetId(t_Handle h_FmMac, uint32_t *p_MacId);
79243 +
79244 +/**************************************************************************//**
79245 + @Function FM_MAC_GetVesrion
79246 +
79247 + @Description Return Mac HW chip version
79248 +
79249 + @Param[in] h_FmMac - A handle to a FM Module.
79250 + @Param[out] p_MacVresion - Mac version as defined by the chip
79251 +
79252 + @Return E_OK on success; Error code otherwise.
79253 +
79254 + @Cautions Allowed only after FM_MAC_Init().
79255 +*//***************************************************************************/
79256 +t_Error FM_MAC_GetVesrion(t_Handle h_FmMac, uint32_t *p_MacVresion);
79257 +
79258 +/**************************************************************************//**
79259 + @Function FM_MAC_MII_WritePhyReg
79260 +
79261 + @Description Write data into Phy Register
79262 +
79263 + @Param[in] h_FmMac - A handle to a FM Module.
79264 + @Param[in] phyAddr - Phy Address on the MII bus
79265 + @Param[in] reg - Register Number.
79266 + @Param[in] data - Data to write.
79267 +
79268 + @Return E_OK on success; Error code otherwise.
79269 +
79270 + @Cautions Allowed only after FM_MAC_Init().
79271 +*//***************************************************************************/
79272 +t_Error FM_MAC_MII_WritePhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
79273 +
79274 +/**************************************************************************//**
79275 + @Function FM_MAC_MII_ReadPhyReg
79276 +
79277 + @Description Read data from Phy Register
79278 +
79279 + @Param[in] h_FmMac - A handle to a FM Module.
79280 + @Param[in] phyAddr - Phy Address on the MII bus
79281 + @Param[in] reg - Register Number.
79282 + @Param[out] p_Data - Data from PHY.
79283 +
79284 + @Return E_OK on success; Error code otherwise.
79285 +
79286 + @Cautions Allowed only after FM_MAC_Init().
79287 +*//***************************************************************************/
79288 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
79289 +
79290 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79291 +/**************************************************************************//**
79292 + @Function FM_MAC_DumpRegs
79293 +
79294 + @Description Dump internal registers
79295 +
79296 + @Param[in] h_FmMac - A handle to a FM Module.
79297 +
79298 + @Return E_OK on success; Error code otherwise.
79299 +
79300 + @Cautions Allowed only after FM_MAC_Init().
79301 +*//***************************************************************************/
79302 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac);
79303 +#endif /* (defined(DEBUG_ERRORS) && ... */
79304 +
79305 +/** @} */ /* end of FM_mac_runtime_control_grp group */
79306 +/** @} */ /* end of FM_mac_grp group */
79307 +/** @} */ /* end of FM_grp group */
79308 +
79309 +
79310 +#endif /* __FM_MAC_EXT_H */
79311 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
79312 new file mode 100644
79313 index 00000000..57925f10
79314 --- /dev/null
79315 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
79316 @@ -0,0 +1,1271 @@
79317 +/*
79318 + * Copyright 2008-2015 Freescale Semiconductor Inc.
79319 + *
79320 + * Redistribution and use in source and binary forms, with or without
79321 + * modification, are permitted provided that the following conditions are met:
79322 + * * Redistributions of source code must retain the above copyright
79323 + * notice, this list of conditions and the following disclaimer.
79324 + * * Redistributions in binary form must reproduce the above copyright
79325 + * notice, this list of conditions and the following disclaimer in the
79326 + * documentation and/or other materials provided with the distribution.
79327 + * * Neither the name of Freescale Semiconductor nor the
79328 + * names of its contributors may be used to endorse or promote products
79329 + * derived from this software without specific prior written permission.
79330 + *
79331 + *
79332 + * ALTERNATIVELY, this software may be distributed under the terms of the
79333 + * GNU General Public License ("GPL") as published by the Free Software
79334 + * Foundation, either version 2 of that License or (at your option) any
79335 + * later version.
79336 + *
79337 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
79338 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
79339 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
79340 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
79341 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
79342 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
79343 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
79344 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
79345 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
79346 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79347 + */
79348 +
79349 +/**************************************************************************//**
79350 + @File fm_macsec_ext.h
79351 +
79352 + @Description FM MACSEC ...
79353 +*//***************************************************************************/
79354 +#ifndef __FM_MACSEC_EXT_H
79355 +#define __FM_MACSEC_EXT_H
79356 +
79357 +#include "std_ext.h"
79358 +
79359 +
79360 +/**************************************************************************//**
79361 + @Group FM_grp Frame Manager API
79362 +
79363 + @Description FM API functions, definitions and enums
79364 +
79365 + @{
79366 +*//***************************************************************************/
79367 +
79368 +/**************************************************************************//**
79369 + @Group FM_MACSEC_grp FM MACSEC
79370 +
79371 + @Description FM MACSEC API functions, definitions and enums
79372 +
79373 + @{
79374 +*//***************************************************************************/
79375 +
79376 +/**************************************************************************//**
79377 + @Description MACSEC Exceptions
79378 +*//***************************************************************************/
79379 +typedef enum e_FmMacsecExceptions {
79380 + e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */
79381 + e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */
79382 +} e_FmMacsecExceptions;
79383 +
79384 +
79385 +/**************************************************************************//**
79386 + @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit
79387 +
79388 + @Description FM MACSEC Initialization Unit
79389 +
79390 + @{
79391 +*//***************************************************************************/
79392 +
79393 +/**************************************************************************//**
79394 + @Function t_FmMacsecExceptionsCallback
79395 +
79396 + @Description Exceptions user callback routine, will be called upon an
79397 + exception passing the exception identification.
79398 +
79399 + @Param[in] h_App A handle to an application layer object; This handle
79400 + will be passed by the driver upon calling this callback.
79401 + @Param[in] exception The exception.
79402 +*//***************************************************************************/
79403 +typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App,
79404 + e_FmMacsecExceptions exception);
79405 +
79406 +
79407 +/**************************************************************************//**
79408 + @Description FM MACSEC config input
79409 +*//***************************************************************************/
79410 +typedef struct t_FmMacsecParams {
79411 + t_Handle h_Fm; /**< A handle to the FM object related to */
79412 + bool guestMode; /**< Partition-id */
79413 + union {
79414 + struct {
79415 + uint8_t fmMacId; /**< FM MAC id */
79416 + } guestParams;
79417 +
79418 + struct {
79419 + uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */
79420 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
79421 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
79422 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79423 + be passed by the driver upon calling the above callbacks */
79424 + } nonGuestParams;
79425 + };
79426 +} t_FmMacsecParams;
79427 +
79428 +/**************************************************************************//**
79429 + @Function FM_MACSEC_Config
79430 +
79431 + @Description Creates descriptor for the FM MACSEC module;
79432 +
79433 + The routine returns a handle (descriptor) to the FM MACSEC object;
79434 + This descriptor must be passed as first parameter to all other
79435 + FM MACSEC function calls;
79436 +
79437 + No actual initialization or configuration of FM MACSEC hardware is
79438 + done by this routine.
79439 +
79440 + @Param[in] p_FmMacsecParam Pointer to data structure of parameters.
79441 +
79442 + @Retval Handle to FM MACSEC object, or NULL for Failure.
79443 +*//***************************************************************************/
79444 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam);
79445 +
79446 +/**************************************************************************//**
79447 + @Function FM_MACSEC_Init
79448 +
79449 + @Description Initializes the FM MACSEC module.
79450 +
79451 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79452 +
79453 + @Return E_OK on success; Error code otherwise.
79454 +*//***************************************************************************/
79455 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec);
79456 +
79457 +/**************************************************************************//**
79458 + @Function FM_MACSEC_Free
79459 +
79460 + @Description Frees all resources that were assigned to FM MACSEC module;
79461 +
79462 + Calling this routine invalidates the descriptor.
79463 +
79464 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79465 +
79466 + @Return E_OK on success; Error code otherwise.
79467 +*//***************************************************************************/
79468 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec);
79469 +
79470 +
79471 +/**************************************************************************//**
79472 + @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit
79473 +
79474 + @Description Configuration functions used to change default values.
79475 +
79476 + @{
79477 +*//***************************************************************************/
79478 +
79479 +/**************************************************************************//**
79480 + @Description enum for unknown sci frame treatment
79481 +*//***************************************************************************/
79482 +typedef enum e_FmMacsecUnknownSciFrameTreatment {
79483 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */
79484 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard
79485 + Controlled port - Check or Disable mode */
79486 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */
79487 + 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,
79488 + else discard on uncontrolled port and deliver on controlled port
79489 + Controlled port - Check or Disable mode */
79490 +} e_FmMacsecUnknownSciFrameTreatment;
79491 +
79492 +/**************************************************************************//**
79493 + @Description enum for untag frame treatment
79494 +*//***************************************************************************/
79495 +typedef enum e_FmMacsecUntagFrameTreatment {
79496 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */
79497 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */
79498 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */
79499 +} e_FmMacsecUntagFrameTreatment;
79500 +
79501 +/**************************************************************************//**
79502 + @Function FM_MACSEC_ConfigUnknownSciFrameTreatment
79503 +
79504 + @Description Change the treatment for received frames with unknown sci from its default
79505 + configuration [DEFAULT_unknownSciFrameTreatment].
79506 +
79507 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79508 + @Param[in] treatMode The selected mode.
79509 +
79510 + @Return E_OK on success; Error code otherwise.
79511 +
79512 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79513 +*//***************************************************************************/
79514 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
79515 +
79516 +/**************************************************************************//**
79517 + @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment
79518 +
79519 + @Description Change the treatment for received frames with invalid tags or
79520 + a zero value PN or an invalid ICV from its default configuration
79521 + [DEFAULT_invalidTagsFrameTreatment].
79522 +
79523 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79524 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79525 + In both cases discard on the controlled port;
79526 + this provide Strict, Check or Disable mode.
79527 +
79528 + @Return E_OK on success; Error code otherwise.
79529 +
79530 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79531 +*//***************************************************************************/
79532 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79533 +
79534 +/**************************************************************************//**
79535 + @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment
79536 +
79537 + @Description Change the treatment for received frames with the Encryption bit
79538 + set and the Changed Text bit clear from its default configuration
79539 + [DEFAULT_encryptWithNoChangedTextFrameTreatment].
79540 +
79541 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79542 + @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver;
79543 + In both cases discard on the controlled port;
79544 + this provide Strict, Check or Disable mode.
79545 +
79546 + @Return E_OK on success; Error code otherwise.
79547 +
79548 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79549 +*//***************************************************************************/
79550 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled);
79551 +
79552 +/**************************************************************************//**
79553 + @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment
79554 +
79555 + @Description Change the treatment for received frames with the Encryption bit
79556 + clear and the Changed Text bit set from its default configuration
79557 + [DEFAULT_changedTextWithNoEncryptFrameTreatment].
79558 +
79559 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79560 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79561 + In both cases discard on the controlled port;
79562 + this provide Strict, Check or Disable mode.
79563 +
79564 + @Return E_OK on success; Error code otherwise.
79565 +
79566 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79567 +*//***************************************************************************/
79568 +t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79569 +
79570 +/**************************************************************************//**
79571 + @Function FM_MACSEC_ConfigUntagFrameTreatment
79572 +
79573 + @Description Change the treatment for received frames without the MAC security tag (SecTAG)
79574 + from its default configuration [DEFAULT_untagFrameTreatment].
79575 +
79576 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79577 + @Param[in] treatMode The selected mode.
79578 +
79579 + @Return E_OK on success; Error code otherwise.
79580 +
79581 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79582 +*//***************************************************************************/
79583 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
79584 +
79585 +/**************************************************************************//**
79586 + @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment
79587 +
79588 + @Description Change the treatment for received frames with only SCB bit set
79589 + from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment].
79590 +
79591 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79592 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79593 + In both cases discard on the controlled port;
79594 + this provide Strict, Check or Disable mode.
79595 +
79596 + @Return E_OK on success; Error code otherwise.
79597 +
79598 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79599 +*//***************************************************************************/
79600 +t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79601 +
79602 +/**************************************************************************//**
79603 + @Function FM_MACSEC_ConfigPnExhaustionThreshold
79604 +
79605 + @Description It's provide the ability to configure a PN exhaustion threshold;
79606 + When the NextPn crosses this value an interrupt event
79607 + is asserted to warn that the active SA should re-key.
79608 +
79609 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79610 + @Param[in] pnExhThr If the threshold is reached, an interrupt event
79611 + is asserted to re-key.
79612 +
79613 + @Return E_OK on success; Error code otherwise.
79614 +
79615 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79616 +*//***************************************************************************/
79617 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr);
79618 +
79619 +/**************************************************************************//**
79620 + @Function FM_MACSEC_ConfigKeysUnreadable
79621 +
79622 + @Description Turn on privacy mode; All the keys and their hash values can't be read any more;
79623 + Can not be cleared unless hard reset.
79624 +
79625 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79626 +
79627 + @Return E_OK on success; Error code otherwise.
79628 +
79629 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79630 +*//***************************************************************************/
79631 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec);
79632 +
79633 +/**************************************************************************//**
79634 + @Function FM_MACSEC_ConfigSectagWithoutSCI
79635 +
79636 + @Description Promise that all generated Sectag will be without SCI included.
79637 +
79638 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79639 +
79640 + @Return E_OK on success; Error code otherwise.
79641 +
79642 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79643 +*//***************************************************************************/
79644 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec);
79645 +
79646 +/**************************************************************************//**
79647 + @Function FM_MACSEC_ConfigException
79648 +
79649 + @Description Calling this routine changes the internal driver data base
79650 + from its default selection of exceptions enablement;
79651 + By default all exceptions are enabled.
79652 +
79653 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79654 + @Param[in] exception The exception to be selected.
79655 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79656 +
79657 + @Return E_OK on success; Error code otherwise.
79658 +
79659 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79660 +*//***************************************************************************/
79661 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79662 +
79663 +/** @} */ /* end of FM_MACSEC_advanced_init_grp group */
79664 +/** @} */ /* end of FM_MACSEC_init_grp group */
79665 +
79666 +
79667 +/**************************************************************************//**
79668 + @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit
79669 +
79670 + @Description FM MACSEC runtime control data unit API functions, definitions and enums.
79671 +
79672 + @{
79673 +*//***************************************************************************/
79674 +
79675 +/**************************************************************************//**
79676 + @Function FM_MACSEC_GetRevision
79677 +
79678 + @Description Return MACSEC HW chip revision
79679 +
79680 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79681 + @Param[out] p_MacsecRevision MACSEC revision as defined by the chip.
79682 +
79683 + @Return E_OK on success; Error code otherwise.
79684 +
79685 + @Cautions Allowed only after FM_MACSEC_Init().
79686 +*//***************************************************************************/
79687 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
79688 +
79689 +/**************************************************************************//**
79690 + @Function FM_MACSEC_Enable
79691 +
79692 + @Description This routine should be called after MACSEC is initialized for enabling all
79693 + MACSEC engines according to their existing configuration.
79694 +
79695 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79696 +
79697 + @Return E_OK on success; Error code otherwise.
79698 +
79699 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled.
79700 +*//***************************************************************************/
79701 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec);
79702 +
79703 +/**************************************************************************//**
79704 + @Function FM_MACSEC_Disable
79705 +
79706 + @Description This routine may be called when MACSEC is enabled in order to
79707 + disable all MACSEC engines; The MACSEC is working in bypass mode.
79708 +
79709 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79710 +
79711 + @Return E_OK on success; Error code otherwise.
79712 +
79713 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled.
79714 +*//***************************************************************************/
79715 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec);
79716 +
79717 +/**************************************************************************//**
79718 + @Function FM_MACSEC_SetException
79719 +
79720 + @Description Calling this routine enables/disables the specified exception.
79721 +
79722 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79723 + @Param[in] exception The exception to be selected.
79724 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79725 +
79726 + @Return E_OK on success; Error code otherwise.
79727 +
79728 + @Cautions Allowed only following FM_MACSEC_Init().
79729 +*//***************************************************************************/
79730 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79731 +
79732 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79733 +/**************************************************************************//**
79734 + @Function FM_MACSEC_DumpRegs
79735 +
79736 + @Description Dump internal registers.
79737 +
79738 + @Param[in] h_FmMacsec - FM MACSEC module descriptor.
79739 +
79740 + @Return E_OK on success; Error code otherwise.
79741 +
79742 + @Cautions Allowed only after FM_MACSEC_Init().
79743 +*//***************************************************************************/
79744 +t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec);
79745 +#endif /* (defined(DEBUG_ERRORS) && ... */
79746 +
79747 +#ifdef VERIFICATION_SUPPORT
79748 +/********************* VERIFICATION ONLY ********************************/
79749 +/**************************************************************************//**
79750 + @Function FM_MACSEC_BackdoorSet
79751 +
79752 + @Description Set register of the MACSEC memory map
79753 +
79754 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79755 + @Param[out] offset Register offset.
79756 + @Param[out] value Value to write.
79757 +
79758 +
79759 + @Return None
79760 +
79761 + @Cautions Allowed only following FM_MACSEC_Init().
79762 +*//***************************************************************************/
79763 +t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value);
79764 +
79765 +/**************************************************************************//**
79766 + @Function FM_MACSEC_BackdoorGet
79767 +
79768 + @Description Read from register of the MACSEC memory map.
79769 +
79770 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79771 + @Param[out] offset Register offset.
79772 +
79773 + @Return Value read
79774 +
79775 + @Cautions Allowed only following FM_MACSEC_Init().
79776 +*//***************************************************************************/
79777 +uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset);
79778 +#endif /* VERIFICATION_SUPPORT */
79779 +
79780 +/** @} */ /* end of FM_MACSEC_runtime_control_grp group */
79781 +
79782 +
79783 +/**************************************************************************//**
79784 + @Group FM_MACSEC_SECY_grp FM-MACSEC SecY
79785 +
79786 + @Description FM-MACSEC SecY API functions, definitions and enums
79787 +
79788 + @{
79789 +*//***************************************************************************/
79790 +
79791 +typedef uint8_t macsecSAKey_t[32];
79792 +typedef uint64_t macsecSCI_t;
79793 +typedef uint8_t macsecAN_t;
79794 +
79795 +/**************************************************************************//**
79796 +@Description MACSEC SECY Cipher Suite
79797 +*//***************************************************************************/
79798 +typedef enum e_FmMacsecSecYCipherSuite {
79799 + e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */
79800 +#if (DPAA_VERSION >= 11)
79801 + e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
79802 +#endif /* (DPAA_VERSION >= 11) */
79803 +} e_FmMacsecSecYCipherSuite;
79804 +
79805 +/**************************************************************************//**
79806 + @Description MACSEC SECY Exceptions
79807 +*//***************************************************************************/
79808 +typedef enum e_FmMacsecSecYExceptions {
79809 + e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */
79810 +} e_FmMacsecSecYExceptions;
79811 +
79812 +/**************************************************************************//**
79813 + @Description MACSEC SECY Events
79814 +*//***************************************************************************/
79815 +typedef enum e_FmMacsecSecYEvents {
79816 + e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */
79817 +} e_FmMacsecSecYEvents;
79818 +
79819 +/**************************************************************************//**
79820 + @Collection MACSEC SECY Frame Discarded Descriptor error
79821 +*//***************************************************************************/
79822 +typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */
79823 +
79824 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */
79825 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */
79826 +/* @} */
79827 +
79828 +/**************************************************************************//**
79829 + @Function t_FmMacsecSecYExceptionsCallback
79830 +
79831 + @Description Exceptions user callback routine, will be called upon an
79832 + exception passing the exception identification.
79833 +
79834 + @Param[in] h_App A handle to an application layer object; This handle
79835 + will be passed by the driver upon calling this callback.
79836 + @Param[in] exception The exception.
79837 +*//***************************************************************************/
79838 +typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App,
79839 + e_FmMacsecSecYExceptions exception);
79840 +
79841 +/**************************************************************************//**
79842 + @Function t_FmMacsecSecYEventsCallback
79843 +
79844 + @Description Events user callback routine, will be called upon an
79845 + event passing the event identification.
79846 +
79847 + @Param[in] h_App A handle to an application layer object; This handle
79848 + will be passed by the driver upon calling this callback.
79849 + @Param[in] event The event.
79850 +*//***************************************************************************/
79851 +typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App,
79852 + e_FmMacsecSecYEvents event);
79853 +
79854 +/**************************************************************************//**
79855 + @Description RFC2863 MIB
79856 +*//***************************************************************************/
79857 +typedef struct t_MIBStatistics {
79858 + uint64_t ifInOctets; /**< Total number of byte received */
79859 + uint64_t ifInPkts; /**< Total number of packets received */
79860 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received */
79861 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
79862 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX :
79863 + - InPktsNoTag,
79864 + - InPktsLate,
79865 + - InPktsOverrun */
79866 + uint64_t ifInErrors; /**< Number of frames received with error:
79867 + - InPktsBadTag,
79868 + - InPktsNoSCI,
79869 + - InPktsNotUsingSA
79870 + - InPktsNotValid */
79871 + uint64_t ifOutOctets; /**< Total number of byte sent */
79872 + uint64_t ifOutPkts; /**< Total number of packets sent */
79873 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
79874 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
79875 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */
79876 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
79877 + - FIFO Overflow Error
79878 + - FIFO Underflow Error
79879 + - Other */
79880 +} t_MIBStatistics;
79881 +
79882 +/**************************************************************************//**
79883 + @Description MACSEC SecY Rx SA Statistics
79884 +*//***************************************************************************/
79885 +typedef struct t_FmMacsecSecYRxSaStatistics {
79886 + uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79887 + frame validation frame validation with the validateFrame not set to disable */
79888 + uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79889 + validation with the validateFrame set to check */
79890 + uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79891 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79892 + uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79893 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79894 + uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79895 + with validateFrame not in the strict mode and the C bit is cleared */
79896 +} t_FmMacsecSecYRxSaStatistics;
79897 +
79898 +/**************************************************************************//**
79899 + @Description MACSEC SecY Tx SA Statistics
79900 +*//***************************************************************************/
79901 +typedef struct t_FmMacsecSecYTxSaStatistics {
79902 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79903 + be transmitted, which were integrity protected */
79904 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79905 + be transmitted, which were confidentiality protected */
79906 +} t_FmMacsecSecYTxSaStatistics;
79907 +
79908 +/**************************************************************************//**
79909 + @Description MACSEC SecY Rx SC Statistics
79910 +*//***************************************************************************/
79911 +typedef struct t_FmMacsecSecYRxScStatistics {
79912 + uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79913 + that are not validated with the validateFrame set to disable */
79914 + uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79915 + that have their PN smaller than the lowest_PN with the validateFrame set to
79916 + disable or replayProtect disabled */
79917 + uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port,
79918 + that have their PN smaller than the lowest_PN with the validateFrame set to
79919 + Check or Strict and replayProtect enabled */
79920 + uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79921 + frame validation frame validation with the validateFrame not set to disable */
79922 + uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79923 + validation with the validateFrame set to check */
79924 + uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79925 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79926 + uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79927 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79928 + uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79929 + with validateFrame not in the strict mode and the C bit is cleared */
79930 +} t_FmMacsecSecYRxScStatistics;
79931 +
79932 +/**************************************************************************//**
79933 + @Description MACSEC SecY Tx SC Statistics
79934 +*//***************************************************************************/
79935 +typedef struct t_FmMacsecSecYTxScStatistics {
79936 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79937 + be transmitted, which were integrity protected */
79938 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79939 + be transmitted, which were confidentiality protected */
79940 +} t_FmMacsecSecYTxScStatistics;
79941 +
79942 +/**************************************************************************//**
79943 + @Description MACSEC SecY Statistics
79944 +*//***************************************************************************/
79945 +typedef struct t_FmMacsecSecYStatistics {
79946 + t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */
79947 + t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */
79948 +/* Frame verification statistics */
79949 + uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag
79950 + (SecTAG) with validateFrames which is not in the strict mode */
79951 + uint64_t inPktsNoTag; /**< The number of received packets discarded without the
79952 + MAC security tag (SecTAG) with validateFrames which is in the strict mode */
79953 + uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid
79954 + SecTAG or a zero value PN or an invalid ICV */
79955 + uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the
79956 + condition : validateFrames is not in the strict mode and the
79957 + C bit in the SecTAG is not set */
79958 + uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI
79959 + information with the condition : validateFrames is in the strict mode
79960 + or the C bit in the SecTAG is set */
79961 + uint64_t inPktsOverrun; /**< The number of packets discarded because the number of
79962 + received packets exceeded the cryptographic performance capabilities */
79963 +/* Frame validation statistics */
79964 + uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with
79965 + resolved SCI that were integrity protected but not encrypted */
79966 + uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with
79967 + resolved SCI that were integrity protected and encrypted */
79968 +/* Frame generation statistics */
79969 + uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to
79970 + be transmitted, with protectFrame false */
79971 + uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to
79972 + be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */
79973 +/* Frame protection statistics */
79974 + uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were
79975 + integrity protected but not encrypted */
79976 + uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were
79977 + both integrity protected and encrypted */
79978 +} t_FmMacsecSecYStatistics;
79979 +
79980 +
79981 +/**************************************************************************//**
79982 + @Description MACSEC SecY SC Params
79983 +*//***************************************************************************/
79984 +typedef struct t_FmMacsecSecYSCParams {
79985 + macsecSCI_t sci; /**< The secure channel identification of the SC */
79986 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */
79987 +} t_FmMacsecSecYSCParams;
79988 +
79989 +/**************************************************************************//**
79990 + @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit
79991 +
79992 + @Description FM-MACSEC SecY Initialization Unit
79993 +
79994 + @{
79995 +*//***************************************************************************/
79996 +
79997 +/**************************************************************************//**
79998 + @Description enum for validate frames
79999 +*//***************************************************************************/
80000 +typedef enum e_FmMacsecValidFrameBehavior {
80001 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */
80002 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking
80003 + without filtering out invalid frames */
80004 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter
80005 + out those invalid frames */
80006 +} e_FmMacsecValidFrameBehavior;
80007 +
80008 +/**************************************************************************//**
80009 + @Description enum for sci insertion
80010 +*//***************************************************************************/
80011 +typedef enum e_FmMacsecSciInsertionMode {
80012 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */
80013 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/
80014 + e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */
80015 +} e_FmMacsecSciInsertionMode;
80016 +
80017 +/**************************************************************************//**
80018 + @Description FM MACSEC SecY config input
80019 +*//***************************************************************************/
80020 +typedef struct t_FmMacsecSecYParams {
80021 + t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */
80022 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
80023 + uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */
80024 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */
80025 + t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */
80026 + t_Handle h_App; /**< A handle to an application layer object; This handle will
80027 + be passed by the driver upon calling the above callbacks */
80028 +} t_FmMacsecSecYParams;
80029 +
80030 +/**************************************************************************//**
80031 + @Function FM_MACSEC_SECY_Config
80032 +
80033 + @Description Creates descriptor for the FM MACSEC SECY module;
80034 +
80035 + The routine returns a handle (descriptor) to the FM MACSEC SECY object;
80036 + This descriptor must be passed as first parameter to all other
80037 + FM MACSEC SECY function calls;
80038 + No actual initialization or configuration of FM MACSEC SecY hardware is
80039 + done by this routine.
80040 +
80041 + @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters.
80042 +
80043 + @Return Handle to FM MACSEC SECY object, or NULL for Failure.
80044 +*//***************************************************************************/
80045 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam);
80046 +
80047 +/**************************************************************************//**
80048 + @Function FM_MACSEC_SECY_Init
80049 +
80050 + @Description Initializes the FM MACSEC SECY module.
80051 +
80052 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80053 +
80054 + @Return E_OK on success; Error code otherwise.
80055 +*//***************************************************************************/
80056 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY);
80057 +
80058 +/**************************************************************************//**
80059 + @Function FM_MACSEC_SECY_Free
80060 +
80061 + @Description Frees all resources that were assigned to FM MACSEC SECY module.
80062 +
80063 + Calling this routine invalidates the descriptor.
80064 +
80065 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80066 +
80067 + @Return E_OK on success; Error code otherwise.
80068 +*//***************************************************************************/
80069 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY);
80070 +
80071 +/**************************************************************************//**
80072 + @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit
80073 +
80074 + @Description Configuration functions used to change default values.
80075 +
80076 + @{
80077 +*//***************************************************************************/
80078 +
80079 +/**************************************************************************//**
80080 + @Function FM_MACSEC_SECY_ConfigSciInsertionMode
80081 +
80082 + @Description Calling this routine changes the SCI-insertion-mode in the
80083 + internal driver data base from its default configuration
80084 + [DEFAULT_sciInsertionMode]
80085 +
80086 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80087 + @Param[in] sciInsertionMode Sci insertion mode
80088 +
80089 + @Return E_OK on success; Error code otherwise.
80090 +
80091 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80092 +
80093 +*//***************************************************************************/
80094 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode);
80095 +
80096 +/**************************************************************************//**
80097 + @Function FM_MACSEC_SECY_ConfigProtectFrames
80098 +
80099 + @Description Calling this routine changes the protect-frame mode in the
80100 + internal driver data base from its default configuration
80101 + [DEFAULT_protectFrames]
80102 +
80103 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80104 + @Param[in] protectFrames If FALSE, frames are transmitted without modification
80105 +
80106 + @Return E_OK on success; Error code otherwise.
80107 +
80108 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80109 +
80110 +*//***************************************************************************/
80111 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames);
80112 +
80113 +/**************************************************************************//**
80114 + @Function FM_MACSEC_SECY_ConfigReplayWindow
80115 +
80116 + @Description Calling this routine changes the replay-window settings in the
80117 + internal driver data base from its default configuration
80118 + [DEFAULT_replayEnable], [DEFAULT_replayWindow]
80119 +
80120 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80121 + @Param[in] replayProtect; Replay protection function mode
80122 + @Param[in] replayWindow; The size of the replay window
80123 +
80124 + @Return E_OK on success; Error code otherwise.
80125 +
80126 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80127 +
80128 +*//***************************************************************************/
80129 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow);
80130 +
80131 +/**************************************************************************//**
80132 + @Function FM_MACSEC_SECY_ConfigValidationMode
80133 +
80134 + @Description Calling this routine changes the frame-validation-behavior mode
80135 + in the internal driver data base from its default configuration
80136 + [DEFAULT_validateFrames]
80137 +
80138 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80139 + @Param[in] validateFrames Validation function mode
80140 +
80141 + @Return E_OK on success; Error code otherwise.
80142 +
80143 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80144 +
80145 +*//***************************************************************************/
80146 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames);
80147 +
80148 +/**************************************************************************//**
80149 + @Function FM_MACSEC_SECY_ConfigConfidentiality
80150 +
80151 + @Description Calling this routine changes the confidentiality settings in the
80152 + internal driver data base from its default configuration
80153 + [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset]
80154 +
80155 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80156 + @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection
80157 + FALSE - no confidentiality protection, only integrity protection
80158 + @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection
80159 + common values are 0, 30, and 50
80160 +
80161 + @Return E_OK on success; Error code otherwise.
80162 +
80163 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80164 +
80165 +*//***************************************************************************/
80166 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset);
80167 +
80168 +/**************************************************************************//**
80169 + @Function FM_MACSEC_SECY_ConfigPointToPoint
80170 +
80171 + @Description configure this SecY to work in point-to-point mode, means that
80172 + it will have only one rx sc;
80173 +
80174 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80175 +
80176 + @Return E_OK on success; Error code otherwise.
80177 +
80178 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80179 + Can be called only once in a system; only the first secY that will call this
80180 + routine will be able to operate in Point-To-Point mode.
80181 +*//***************************************************************************/
80182 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY);
80183 +
80184 +/**************************************************************************//**
80185 + @Function FM_MACSEC_SECY_ConfigException
80186 +
80187 + @Description Calling this routine changes the internal driver data base
80188 + from its default selection of exceptions enablement;
80189 + By default all exceptions are enabled.
80190 +
80191 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80192 + @Param[in] exception The exception to be selected.
80193 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80194 +
80195 + @Return E_OK on success; Error code otherwise.
80196 +
80197 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80198 +*//***************************************************************************/
80199 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable);
80200 +
80201 +/**************************************************************************//**
80202 + @Function FM_MACSEC_SECY_ConfigEvent
80203 +
80204 + @Description Calling this routine changes the internal driver data base
80205 + from its default selection of events enablement;
80206 + By default all events are enabled.
80207 +
80208 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80209 + @Param[in] event The event to be selected.
80210 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80211 +
80212 + @Return E_OK on success; Error code otherwise.
80213 +
80214 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80215 +*//***************************************************************************/
80216 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
80217 +
80218 +/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */
80219 +/** @} */ /* end of FM_MACSEC_SECY_init_grp group */
80220 +
80221 +
80222 +/**************************************************************************//**
80223 + @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit
80224 +
80225 + @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums.
80226 +
80227 + @{
80228 +*//***************************************************************************/
80229 +
80230 +/**************************************************************************//**
80231 + @Function FM_MACSEC_SECY_CreateRxSc
80232 +
80233 + @Description Create a receive secure channel.
80234 +
80235 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80236 + @Param[in] scParams secure channel params.
80237 +
80238 + @Return E_OK on success; Error code otherwise.
80239 +
80240 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80241 +*//***************************************************************************/
80242 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams);
80243 +
80244 +/**************************************************************************//**
80245 + @Function FM_MACSEC_SECY_DeleteRxSc
80246 +
80247 + @Description Deleting an initialized secure channel.
80248 +
80249 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80250 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80251 +
80252 + @Return E_OK on success; Error code otherwise.
80253 +
80254 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80255 +*//***************************************************************************/
80256 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc);
80257 +
80258 +/**************************************************************************//**
80259 + @Function FM_MACSEC_SECY_CreateRxSa
80260 +
80261 + @Description Create a receive secure association for the secure channel;
80262 + the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called.
80263 +
80264 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80265 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80266 + @Param[in] an association number represent the SA.
80267 + @Param[in] lowestPn the lowest acceptable PN value for a received frame.
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_CreateRxSc().
80273 +*//***************************************************************************/
80274 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
80275 +
80276 +/**************************************************************************//**
80277 + @Function FM_MACSEC_SECY_DeleteRxSa
80278 +
80279 + @Description Deleting an initialized secure association.
80280 +
80281 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80282 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80283 + @Param[in] an association number represent the SA.
80284 +
80285 + @Return E_OK on success; Error code otherwise.
80286 +
80287 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80288 +*//***************************************************************************/
80289 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
80290 +
80291 +/**************************************************************************//**
80292 + @Function FM_MACSEC_SECY_RxSaEnableReceive
80293 +
80294 + @Description Enabling the SA to receive frames.
80295 +
80296 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80297 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80298 + @Param[in] an association number represent the SA.
80299 +
80300 + @Return E_OK on success; Error code otherwise.
80301 +
80302 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80303 +*//***************************************************************************/
80304 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
80305 +
80306 +/**************************************************************************//**
80307 + @Function FM_MACSEC_SECY_RxSaDisableReceive
80308 +
80309 + @Description Disabling the SA from receive frames.
80310 +
80311 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80312 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80313 + @Param[in] an association number represent the SA.
80314 +
80315 + @Return E_OK on success; Error code otherwise.
80316 +
80317 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80318 +*//***************************************************************************/
80319 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
80320 +
80321 +/**************************************************************************//**
80322 + @Function FM_MACSEC_SECY_RxSaUpdateNextPn
80323 +
80324 + @Description Update the next packet number expected on RX;
80325 + The value of nextPN shall be set to the greater of its existing value and the
80326 + supplied of updtNextPN (802.1AE-2006 10.7.15).
80327 +
80328 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80329 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80330 + @Param[in] an association number represent the SA.
80331 + @Param[in] updtNextPN the next PN value for a received frame.
80332 +
80333 + @Return E_OK on success; Error code otherwise.
80334 +
80335 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80336 +*//***************************************************************************/
80337 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN);
80338 +
80339 +/**************************************************************************//**
80340 + @Function FM_MACSEC_SECY_RxSaUpdateLowestPn
80341 +
80342 + @Description Update the lowest packet number expected on RX;
80343 + The value of lowestPN shall be set to the greater of its existing value and the
80344 + supplied of updtLowestPN (802.1AE-2006 10.7.15).
80345 +
80346 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80347 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80348 + @Param[in] an association number represent the SA.
80349 + @Param[in] updtLowestPN the lowest PN acceptable value for a received frame.
80350 +
80351 + @Return E_OK on success; Error code otherwise.
80352 +
80353 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80354 +*//***************************************************************************/
80355 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN);
80356 +
80357 +/**************************************************************************//**
80358 + @Function FM_MACSEC_SECY_RxSaModifyKey
80359 +
80360 + @Description Modify the current key of the SA with a new one.
80361 +
80362 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80363 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80364 + @Param[in] an association number represent the SA.
80365 + @Param[in] key new key to replace the current key.
80366 +
80367 + @Return E_OK on success; Error code otherwise.
80368 +
80369 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80370 +*//***************************************************************************/
80371 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key);
80372 +
80373 +/**************************************************************************//**
80374 + @Function FM_MACSEC_SECY_CreateTxSa
80375 +
80376 + @Description Create a transmit secure association for the secure channel;
80377 + the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called;
80378 + Only one SA can be active at a time.
80379 +
80380 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80381 + @Param[in] an association number represent the SA.
80382 + @Param[in] key the desired key for this SA.
80383 +
80384 + @Return E_OK on success; Error code otherwise.
80385 +
80386 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80387 +*//***************************************************************************/
80388 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key);
80389 +
80390 +/**************************************************************************//**
80391 + @Function FM_MACSEC_SECY_DeleteTxSa
80392 +
80393 + @Description Deleting an initialized secure association.
80394 +
80395 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80396 + @Param[in] an association number represent the SA.
80397 +
80398 + @Return E_OK on success; Error code otherwise.
80399 +
80400 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80401 +*//***************************************************************************/
80402 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an);
80403 +
80404 +/**************************************************************************//**
80405 + @Function FM_MACSEC_SECY_TxSaModifyKey
80406 +
80407 + @Description Modify the key of the inactive SA with a new one.
80408 +
80409 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80410 + @Param[in] nextActiveAn association number represent the next SA to be activated.
80411 + @Param[in] key new key to replace the current key.
80412 +
80413 + @Return E_OK on success; Error code otherwise.
80414 +
80415 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80416 +*//***************************************************************************/
80417 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key);
80418 +
80419 +/**************************************************************************//**
80420 + @Function FM_MACSEC_SECY_TxSaSetActive
80421 +
80422 + @Description Set this SA to the active SA to be used on TX for SC;
80423 + only one SA can be active at a time.
80424 +
80425 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80426 + @Param[in] an association number represent the SA.
80427 +
80428 + @Return E_OK on success; Error code otherwise.
80429 +
80430 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80431 +*//***************************************************************************/
80432 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an);
80433 +
80434 +/**************************************************************************//**
80435 + @Function FM_MACSEC_SECY_TxSaGetActive
80436 +
80437 + @Description Get the active SA that being used for TX.
80438 +
80439 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80440 + @Param[out] p_An the active an.
80441 +
80442 + @Return E_OK on success; Error code otherwise.
80443 +
80444 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80445 +*//***************************************************************************/
80446 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An);
80447 +
80448 +/**************************************************************************//**
80449 + @Function FM_MACSEC_SECY_GetStatistics
80450 +
80451 + @Description get all statistics counters.
80452 +
80453 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80454 + @Param[in] p_Statistics Structure with statistics.
80455 +
80456 + @Return E_OK on success; Error code otherwise.
80457 +
80458 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80459 +*//***************************************************************************/
80460 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics);
80461 +
80462 +/**************************************************************************//**
80463 + @Function FM_MACSEC_SECY_RxScGetStatistics
80464 +
80465 + @Description get all statistics counters.
80466 +
80467 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80468 + @Param[in] h_Sc Rx Sc handle.
80469 + @Param[in] p_Statistics Structure with statistics.
80470 +
80471 + @Return E_OK on success; Error code otherwise.
80472 +
80473 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80474 +*//***************************************************************************/
80475 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics);
80476 +
80477 +/**************************************************************************//**
80478 + @Function FM_MACSEC_SECY_RxSaGetStatistics
80479 +
80480 + @Description get all statistics counters
80481 +
80482 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80483 + @Param[in] h_Sc Rx Sc handle.
80484 + @Param[in] an association number represent the SA.
80485 + @Param[in] p_Statistics Structure with statistics.
80486 +
80487 + @Return E_OK on success; Error code otherwise.
80488 +
80489 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80490 +*//***************************************************************************/
80491 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics);
80492 +
80493 +/**************************************************************************//**
80494 + @Function FM_MACSEC_SECY_TxScGetStatistics
80495 +
80496 + @Description get all statistics counters.
80497 +
80498 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80499 + @Param[in] p_Statistics Structure with statistics.
80500 +
80501 + @Return E_OK on success; Error code otherwise.
80502 +
80503 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80504 +*//***************************************************************************/
80505 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics);
80506 +
80507 +/**************************************************************************//**
80508 + @Function FM_MACSEC_SECY_TxSaGetStatistics
80509 +
80510 + @Description get all statistics counters.
80511 +
80512 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80513 + @Param[in] an association number represent the SA.
80514 + @Param[in] p_Statistics Structure with statistics.
80515 +
80516 + @Return E_OK on success; Error code otherwise.
80517 +
80518 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80519 +*//***************************************************************************/
80520 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics);
80521 +
80522 +/**************************************************************************//**
80523 + @Function FM_MACSEC_SECY_SetException
80524 +
80525 + @Description Calling this routine enables/disables the specified exception.
80526 +
80527 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80528 + @Param[in] exception The exception to be selected.
80529 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80530 +
80531 + @Return E_OK on success; Error code otherwise.
80532 +
80533 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80534 +*//***************************************************************************/
80535 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable);
80536 +
80537 +/**************************************************************************//**
80538 + @Function FM_MACSEC_SECY_SetEvent
80539 +
80540 + @Description Calling this routine enables/disables the specified event.
80541 +
80542 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80543 + @Param[in] event The event to be selected.
80544 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80545 +
80546 + @Return E_OK on success; Error code otherwise.
80547 +
80548 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80549 +*//***************************************************************************/
80550 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
80551 +
80552 +/**************************************************************************//**
80553 + @Function FM_MACSEC_SECY_GetRxScPhysId
80554 +
80555 + @Description return the physical id of the Secure Channel.
80556 +
80557 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80558 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80559 + @Param[out] p_ScPhysId the SC physical id.
80560 +
80561 + @Return E_OK on success; Error code otherwise.
80562 +
80563 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80564 +*//***************************************************************************/
80565 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId);
80566 +
80567 +/**************************************************************************//**
80568 + @Function FM_MACSEC_SECY_GetTxScPhysId
80569 +
80570 + @Description return the physical id of the Secure Channel.
80571 +
80572 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80573 + @Param[out] p_ScPhysId the SC physical id.
80574 +
80575 + @Return E_OK on success; Error code otherwise.
80576 +
80577 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80578 +*//***************************************************************************/
80579 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId);
80580 +
80581 +/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */
80582 +/** @} */ /* end of FM_MACSEC_SECY_grp group */
80583 +/** @} */ /* end of FM_MACSEC_grp group */
80584 +/** @} */ /* end of FM_grp group */
80585 +
80586 +
80587 +#endif /* __FM_MACSEC_EXT_H */
80588 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
80589 new file mode 100644
80590 index 00000000..ef62c8ef
80591 --- /dev/null
80592 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
80593 @@ -0,0 +1,170 @@
80594 +/*
80595 + * Copyright 2008-2012 Freescale Semiconductor Inc.
80596 + *
80597 + * Redistribution and use in source and binary forms, with or without
80598 + * modification, are permitted provided that the following conditions are met:
80599 + * * Redistributions of source code must retain the above copyright
80600 + * notice, this list of conditions and the following disclaimer.
80601 + * * Redistributions in binary form must reproduce the above copyright
80602 + * notice, this list of conditions and the following disclaimer in the
80603 + * documentation and/or other materials provided with the distribution.
80604 + * * Neither the name of Freescale Semiconductor nor the
80605 + * names of its contributors may be used to endorse or promote products
80606 + * derived from this software without specific prior written permission.
80607 + *
80608 + *
80609 + * ALTERNATIVELY, this software may be distributed under the terms of the
80610 + * GNU General Public License ("GPL") as published by the Free Software
80611 + * Foundation, either version 2 of that License or (at your option) any
80612 + * later version.
80613 + *
80614 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80615 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80616 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80617 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80618 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80619 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80620 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80621 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80622 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80623 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80624 + */
80625 +
80626 +
80627 +/**************************************************************************//**
80628 + @File fm_muram_ext.h
80629 +
80630 + @Description FM MURAM Application Programming Interface.
80631 +*//***************************************************************************/
80632 +#ifndef __FM_MURAM_EXT
80633 +#define __FM_MURAM_EXT
80634 +
80635 +#include "error_ext.h"
80636 +#include "std_ext.h"
80637 +
80638 +
80639 +/**************************************************************************//**
80640 +
80641 + @Group FM_grp Frame Manager API
80642 +
80643 + @Description FM API functions, definitions and enums
80644 +
80645 + @{
80646 +*//***************************************************************************/
80647 +
80648 +/**************************************************************************//**
80649 + @Group FM_muram_grp FM MURAM
80650 +
80651 + @Description FM MURAM API functions, definitions and enums
80652 +
80653 + @{
80654 +*//***************************************************************************/
80655 +
80656 +/**************************************************************************//**
80657 + @Group FM_muram_init_grp FM MURAM Initialization Unit
80658 +
80659 + @Description FM MURAM initialization API functions, definitions and enums
80660 +
80661 + @{
80662 +*//***************************************************************************/
80663 +
80664 +/**************************************************************************//**
80665 + @Function FM_MURAM_ConfigAndInit
80666 +
80667 + @Description Creates partition in the MURAM.
80668 +
80669 + The routine returns a handle (descriptor) to the MURAM partition.
80670 + This descriptor must be passed as first parameter to all other
80671 + FM-MURAM function calls.
80672 +
80673 + No actual initialization or configuration of FM_MURAM hardware is
80674 + done by this routine.
80675 +
80676 + @Param[in] baseAddress - Pointer to base of memory mapped FM-MURAM.
80677 + @Param[in] size - Size of the FM-MURAM partition.
80678 +
80679 + @Return Handle to FM-MURAM object, or NULL for Failure.
80680 +*//***************************************************************************/
80681 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size);
80682 +
80683 +/**************************************************************************//**
80684 + @Function FM_MURAM_Free
80685 +
80686 + @Description Frees all resources that were assigned to FM-MURAM module.
80687 +
80688 + Calling this routine invalidates the descriptor.
80689 +
80690 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80691 +
80692 + @Return E_OK on success; Error code otherwise.
80693 +*//***************************************************************************/
80694 +t_Error FM_MURAM_Free(t_Handle h_FmMuram);
80695 +
80696 +/** @} */ /* end of FM_muram_init_grp group */
80697 +
80698 +
80699 +/**************************************************************************//**
80700 + @Group FM_muram_ctrl_grp FM MURAM Control Unit
80701 +
80702 + @Description FM MURAM control API functions, definitions and enums
80703 +
80704 + @{
80705 +*//***************************************************************************/
80706 +
80707 +/**************************************************************************//**
80708 + @Function FM_MURAM_AllocMem
80709 +
80710 + @Description Allocate some memory from FM-MURAM partition.
80711 +
80712 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80713 + @Param[in] size - size of the memory to be allocated.
80714 + @Param[in] align - Alignment of the memory.
80715 +
80716 + @Return address of the allocated memory; NULL otherwise.
80717 +*//***************************************************************************/
80718 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align);
80719 +
80720 +/**************************************************************************//**
80721 + @Function FM_MURAM_AllocMemForce
80722 +
80723 + @Description Allocate some specific memory from FM-MURAM partition (according
80724 + to base).
80725 +
80726 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80727 + @Param[in] base - the desired base-address to be allocated.
80728 + @Param[in] size - size of the memory to be allocated.
80729 +
80730 + @Return address of the allocated memory; NULL otherwise.
80731 +*//***************************************************************************/
80732 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size);
80733 +
80734 +/**************************************************************************//**
80735 + @Function FM_MURAM_FreeMem
80736 +
80737 + @Description Free an allocated memory from FM-MURAM partition.
80738 +
80739 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80740 + @Param[in] ptr - A pointer to an allocated memory.
80741 +
80742 + @Return E_OK on success; Error code otherwise.
80743 +*//***************************************************************************/
80744 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr);
80745 +
80746 +/**************************************************************************//**
80747 + @Function FM_MURAM_GetFreeMemSize
80748 +
80749 + @Description Returns the size (in bytes) of free MURAM memory.
80750 +
80751 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80752 +
80753 + @Return Free MURAM memory size in bytes.
80754 +*//***************************************************************************/
80755 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram);
80756 +
80757 +/** @} */ /* end of FM_muram_ctrl_grp group */
80758 +/** @} */ /* end of FM_muram_grp group */
80759 +/** @} */ /* end of FM_grp group */
80760 +
80761 +
80762 +
80763 +#endif /* __FM_MURAM_EXT */
80764 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
80765 new file mode 100644
80766 index 00000000..8d1c3d88
80767 --- /dev/null
80768 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
80769 @@ -0,0 +1,3974 @@
80770 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
80771 + * All rights reserved.
80772 + *
80773 + * Redistribution and use in source and binary forms, with or without
80774 + * modification, are permitted provided that the following conditions are met:
80775 + * * Redistributions of source code must retain the above copyright
80776 + * notice, this list of conditions and the following disclaimer.
80777 + * * Redistributions in binary form must reproduce the above copyright
80778 + * notice, this list of conditions and the following disclaimer in the
80779 + * documentation and/or other materials provided with the distribution.
80780 + * * Neither the name of Freescale Semiconductor nor the
80781 + * names of its contributors may be used to endorse or promote products
80782 + * derived from this software without specific prior written permission.
80783 + *
80784 + *
80785 + * ALTERNATIVELY, this software may be distributed under the terms of the
80786 + * GNU General Public License ("GPL") as published by the Free Software
80787 + * Foundation, either version 2 of that License or (at your option) any
80788 + * later version.
80789 + *
80790 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80791 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80792 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80793 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80794 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80795 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80796 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80797 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80798 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80799 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80800 + */
80801 +
80802 +
80803 +/**************************************************************************//**
80804 + @File fm_pcd_ext.h
80805 +
80806 + @Description FM PCD API definitions
80807 +*//***************************************************************************/
80808 +#ifndef __FM_PCD_EXT
80809 +#define __FM_PCD_EXT
80810 +
80811 +#include "std_ext.h"
80812 +#include "net_ext.h"
80813 +#include "list_ext.h"
80814 +#include "fm_ext.h"
80815 +#include "fsl_fman_kg.h"
80816 +
80817 +
80818 +/**************************************************************************//**
80819 + @Group FM_grp Frame Manager API
80820 +
80821 + @Description Frame Manager Application Programming Interface
80822 +
80823 + @{
80824 +*//***************************************************************************/
80825 +
80826 +/**************************************************************************//**
80827 + @Group FM_PCD_grp FM PCD
80828 +
80829 + @Description Frame Manager PCD (Parse-Classify-Distribute) API.
80830 +
80831 + The FM PCD module is responsible for the initialization of all
80832 + global classifying FM modules. This includes the parser general and
80833 + common registers, the key generator global and common registers,
80834 + and the policer global and common registers.
80835 + In addition, the FM PCD SW module will initialize all required
80836 + key generator schemes, coarse classification flows, and policer
80837 + profiles. When FM module is configured to work with one of these
80838 + entities, it will register to it using the FM PORT API. The PCD
80839 + module will manage the PCD resources - i.e. resource management of
80840 + KeyGen schemes, etc.
80841 +
80842 + @{
80843 +*//***************************************************************************/
80844 +
80845 +/**************************************************************************//**
80846 + @Collection General PCD defines
80847 +*//***************************************************************************/
80848 +#define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
80849 +
80850 +#define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
80851 +#define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
80852 + /**< Number of distinction units is limited by
80853 + register size (32 bits) minus reserved bits
80854 + for private headers. */
80855 +#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
80856 + in a distinction unit */
80857 +#define FM_PCD_KG_NUM_OF_GENERIC_REGS FM_KG_NUM_OF_GENERIC_REGS /**< Total number of generic KeyGen registers */
80858 +#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
80859 + For HW implementation reasons, in most
80860 + cases less than this will be allowed; The
80861 + driver will return an initialization error
80862 + if resource is unavailable. */
80863 +#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
80864 +#define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
80865 +
80866 +#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
80867 +#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)
80868 + /**< Maximum size of SW parser code */
80869 +
80870 +#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
80871 + insert manipulation */
80872 +
80873 +#if (DPAA_VERSION >= 11)
80874 +#define FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
80875 +#endif /* (DPAA_VERSION >= 11) */
80876 +/* @} */
80877 +
80878 +
80879 +/**************************************************************************//**
80880 + @Group FM_PCD_init_grp FM PCD Initialization Unit
80881 +
80882 + @Description Frame Manager PCD Initialization Unit API
80883 +
80884 + @{
80885 +*//***************************************************************************/
80886 +
80887 +/**************************************************************************//**
80888 + @Description PCD counters
80889 +*//***************************************************************************/
80890 +typedef enum e_FmPcdCounters {
80891 + e_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
80892 + e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
80893 + e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
80894 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
80895 + This is a subset of e_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
80896 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
80897 + This is a subset of e_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
80898 + e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
80899 + e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
80900 + e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
80901 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
80902 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
80903 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
80904 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
80905 + 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. */
80906 + 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. */
80907 + 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. */
80908 + 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. */
80909 + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
80910 + 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. */
80911 + 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). */
80912 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
80913 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
80914 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
80915 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
80916 + e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
80917 +} e_FmPcdCounters;
80918 +
80919 +/**************************************************************************//**
80920 + @Description PCD interrupts
80921 +*//***************************************************************************/
80922 +typedef enum e_FmPcdExceptions {
80923 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
80924 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
80925 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
80926 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
80927 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
80928 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
80929 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
80930 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
80931 +} e_FmPcdExceptions;
80932 +
80933 +
80934 +/**************************************************************************//**
80935 + @Description Exceptions user callback routine, will be called upon an
80936 + exception passing the exception identification.
80937 +
80938 + @Param[in] h_App - User's application descriptor.
80939 + @Param[in] exception - The exception.
80940 + *//***************************************************************************/
80941 +typedef void (t_FmPcdExceptionCallback) (t_Handle h_App, e_FmPcdExceptions exception);
80942 +
80943 +/**************************************************************************//**
80944 + @Description Exceptions user callback routine, will be called upon an exception
80945 + passing the exception identification.
80946 +
80947 + @Param[in] h_App - User's application descriptor.
80948 + @Param[in] exception - The exception.
80949 + @Param[in] index - id of the relevant source (may be scheme or profile id).
80950 + *//***************************************************************************/
80951 +typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App,
80952 + e_FmPcdExceptions exception,
80953 + uint16_t index);
80954 +
80955 +/**************************************************************************//**
80956 + @Description A callback for enqueuing frame onto a QM queue.
80957 +
80958 + @Param[in] h_QmArg - Application's handle passed to QM module on enqueue.
80959 + @Param[in] p_Fd - Frame descriptor for the frame.
80960 +
80961 + @Return E_OK on success; Error code otherwise.
80962 + *//***************************************************************************/
80963 +typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd);
80964 +
80965 +/**************************************************************************//**
80966 + @Description Host-Command parameters structure.
80967 +
80968 + When using Host command for PCD functionalities, a dedicated port
80969 + must be used. If this routine is called for a PCD in a single partition
80970 + environment, or it is the Master partition in a Multi-partition
80971 + environment, The port will be initialized by the PCD driver
80972 + initialization routine.
80973 + *//***************************************************************************/
80974 +typedef struct t_FmPcdHcParams {
80975 + uintptr_t portBaseAddr; /**< Virtual Address of Host-Command Port memory mapped registers.*/
80976 + uint8_t portId; /**< Port Id (0-6 relative to Host-Command/Offline-Parsing ports);
80977 + NOTE: When configuring Host Command port for
80978 + FMANv3 devices (DPAA_VERSION 11 and higher),
80979 + portId=0 MUST be used. */
80980 + uint16_t liodnBase; /**< LIODN base for this port, to be used together with LIODN offset
80981 + (irrelevant for P4080 revision 1.0) */
80982 + uint32_t errFqid; /**< Host-Command Port error queue Id. */
80983 + uint32_t confFqid; /**< Host-Command Port confirmation queue Id. */
80984 + uint32_t qmChannel; /**< QM channel dedicated to this Host-Command port;
80985 + will be used by the FM for dequeue. */
80986 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Callback routine for enqueuing a frame to the QM */
80987 + t_Handle h_QmArg; /**< Application's handle passed to QM module on enqueue */
80988 +} t_FmPcdHcParams;
80989 +
80990 +/**************************************************************************//**
80991 + @Description The main structure for PCD initialization
80992 + *//***************************************************************************/
80993 +typedef struct t_FmPcdParams {
80994 + bool prsSupport; /**< TRUE if Parser will be used for any of the FM ports. */
80995 + bool ccSupport; /**< TRUE if Coarse Classification will be used for any
80996 + of the FM ports. */
80997 + bool kgSupport; /**< TRUE if KeyGen will be used for any of the FM ports. */
80998 + bool plcrSupport; /**< TRUE if Policer will be used for any of the FM ports. */
80999 + t_Handle h_Fm; /**< A handle to the FM module. */
81000 + uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition.
81001 + this parameter is relevant if 'kgSupport'=TRUE. */
81002 + bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */
81003 + t_FmPcdHcParams hc; /**< Host Command parameters, relevant only if 'useHostCommand'=TRUE;
81004 + Relevant when FM not runs in "guest-mode". */
81005 +
81006 + t_FmPcdExceptionCallback *f_Exception; /**< Callback routine for general PCD exceptions;
81007 + Relevant when FM not runs in "guest-mode". */
81008 + t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Callback routine for specific KeyGen scheme or
81009 + Policer profile exceptions;
81010 + Relevant when FM not runs in "guest-mode". */
81011 + t_Handle h_App; /**< A handle to an application layer object; This handle will
81012 + be passed by the driver upon calling the above callbacks;
81013 + Relevant when FM not runs in "guest-mode". */
81014 + uint8_t partPlcrProfilesBase; /**< The first policer-profile-id dedicated to this partition.
81015 + this parameter is relevant if 'plcrSupport'=TRUE.
81016 + NOTE: this parameter relevant only when working with multiple partitions. */
81017 + uint16_t partNumOfPlcrProfiles; /**< Number of policer-profiles dedicated to this partition.
81018 + this parameter is relevant if 'plcrSupport'=TRUE.
81019 + NOTE: this parameter relevant only when working with multiple partitions. */
81020 +} t_FmPcdParams;
81021 +
81022 +
81023 +/**************************************************************************//**
81024 + @Function FM_PCD_Config
81025 +
81026 + @Description Basic configuration of the PCD module.
81027 + Creates descriptor for the FM PCD module.
81028 +
81029 + @Param[in] p_FmPcdParams A structure of parameters for the initialization of PCD.
81030 +
81031 + @Return A handle to the initialized module.
81032 +*//***************************************************************************/
81033 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams);
81034 +
81035 +/**************************************************************************//**
81036 + @Function FM_PCD_Init
81037 +
81038 + @Description Initialization of the PCD module.
81039 +
81040 + @Param[in] h_FmPcd - FM PCD module descriptor.
81041 +
81042 + @Return E_OK on success; Error code otherwise.
81043 +*//***************************************************************************/
81044 +t_Error FM_PCD_Init(t_Handle h_FmPcd);
81045 +
81046 +/**************************************************************************//**
81047 + @Function FM_PCD_Free
81048 +
81049 + @Description Frees all resources that were assigned to FM module.
81050 +
81051 + Calling this routine invalidates the descriptor.
81052 +
81053 + @Param[in] h_FmPcd - FM PCD module descriptor.
81054 +
81055 + @Return E_OK on success; Error code otherwise.
81056 +*//***************************************************************************/
81057 +t_Error FM_PCD_Free(t_Handle h_FmPcd);
81058 +
81059 +/**************************************************************************//**
81060 + @Group FM_PCD_advanced_cfg_grp FM PCD Advanced Configuration Unit
81061 +
81062 + @Description Frame Manager PCD Advanced Configuration API.
81063 +
81064 + @{
81065 +*//***************************************************************************/
81066 +
81067 +/**************************************************************************//**
81068 + @Function FM_PCD_ConfigException
81069 +
81070 + @Description Calling this routine changes the internal driver data base
81071 + from its default selection of exceptions enabling.
81072 + [DEFAULT_numOfSharedPlcrProfiles].
81073 +
81074 + @Param[in] h_FmPcd FM PCD module descriptor.
81075 + @Param[in] exception The exception to be selected.
81076 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81077 +
81078 + @Return E_OK on success; Error code otherwise.
81079 +
81080 + @Cautions This routine should NOT be called from guest-partition
81081 + (i.e. guestId != NCSW_MASTER_ID)
81082 +*//***************************************************************************/
81083 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
81084 +
81085 +/**************************************************************************//**
81086 + @Function FM_PCD_ConfigHcFramesDataMemory
81087 +
81088 + @Description Configures memory-partition-id for FMan-Controller Host-Command
81089 + frames. Calling this routine changes the internal driver data
81090 + base from its default configuration [0].
81091 +
81092 + @Param[in] h_FmPcd FM PCD module descriptor.
81093 + @Param[in] memId Memory partition ID.
81094 +
81095 + @Return E_OK on success; Error code otherwise.
81096 +
81097 + @Cautions This routine may be called only if 'useHostCommand' was TRUE
81098 + when FM_PCD_Config() routine was called.
81099 +*//***************************************************************************/
81100 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId);
81101 +
81102 +/**************************************************************************//**
81103 + @Function FM_PCD_ConfigPlcrNumOfSharedProfiles
81104 +
81105 + @Description Calling this routine changes the internal driver data base
81106 + from its default selection of exceptions enablement.
81107 + [DEFAULT_numOfSharedPlcrProfiles].
81108 +
81109 + @Param[in] h_FmPcd FM PCD module descriptor.
81110 + @Param[in] numOfSharedPlcrProfiles Number of profiles to
81111 + be shared between ports on this partition
81112 +
81113 + @Return E_OK on success; Error code otherwise.
81114 +*//***************************************************************************/
81115 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles);
81116 +
81117 +/**************************************************************************//**
81118 + @Function FM_PCD_ConfigPlcrAutoRefreshMode
81119 +
81120 + @Description Calling this routine changes the internal driver data base
81121 + from its default selection of exceptions enablement.
81122 + By default auto-refresh is [DEFAULT_plcrAutoRefresh].
81123 +
81124 + @Param[in] h_FmPcd FM PCD module descriptor.
81125 + @Param[in] enable TRUE to enable, FALSE to disable
81126 +
81127 + @Return E_OK on success; Error code otherwise.
81128 +
81129 + @Cautions This routine should NOT be called from guest-partition
81130 + (i.e. guestId != NCSW_MASTER_ID)
81131 +*//***************************************************************************/
81132 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable);
81133 +
81134 +/**************************************************************************//**
81135 + @Function FM_PCD_ConfigPrsMaxCycleLimit
81136 +
81137 + @Description Calling this routine changes the internal data structure for
81138 + the maximum parsing time from its default value
81139 + [DEFAULT_MAX_PRS_CYC_LIM].
81140 +
81141 + @Param[in] h_FmPcd FM PCD module descriptor.
81142 + @Param[in] value 0 to disable the mechanism, or new
81143 + maximum parsing time.
81144 +
81145 + @Return E_OK on success; Error code otherwise.
81146 +
81147 + @Cautions This routine should NOT be called from guest-partition
81148 + (i.e. guestId != NCSW_MASTER_ID)
81149 +*//***************************************************************************/
81150 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value);
81151 +
81152 +/** @} */ /* end of FM_PCD_advanced_cfg_grp group */
81153 +/** @} */ /* end of FM_PCD_init_grp group */
81154 +
81155 +
81156 +/**************************************************************************//**
81157 + @Group FM_PCD_Runtime_grp FM PCD Runtime Unit
81158 +
81159 + @Description Frame Manager PCD Runtime Unit API
81160 +
81161 + The runtime control allows creation of PCD infrastructure modules
81162 + such as Network Environment Characteristics, Classification Plan
81163 + Groups and Coarse Classification Trees.
81164 + It also allows on-the-fly initialization, modification and removal
81165 + of PCD modules such as KeyGen schemes, coarse classification nodes
81166 + and Policer profiles.
81167 +
81168 + In order to explain the programming model of the PCD driver interface
81169 + a few terms should be explained, and will be used below.
81170 + - Distinction Header - One of the 16 protocols supported by the FM parser,
81171 + or one of the SHIM headers (1 or 2). May be a header with a special
81172 + option (see below).
81173 + - Interchangeable Headers Group - This is a group of Headers recognized
81174 + by either one of them. For example, if in a specific context the user
81175 + chooses to treat IPv4 and IPV6 in the same way, they may create an
81176 + interchangeable Headers Unit consisting of these 2 headers.
81177 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
81178 + Group.
81179 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
81180 + IPv6, includes multicast, broadcast and other protocol specific options.
81181 + In terms of hardware it relates to the options available in the classification
81182 + plan.
81183 + - Network Environment Characteristics - a set of Distinction Units that define
81184 + the total recognizable header selection for a certain environment. This is
81185 + NOT the list of all headers that will ever appear in a flow, but rather
81186 + everything that needs distinction in a flow, where distinction is made by KeyGen
81187 + schemes and coarse classification action descriptors.
81188 +
81189 + The PCD runtime modules initialization is done in stages. The first stage after
81190 + initializing the PCD module itself is to establish a Network Flows Environment
81191 + Definition. The application may choose to establish one or more such environments.
81192 + Later, when needed, the application will have to state, for some of its modules,
81193 + to which single environment it belongs.
81194 +
81195 + @{
81196 +*//***************************************************************************/
81197 +
81198 +/**************************************************************************//**
81199 + @Description A structure for SW parser labels
81200 + *//***************************************************************************/
81201 +typedef struct t_FmPcdPrsLabelParams {
81202 + uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes
81203 + resolution), relative to Parser RAM. */
81204 + e_NetHeaderType hdr; /**< The existence of this header will invoke
81205 + the SW parser code; Use HEADER_TYPE_NONE
81206 + to indicate that sw parser is to run
81207 + independent of the existence of any protocol
81208 + (run before HW parser). */
81209 + uint8_t indexPerHdr; /**< Normally 0, if more than one SW parser
81210 + attachments for the same header, use this
81211 + index to distinguish between them. */
81212 +} t_FmPcdPrsLabelParams;
81213 +
81214 +/**************************************************************************//**
81215 + @Description A structure for SW parser
81216 + *//***************************************************************************/
81217 +typedef struct t_FmPcdPrsSwParams {
81218 + bool override; /**< FALSE to invoke a check that nothing else
81219 + was loaded to this address, including
81220 + internal patches.
81221 + TRUE to override any existing code.*/
81222 + uint32_t size; /**< SW parser code size */
81223 + uint16_t base; /**< SW parser base (in instruction counts!
81224 + must be larger than 0x20)*/
81225 + uint8_t *p_Code; /**< SW parser code */
81226 + uint32_t swPrsDataParams[FM_PCD_PRS_NUM_OF_HDRS];
81227 + /**< SW parser data (parameters) */
81228 + uint8_t numOfLabels; /**< Number of labels for SW parser. */
81229 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
81230 + /**< SW parser labels table, containing
81231 + numOfLabels entries */
81232 +} t_FmPcdPrsSwParams;
81233 +
81234 +
81235 +/**************************************************************************//**
81236 + @Function FM_PCD_Enable
81237 +
81238 + @Description This routine should be called after PCD is initialized for enabling all
81239 + PCD engines according to their existing configuration.
81240 +
81241 + @Param[in] h_FmPcd FM PCD module descriptor.
81242 +
81243 + @Return E_OK on success; Error code otherwise.
81244 +
81245 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81246 +*//***************************************************************************/
81247 +t_Error FM_PCD_Enable(t_Handle h_FmPcd);
81248 +
81249 +/**************************************************************************//**
81250 + @Function FM_PCD_Disable
81251 +
81252 + @Description This routine may be called when PCD is enabled in order to
81253 + disable all PCD engines. It may be called
81254 + only when none of the ports in the system are using the PCD.
81255 +
81256 + @Param[in] h_FmPcd FM PCD module descriptor.
81257 +
81258 + @Return E_OK on success; Error code otherwise.
81259 +
81260 + @Cautions Allowed only following FM_PCD_Init() and when PCD is enabled.
81261 +*//***************************************************************************/
81262 +t_Error FM_PCD_Disable(t_Handle h_FmPcd);
81263 +
81264 +/**************************************************************************//**
81265 + @Function FM_PCD_GetCounter
81266 +
81267 + @Description Reads one of the FM PCD counters.
81268 +
81269 + @Param[in] h_FmPcd FM PCD module descriptor.
81270 + @Param[in] counter The requested counter.
81271 +
81272 + @Return Counter's current value.
81273 +
81274 + @Cautions Allowed only following FM_PCD_Init().
81275 + Note that it is user's responsibility to call this routine only
81276 + for enabled counters, and there will be no indication if a
81277 + disabled counter is accessed.
81278 +*//***************************************************************************/
81279 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter);
81280 +
81281 +/**************************************************************************//**
81282 +@Function FM_PCD_PrsLoadSw
81283 +
81284 +@Description This routine may be called in order to load software parsing code.
81285 +
81286 +
81287 +@Param[in] h_FmPcd FM PCD module descriptor.
81288 +@Param[in] p_SwPrs A pointer to a structure of software
81289 + parser parameters, including the software
81290 + parser image.
81291 +
81292 +@Return E_OK on success; Error code otherwise.
81293 +
81294 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81295 + This routine should NOT be called from guest-partition
81296 + (i.e. guestId != NCSW_MASTER_ID)
81297 +*//***************************************************************************/
81298 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs);
81299 +
81300 +/**************************************************************************//**
81301 +@Function FM_PCD_SetAdvancedOffloadSupport
81302 +
81303 +@Description This routine must be called in order to support the following features:
81304 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
81305 +
81306 +@Param[in] h_FmPcd FM PCD module descriptor.
81307 +
81308 +@Return E_OK on success; Error code otherwise.
81309 +
81310 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81311 + This routine should NOT be called from guest-partition
81312 + (i.e. guestId != NCSW_MASTER_ID)
81313 +*//***************************************************************************/
81314 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd);
81315 +
81316 +/**************************************************************************//**
81317 + @Function FM_PCD_KgSetDfltValue
81318 +
81319 + @Description Calling this routine sets a global default value to be used
81320 + by the KeyGen when parser does not recognize a required
81321 + field/header.
81322 + By default default values are 0.
81323 +
81324 + @Param[in] h_FmPcd FM PCD module descriptor.
81325 + @Param[in] valueId 0,1 - one of 2 global default values.
81326 + @Param[in] value The requested default value.
81327 +
81328 + @Return E_OK on success; Error code otherwise.
81329 +
81330 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81331 + This routine should NOT be called from guest-partition
81332 + (i.e. guestId != NCSW_MASTER_ID)
81333 +*//***************************************************************************/
81334 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value);
81335 +
81336 +/**************************************************************************//**
81337 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
81338 +
81339 + @Description Calling this routine allows the KeyGen to access data past
81340 + the parser finishing point.
81341 +
81342 + @Param[in] h_FmPcd FM PCD module descriptor.
81343 + @Param[in] payloadOffset the number of bytes beyond the parser location.
81344 +
81345 + @Return E_OK on success; Error code otherwise.
81346 +
81347 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81348 + This routine should NOT be called from guest-partition
81349 + (i.e. guestId != NCSW_MASTER_ID)
81350 +*//***************************************************************************/
81351 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset);
81352 +
81353 +/**************************************************************************//**
81354 + @Function FM_PCD_SetException
81355 +
81356 + @Description Calling this routine enables/disables PCD interrupts.
81357 +
81358 + @Param[in] h_FmPcd FM PCD module descriptor.
81359 + @Param[in] exception The exception to be selected.
81360 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81361 +
81362 + @Return E_OK on success; Error code otherwise.
81363 +
81364 + @Cautions Allowed only following FM_PCD_Init().
81365 + This routine should NOT be called from guest-partition
81366 + (i.e. guestId != NCSW_MASTER_ID)
81367 +*//***************************************************************************/
81368 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
81369 +
81370 +/**************************************************************************//**
81371 + @Function FM_PCD_ModifyCounter
81372 +
81373 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
81374 +
81375 + @Param[in] h_FmPcd FM PCD module descriptor.
81376 + @Param[in] counter The requested counter.
81377 + @Param[in] value The requested value to be written into the counter.
81378 +
81379 + @Return E_OK on success; Error code otherwise.
81380 +
81381 + @Cautions Allowed only following FM_PCD_Init().
81382 + This routine should NOT be called from guest-partition
81383 + (i.e. guestId != NCSW_MASTER_ID)
81384 +*//***************************************************************************/
81385 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value);
81386 +
81387 +/**************************************************************************//**
81388 + @Function FM_PCD_SetPlcrStatistics
81389 +
81390 + @Description This routine may be used to enable/disable policer statistics
81391 + counter. By default the statistics is enabled.
81392 +
81393 + @Param[in] h_FmPcd FM PCD module descriptor
81394 + @Param[in] enable TRUE to enable, FALSE to disable.
81395 +
81396 + @Return E_OK on success; Error code otherwise.
81397 +
81398 + @Cautions Allowed only following FM_PCD_Init().
81399 + This routine should NOT be called from guest-partition
81400 + (i.e. guestId != NCSW_MASTER_ID)
81401 +*//***************************************************************************/
81402 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable);
81403 +
81404 +/**************************************************************************//**
81405 + @Function FM_PCD_SetPrsStatistics
81406 +
81407 + @Description Defines whether to gather parser statistics including all ports.
81408 +
81409 + @Param[in] h_FmPcd FM PCD module descriptor.
81410 + @Param[in] enable TRUE to enable, FALSE to disable.
81411 +
81412 + @Return None
81413 +
81414 + @Cautions Allowed only following FM_PCD_Init().
81415 + This routine should NOT be called from guest-partition
81416 + (i.e. guestId != NCSW_MASTER_ID)
81417 +*//***************************************************************************/
81418 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable);
81419 +
81420 +/**************************************************************************//**
81421 + @Function FM_PCD_HcTxConf
81422 +
81423 + @Description This routine should be called to confirm frames that were
81424 + received on the HC confirmation queue.
81425 +
81426 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81427 + @Param[in] p_Fd Frame descriptor of the received frame.
81428 +
81429 + @Cautions Allowed only following FM_PCD_Init(). Allowed only if 'useHostCommand'
81430 + option was selected in the initialization.
81431 +*//***************************************************************************/
81432 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd);
81433 +
81434 +/**************************************************************************//*
81435 + @Function FM_PCD_ForceIntr
81436 +
81437 + @Description Causes an interrupt event on the requested source.
81438 +
81439 + @Param[in] h_FmPcd FM PCD module descriptor.
81440 + @Param[in] exception An exception to be forced.
81441 +
81442 + @Return E_OK on success; Error code if the exception is not enabled,
81443 + or is not able to create interrupt.
81444 +
81445 + @Cautions Allowed only following FM_PCD_Init().
81446 + This routine should NOT be called from guest-partition
81447 + (i.e. guestId != NCSW_MASTER_ID)
81448 +*//***************************************************************************/
81449 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception);
81450 +
81451 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
81452 +/**************************************************************************//**
81453 + @Function FM_PCD_DumpRegs
81454 +
81455 + @Description Dumps all PCD registers
81456 +
81457 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81458 +
81459 + @Return E_OK on success; Error code otherwise.
81460 +
81461 + @Cautions Allowed only following FM_PCD_Init().
81462 + NOTE: this routine may be called only for FM in master mode
81463 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81464 + are mapped.
81465 +*//***************************************************************************/
81466 +t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd);
81467 +
81468 +/**************************************************************************//**
81469 + @Function FM_PCD_KgDumpRegs
81470 +
81471 + @Description Dumps all PCD KG registers
81472 +
81473 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81474 +
81475 + @Return E_OK on success; Error code otherwise.
81476 +
81477 + @Cautions Allowed only following FM_PCD_Init().
81478 + NOTE: this routine may be called only for FM in master mode
81479 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81480 + are mapped.
81481 +*//***************************************************************************/
81482 +t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd);
81483 +
81484 +/**************************************************************************//**
81485 + @Function FM_PCD_PlcrDumpRegs
81486 +
81487 + @Description Dumps all PCD Policer registers
81488 +
81489 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81490 +
81491 + @Return E_OK on success; Error code otherwise.
81492 +
81493 + @Cautions Allowed only following FM_PCD_Init().
81494 + NOTE: this routine may be called only for FM in master mode
81495 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81496 + are mapped.
81497 +*//***************************************************************************/
81498 +t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd);
81499 +
81500 +/**************************************************************************//**
81501 + @Function FM_PCD_PlcrProfileDumpRegs
81502 +
81503 + @Description Dumps all PCD Policer profile registers
81504 +
81505 + @Param[in] h_Profile A handle to a Policer profile.
81506 +
81507 + @Return E_OK on success; Error code otherwise.
81508 +
81509 + @Cautions Allowed only following FM_PCD_Init().
81510 + NOTE: this routine may be called only for FM in master mode
81511 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81512 + are mapped.
81513 +*//***************************************************************************/
81514 +t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile);
81515 +
81516 +/**************************************************************************//**
81517 + @Function FM_PCD_PrsDumpRegs
81518 +
81519 + @Description Dumps all PCD Parser registers
81520 +
81521 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81522 +
81523 + @Return E_OK on success; Error code otherwise.
81524 +
81525 + @Cautions Allowed only following FM_PCD_Init().
81526 + NOTE: this routine may be called only for FM in master mode
81527 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81528 + are mapped.
81529 +*//***************************************************************************/
81530 +t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd);
81531 +
81532 +/**************************************************************************//**
81533 + @Function FM_PCD_HcDumpRegs
81534 +
81535 + @Description Dumps HC Port registers
81536 +
81537 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81538 +
81539 + @Return E_OK on success; Error code otherwise.
81540 +
81541 + @Cautions Allowed only following FM_PCD_Init().
81542 + NOTE: this routine may be called only for FM in master mode
81543 + (i.e. 'guestId'=NCSW_MASTER_ID).
81544 +*//***************************************************************************/
81545 +t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd);
81546 +#endif /* (defined(DEBUG_ERRORS) && ... */
81547 +
81548 +
81549 +
81550 +/**************************************************************************//**
81551 + KeyGen FM_PCD_Runtime_build_grp FM PCD Runtime Building Unit
81552 +
81553 + @Description Frame Manager PCD Runtime Building API
81554 +
81555 + This group contains routines for setting, deleting and modifying
81556 + PCD resources, for defining the total PCD tree.
81557 + @{
81558 +*//***************************************************************************/
81559 +
81560 +/**************************************************************************//**
81561 + @Collection Definitions of coarse classification
81562 + parameters as required by KeyGen (when coarse classification
81563 + is the next engine after this scheme).
81564 +*//***************************************************************************/
81565 +#define FM_PCD_MAX_NUM_OF_CC_TREES 8
81566 +#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16
81567 +#define FM_PCD_MAX_NUM_OF_CC_UNITS 4
81568 +#define FM_PCD_MAX_NUM_OF_KEYS 256
81569 +#define FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
81570 +#define FM_PCD_MAX_SIZE_OF_KEY 56
81571 +#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
81572 +#define FM_PCD_LAST_KEY_INDEX 0xffff
81573 +
81574 +#define FM_PCD_MAX_NUM_OF_CC_NODES 255 /* Obsolete, not used - will be removed in the future */
81575 +/* @} */
81576 +
81577 +/**************************************************************************//**
81578 + @Collection A set of definitions to allow protocol
81579 + special option description.
81580 +*//***************************************************************************/
81581 +typedef uint32_t protocolOpt_t; /**< A general type to define a protocol option. */
81582 +
81583 +typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. */
81584 +#define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
81585 +#define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
81586 +
81587 +typedef protocolOpt_t vlanProtocolOpt_t; /**< VLAN protocol options. */
81588 +#define VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
81589 +
81590 +typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */
81591 +#define MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
81592 +
81593 +typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */
81594 +#define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
81595 +#define IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
81596 +#define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
81597 +#define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
81598 +
81599 +#define IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
81600 + IPV4 Reassembly manipulation requires network
81601 + environment with IPV4 header and IPV4_FRAG_1 option */
81602 +
81603 +typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */
81604 +#define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
81605 +#define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
81606 +#define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
81607 +
81608 +#define IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
81609 + IPV6 Reassembly manipulation requires network
81610 + environment with IPV6 header and IPV6_FRAG_1 option;
81611 + in case where fragment found, the fragment-extension offset
81612 + may be found at 'shim2' (in parser-result). */
81613 +#if (DPAA_VERSION >= 11)
81614 +typedef protocolOpt_t capwapProtocolOpt_t; /**< CAPWAP protocol options. */
81615 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
81616 + CAPWAP Reassembly manipulation requires network
81617 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
81618 + in case where fragment found, the fragment-extension offset
81619 + may be found at 'shim2' (in parser-result). */
81620 +#endif /* (DPAA_VERSION >= 11) */
81621 +
81622 +
81623 +/* @} */
81624 +
81625 +#define FM_PCD_MANIP_MAX_HDR_SIZE 256
81626 +#define FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
81627 +
81628 +/**************************************************************************//**
81629 + @Collection A set of definitions to support Header Manipulation selection.
81630 +*//***************************************************************************/
81631 +typedef uint32_t hdrManipFlags_t; /**< A general type to define a HMan update command flags. */
81632 +
81633 +typedef hdrManipFlags_t ipv4HdrManipUpdateFlags_t; /**< IPv4 protocol HMan update command flags. */
81634 +
81635 +#define HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
81636 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81637 +#define HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
81638 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81639 +#define HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
81640 +#define HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
81641 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81642 +#define HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
81643 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81644 +
81645 +typedef hdrManipFlags_t ipv6HdrManipUpdateFlags_t; /**< IPv6 protocol HMan update command flags. */
81646 +
81647 +#define HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
81648 + ('trafficClass' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81649 +#define HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
81650 +#define HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
81651 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81652 +#define HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
81653 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81654 +
81655 +typedef hdrManipFlags_t tcpUdpHdrManipUpdateFlags_t;/**< TCP/UDP protocol HMan update command flags. */
81656 +
81657 +#define HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
81658 + ('src' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81659 +#define HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
81660 + ('dst' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81661 +#define HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
81662 +
81663 +/* @} */
81664 +
81665 +/**************************************************************************//**
81666 + @Description A type used for returning the order of the key extraction.
81667 + each value in this array represents the index of the extraction
81668 + command as defined by the user in the initialization extraction array.
81669 + The valid size of this array is the user define number of extractions
81670 + required (also marked by the second '0' in this array).
81671 +*//***************************************************************************/
81672 +typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
81673 +
81674 +/**************************************************************************//**
81675 + @Description All PCD engines
81676 +*//***************************************************************************/
81677 +typedef enum e_FmPcdEngine {
81678 + e_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
81679 + e_FM_PCD_DONE, /**< No PCD Engine indicated */
81680 + e_FM_PCD_KG, /**< KeyGen */
81681 + e_FM_PCD_CC, /**< Coarse classifier */
81682 + e_FM_PCD_PLCR, /**< Policer */
81683 + e_FM_PCD_PRS, /**< Parser */
81684 +#if (DPAA_VERSION >= 11)
81685 + e_FM_PCD_FR, /**< Frame-Replicator */
81686 +#endif /* (DPAA_VERSION >= 11) */
81687 + e_FM_PCD_HASH /**< Hash table */
81688 +} e_FmPcdEngine;
81689 +
81690 +/**************************************************************************//**
81691 + @Description Enumeration type for selecting extraction by header types
81692 +*//***************************************************************************/
81693 +typedef enum e_FmPcdExtractByHdrType {
81694 + e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
81695 + e_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
81696 + e_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
81697 +} e_FmPcdExtractByHdrType;
81698 +
81699 +/**************************************************************************//**
81700 + @Description Enumeration type for selecting extraction source
81701 + (when it is not the header)
81702 +*//***************************************************************************/
81703 +typedef enum e_FmPcdExtractFrom {
81704 + e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
81705 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
81706 + e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG & CC: Extract from the point where parsing had finished */
81707 + e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
81708 + e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
81709 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG only: Extract from the parser result */
81710 + e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
81711 + e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
81712 +} e_FmPcdExtractFrom;
81713 +
81714 +/**************************************************************************//**
81715 + @Description Enumeration type for selecting extraction type
81716 +*//***************************************************************************/
81717 +typedef enum e_FmPcdExtractType {
81718 + e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
81719 + e_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
81720 + e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
81721 +} e_FmPcdExtractType;
81722 +
81723 +/**************************************************************************//**
81724 + @Description Enumeration type for selecting default extraction value
81725 +*//***************************************************************************/
81726 +typedef enum e_FmPcdKgExtractDfltSelect {
81727 + e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
81728 + e_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
81729 + e_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
81730 + e_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
81731 + e_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
81732 +} e_FmPcdKgExtractDfltSelect;
81733 +
81734 +/**************************************************************************//**
81735 + @Description Enumeration type defining all default groups - each group shares
81736 + a default value, one of four user-initialized values.
81737 +*//***************************************************************************/
81738 +typedef enum e_FmPcdKgKnownFieldsDfltTypes {
81739 + e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
81740 + e_FM_PCD_KG_TCI, /**< TCI field */
81741 + e_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
81742 + e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
81743 + e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
81744 + e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
81745 + e_FM_PCD_KG_IP_ADDR, /**< IP address */
81746 + e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
81747 + e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
81748 + e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
81749 + e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
81750 + e_FM_PCD_KG_L4_PORT, /**< L4 Port */
81751 + e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
81752 + e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
81753 + any data extraction that is not the full
81754 + field described above */
81755 + e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
81756 + any data extraction without validation */
81757 + e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
81758 + extraction from parser result or
81759 + direct use of default value */
81760 +} e_FmPcdKgKnownFieldsDfltTypes;
81761 +
81762 +/**************************************************************************//**
81763 + @Description Enumeration type for defining header index for scenarios with
81764 + multiple (tunneled) headers
81765 +*//***************************************************************************/
81766 +typedef enum e_FmPcdHdrIndex {
81767 + e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
81768 + to specify regular IP (not tunneled). */
81769 + e_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
81770 + e_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
81771 + e_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
81772 + e_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
81773 +} e_FmPcdHdrIndex;
81774 +
81775 +/**************************************************************************//**
81776 + @Description Enumeration type for selecting the policer profile functional type
81777 +*//***************************************************************************/
81778 +typedef enum e_FmPcdProfileTypeSelection {
81779 + e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
81780 + e_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
81781 +} e_FmPcdProfileTypeSelection;
81782 +
81783 +/**************************************************************************//**
81784 + @Description Enumeration type for selecting the policer profile algorithm
81785 +*//***************************************************************************/
81786 +typedef enum e_FmPcdPlcrAlgorithmSelection {
81787 + e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
81788 + e_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
81789 + e_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
81790 +} e_FmPcdPlcrAlgorithmSelection;
81791 +
81792 +/**************************************************************************//**
81793 + @Description Enumeration type for selecting a policer profile color mode
81794 +*//***************************************************************************/
81795 +typedef enum e_FmPcdPlcrColorMode {
81796 + e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
81797 + e_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
81798 +} e_FmPcdPlcrColorMode;
81799 +
81800 +/**************************************************************************//**
81801 + @Description Enumeration type for selecting a policer profile color
81802 +*//***************************************************************************/
81803 +typedef enum e_FmPcdPlcrColor {
81804 + e_FM_PCD_PLCR_GREEN, /**< Green color code */
81805 + e_FM_PCD_PLCR_YELLOW, /**< Yellow color code */
81806 + e_FM_PCD_PLCR_RED, /**< Red color code */
81807 + e_FM_PCD_PLCR_OVERRIDE /**< Color override code */
81808 +} e_FmPcdPlcrColor;
81809 +
81810 +/**************************************************************************//**
81811 + @Description Enumeration type for selecting the policer profile packet frame length selector
81812 +*//***************************************************************************/
81813 +typedef enum e_FmPcdPlcrFrameLengthSelect {
81814 + e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
81815 + e_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
81816 + e_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
81817 + e_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
81818 +} e_FmPcdPlcrFrameLengthSelect;
81819 +
81820 +/**************************************************************************//**
81821 + @Description Enumeration type for selecting roll-back frame
81822 +*//***************************************************************************/
81823 +typedef enum e_FmPcdPlcrRollBackFrameSelect {
81824 + e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Roll-back L2 frame length */
81825 + e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Roll-back Full frame length */
81826 +} e_FmPcdPlcrRollBackFrameSelect;
81827 +
81828 +/**************************************************************************//**
81829 + @Description Enumeration type for selecting the policer profile packet or byte mode
81830 +*//***************************************************************************/
81831 +typedef enum e_FmPcdPlcrRateMode {
81832 + e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
81833 + e_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
81834 +} e_FmPcdPlcrRateMode;
81835 +
81836 +/**************************************************************************//**
81837 + @Description Enumeration type for defining action of frame
81838 +*//***************************************************************************/
81839 +typedef enum e_FmPcdDoneAction {
81840 + e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
81841 + e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue
81842 + to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD'
81843 + flag will be set for this frame. */
81844 +} e_FmPcdDoneAction;
81845 +
81846 +/**************************************************************************//**
81847 + @Description Enumeration type for selecting the policer counter
81848 +*//***************************************************************************/
81849 +typedef enum e_FmPcdPlcrProfileCounters {
81850 + e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
81851 + e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
81852 + e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
81853 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
81854 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
81855 +} e_FmPcdPlcrProfileCounters;
81856 +
81857 +/**************************************************************************//**
81858 + @Description Enumeration type for selecting the PCD action after extraction
81859 +*//***************************************************************************/
81860 +typedef enum e_FmPcdAction {
81861 + e_FM_PCD_ACTION_NONE, /**< NONE */
81862 + e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction */
81863 + e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction */
81864 +} e_FmPcdAction;
81865 +
81866 +/**************************************************************************//**
81867 + @Description Enumeration type for selecting type of insert manipulation
81868 +*//***************************************************************************/
81869 +typedef enum e_FmPcdManipHdrInsrtType {
81870 + e_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
81871 + e_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
81872 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81873 + e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
81874 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81875 +} e_FmPcdManipHdrInsrtType;
81876 +
81877 +/**************************************************************************//**
81878 + @Description Enumeration type for selecting type of remove manipulation
81879 +*//***************************************************************************/
81880 +typedef enum e_FmPcdManipHdrRmvType {
81881 + e_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
81882 + e_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
81883 +} e_FmPcdManipHdrRmvType;
81884 +
81885 +/**************************************************************************//**
81886 + @Description Enumeration type for selecting specific L2 fields removal
81887 +*//***************************************************************************/
81888 +typedef enum e_FmPcdManipHdrRmvSpecificL2 {
81889 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
81890 + e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
81891 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
81892 + the header which follows the MPLS header */
81893 + e_FM_PCD_MANIP_HDR_RMV_MPLS, /**< Remove MPLS header (Unlimited MPLS labels) */
81894 + e_FM_PCD_MANIP_HDR_RMV_PPPOE /**< Remove the PPPoE header and PPP protocol field. */
81895 +} e_FmPcdManipHdrRmvSpecificL2;
81896 +
81897 +/**************************************************************************//**
81898 + @Description Enumeration type for selecting specific fields updates
81899 +*//***************************************************************************/
81900 +typedef enum e_FmPcdManipHdrFieldUpdateType {
81901 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
81902 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
81903 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
81904 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
81905 +} e_FmPcdManipHdrFieldUpdateType;
81906 +
81907 +/**************************************************************************//**
81908 + @Description Enumeration type for selecting VLAN updates
81909 +*//***************************************************************************/
81910 +typedef enum e_FmPcdManipHdrFieldUpdateVlan {
81911 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
81912 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
81913 +} e_FmPcdManipHdrFieldUpdateVlan;
81914 +
81915 +/**************************************************************************//**
81916 + @Description Enumeration type for selecting specific L2 header insertion
81917 +*//***************************************************************************/
81918 +typedef enum e_FmPcdManipHdrInsrtSpecificL2 {
81919 + e_FM_PCD_MANIP_HDR_INSRT_MPLS, /**< Insert MPLS header (Unlimited MPLS labels) */
81920 + e_FM_PCD_MANIP_HDR_INSRT_PPPOE /**< Insert PPPOE */
81921 +} e_FmPcdManipHdrInsrtSpecificL2;
81922 +
81923 +#if (DPAA_VERSION >= 11)
81924 +/**************************************************************************//**
81925 + @Description Enumeration type for selecting QoS mapping mode
81926 +
81927 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
81928 + User should instruct the port to read the hash-result
81929 +*//***************************************************************************/
81930 +typedef enum e_FmPcdManipHdrQosMappingMode {
81931 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
81932 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the hash-result. */
81933 +} e_FmPcdManipHdrQosMappingMode;
81934 +
81935 +/**************************************************************************//**
81936 + @Description Enumeration type for selecting QoS source
81937 +
81938 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
81939 + User should left room for the hash-result on input/output buffer
81940 + and instruct the port to read/write the hash-result to the buffer (RPD should be set)
81941 +*//***************************************************************************/
81942 +typedef enum e_FmPcdManipHdrQosSrc {
81943 + e_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
81944 + e_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the hash-result. */
81945 +} e_FmPcdManipHdrQosSrc;
81946 +#endif /* (DPAA_VERSION >= 11) */
81947 +
81948 +/**************************************************************************//**
81949 + @Description Enumeration type for selecting type of header insertion
81950 +*//***************************************************************************/
81951 +typedef enum e_FmPcdManipHdrInsrtByHdrType {
81952 + e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
81953 +#if (DPAA_VERSION >= 11)
81954 + e_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
81955 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
81956 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
81957 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
81958 +#endif /* (DPAA_VERSION >= 11) */
81959 +} e_FmPcdManipHdrInsrtByHdrType;
81960 +
81961 +/**************************************************************************//**
81962 + @Description Enumeration type for selecting specific customCommand
81963 +*//***************************************************************************/
81964 +typedef enum e_FmPcdManipHdrCustomType {
81965 + e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
81966 + e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE, /**< Replace IPv4/IPv6 */
81967 +} e_FmPcdManipHdrCustomType;
81968 +
81969 +/**************************************************************************//**
81970 + @Description Enumeration type for selecting specific customCommand
81971 +*//***************************************************************************/
81972 +typedef enum e_FmPcdManipHdrCustomIpReplace {
81973 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
81974 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
81975 +} e_FmPcdManipHdrCustomIpReplace;
81976 +
81977 +/**************************************************************************//**
81978 + @Description Enumeration type for selecting type of header removal
81979 +*//***************************************************************************/
81980 +typedef enum e_FmPcdManipHdrRmvByHdrType {
81981 + e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
81982 +#if (DPAA_VERSION >= 11)
81983 + e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
81984 +#endif /* (DPAA_VERSION >= 11) */
81985 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81986 + e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
81987 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81988 +} e_FmPcdManipHdrRmvByHdrType;
81989 +
81990 +/**************************************************************************//**
81991 + @Description Enumeration type for selecting type of timeout mode
81992 +*//***************************************************************************/
81993 +typedef enum e_FmPcdManipReassemTimeOutMode {
81994 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
81995 + from the first fragment to the last */
81996 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
81997 +} e_FmPcdManipReassemTimeOutMode;
81998 +
81999 +/**************************************************************************//**
82000 + @Description Enumeration type for selecting type of WaysNumber mode
82001 +*//***************************************************************************/
82002 +typedef enum e_FmPcdManipReassemWaysNumber {
82003 + e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
82004 + e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
82005 + e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
82006 + e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
82007 + e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
82008 + e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
82009 + e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
82010 + e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
82011 +} e_FmPcdManipReassemWaysNumber;
82012 +
82013 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82014 +/**************************************************************************//**
82015 + @Description Enumeration type for selecting type of statistics mode
82016 +*//***************************************************************************/
82017 +typedef enum e_FmPcdStatsType {
82018 + e_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
82019 +} e_FmPcdStatsType;
82020 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
82021 +
82022 +/**************************************************************************//**
82023 + @Description Enumeration type for selecting manipulation type
82024 +*//***************************************************************************/
82025 +typedef enum e_FmPcdManipType {
82026 + e_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
82027 + e_FM_PCD_MANIP_REASSEM, /**< Reassembly */
82028 + e_FM_PCD_MANIP_FRAG, /**< Fragmentation */
82029 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
82030 +} e_FmPcdManipType;
82031 +
82032 +/**************************************************************************//**
82033 + @Description Enumeration type for selecting type of statistics mode
82034 +*//***************************************************************************/
82035 +typedef enum e_FmPcdCcStatsMode {
82036 + e_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
82037 + e_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
82038 + e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
82039 +#if (DPAA_VERSION >= 11)
82040 + e_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics;
82041 + This mode is supported only on B4860 device */
82042 +#endif /* (DPAA_VERSION >= 11) */
82043 +} e_FmPcdCcStatsMode;
82044 +
82045 +/**************************************************************************//**
82046 + @Description Enumeration type for determining the action in case an IP packet
82047 + is larger than MTU but its DF (Don't Fragment) bit is set.
82048 +*//***************************************************************************/
82049 +typedef enum e_FmPcdManipDontFragAction {
82050 + e_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
82051 + e_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_FM_PCD_MANIP_DISCARD_PACKET,
82052 + /**< Obsolete, cannot enqueue to error queue;
82053 + In practice, selects to discard packets;
82054 + Will be removed in the future */
82055 + e_FM_PCD_MANIP_FRAGMENT_PACKET, /**< Fragment packet and continue normal processing */
82056 + e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
82057 +} e_FmPcdManipDontFragAction;
82058 +
82059 +/**************************************************************************//**
82060 + @Description Enumeration type for selecting type of special offload manipulation
82061 +*//***************************************************************************/
82062 +typedef enum e_FmPcdManipSpecialOffloadType {
82063 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
82064 +#if (DPAA_VERSION >= 11)
82065 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
82066 +#endif /* (DPAA_VERSION >= 11) */
82067 +} e_FmPcdManipSpecialOffloadType;
82068 +
82069 +
82070 +/**************************************************************************//**
82071 + @Description A Union of protocol dependent special options
82072 +*//***************************************************************************/
82073 +typedef union u_FmPcdHdrProtocolOpt {
82074 + ethProtocolOpt_t ethOpt; /**< Ethernet options */
82075 + vlanProtocolOpt_t vlanOpt; /**< VLAN options */
82076 + mplsProtocolOpt_t mplsOpt; /**< MPLS options */
82077 + ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */
82078 + ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */
82079 +#if (DPAA_VERSION >= 11)
82080 + capwapProtocolOpt_t capwapOpt; /**< CAPWAP options */
82081 +#endif /* (DPAA_VERSION >= 11) */
82082 +} u_FmPcdHdrProtocolOpt;
82083 +
82084 +/**************************************************************************//**
82085 + @Description A union holding protocol fields
82086 +
82087 +
82088 + Fields supported as "full fields":
82089 + HEADER_TYPE_ETH:
82090 + NET_HEADER_FIELD_ETH_DA
82091 + NET_HEADER_FIELD_ETH_SA
82092 + NET_HEADER_FIELD_ETH_TYPE
82093 +
82094 + HEADER_TYPE_LLC_SNAP:
82095 + NET_HEADER_FIELD_LLC_SNAP_TYPE
82096 +
82097 + HEADER_TYPE_VLAN:
82098 + NET_HEADER_FIELD_VLAN_TCI
82099 + (index may apply:
82100 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82101 + e_FM_PCD_HDR_INDEX_LAST)
82102 +
82103 + HEADER_TYPE_MPLS:
82104 + NET_HEADER_FIELD_MPLS_LABEL_STACK
82105 + (index may apply:
82106 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82107 + e_FM_PCD_HDR_INDEX_2,
82108 + e_FM_PCD_HDR_INDEX_LAST)
82109 +
82110 + HEADER_TYPE_IPv4:
82111 + NET_HEADER_FIELD_IPv4_SRC_IP
82112 + NET_HEADER_FIELD_IPv4_DST_IP
82113 + NET_HEADER_FIELD_IPv4_PROTO
82114 + NET_HEADER_FIELD_IPv4_TOS
82115 + (index may apply:
82116 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82117 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
82118 +
82119 + HEADER_TYPE_IPv6:
82120 + NET_HEADER_FIELD_IPv6_SRC_IP
82121 + NET_HEADER_FIELD_IPv6_DST_IP
82122 + NET_HEADER_FIELD_IPv6_NEXT_HDR
82123 + NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC (must come together!)
82124 + (index may apply:
82125 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82126 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
82127 +
82128 + (Note that starting from DPAA 1-1, NET_HEADER_FIELD_IPv6_NEXT_HDR applies to
82129 + the last next header indication, meaning the next L4, which may be
82130 + present at the Ipv6 last extension. On earlier revisions this field
82131 + applies to the Next-Header field of the main IPv6 header)
82132 +
82133 + HEADER_TYPE_IP:
82134 + NET_HEADER_FIELD_IP_PROTO
82135 + (index may apply:
82136 + e_FM_PCD_HDR_INDEX_LAST)
82137 + NET_HEADER_FIELD_IP_DSCP
82138 + (index may apply:
82139 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1)
82140 + HEADER_TYPE_GRE:
82141 + NET_HEADER_FIELD_GRE_TYPE
82142 +
82143 + HEADER_TYPE_MINENCAP
82144 + NET_HEADER_FIELD_MINENCAP_SRC_IP
82145 + NET_HEADER_FIELD_MINENCAP_DST_IP
82146 + NET_HEADER_FIELD_MINENCAP_TYPE
82147 +
82148 + HEADER_TYPE_TCP:
82149 + NET_HEADER_FIELD_TCP_PORT_SRC
82150 + NET_HEADER_FIELD_TCP_PORT_DST
82151 + NET_HEADER_FIELD_TCP_FLAGS
82152 +
82153 + HEADER_TYPE_UDP:
82154 + NET_HEADER_FIELD_UDP_PORT_SRC
82155 + NET_HEADER_FIELD_UDP_PORT_DST
82156 +
82157 + HEADER_TYPE_UDP_LITE:
82158 + NET_HEADER_FIELD_UDP_LITE_PORT_SRC
82159 + NET_HEADER_FIELD_UDP_LITE_PORT_DST
82160 +
82161 + HEADER_TYPE_IPSEC_AH:
82162 + NET_HEADER_FIELD_IPSEC_AH_SPI
82163 + NET_HEADER_FIELD_IPSEC_AH_NH
82164 +
82165 + HEADER_TYPE_IPSEC_ESP:
82166 + NET_HEADER_FIELD_IPSEC_ESP_SPI
82167 +
82168 + HEADER_TYPE_SCTP:
82169 + NET_HEADER_FIELD_SCTP_PORT_SRC
82170 + NET_HEADER_FIELD_SCTP_PORT_DST
82171 +
82172 + HEADER_TYPE_DCCP:
82173 + NET_HEADER_FIELD_DCCP_PORT_SRC
82174 + NET_HEADER_FIELD_DCCP_PORT_DST
82175 +
82176 + HEADER_TYPE_PPPoE:
82177 + NET_HEADER_FIELD_PPPoE_PID
82178 + NET_HEADER_FIELD_PPPoE_SID
82179 +
82180 + *****************************************************************
82181 + Fields supported as "from fields":
82182 + HEADER_TYPE_ETH (with or without validation):
82183 + NET_HEADER_FIELD_ETH_TYPE
82184 +
82185 + HEADER_TYPE_VLAN (with or without validation):
82186 + NET_HEADER_FIELD_VLAN_TCI
82187 + (index may apply:
82188 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82189 + e_FM_PCD_HDR_INDEX_LAST)
82190 +
82191 + HEADER_TYPE_IPv4 (without validation):
82192 + NET_HEADER_FIELD_IPv4_PROTO
82193 + (index may apply:
82194 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82195 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
82196 +
82197 + HEADER_TYPE_IPv6 (without validation):
82198 + NET_HEADER_FIELD_IPv6_NEXT_HDR
82199 + (index may apply:
82200 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82201 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
82202 +
82203 +*//***************************************************************************/
82204 +typedef union t_FmPcdFields {
82205 + headerFieldEth_t eth; /**< Ethernet */
82206 + headerFieldVlan_t vlan; /**< VLAN */
82207 + headerFieldLlcSnap_t llcSnap; /**< LLC SNAP */
82208 + headerFieldPppoe_t pppoe; /**< PPPoE */
82209 + headerFieldMpls_t mpls; /**< MPLS */
82210 + headerFieldIp_t ip; /**< IP */
82211 + headerFieldIpv4_t ipv4; /**< IPv4 */
82212 + headerFieldIpv6_t ipv6; /**< IPv6 */
82213 + headerFieldUdp_t udp; /**< UDP */
82214 + headerFieldUdpLite_t udpLite; /**< UDP Lite */
82215 + headerFieldTcp_t tcp; /**< TCP */
82216 + headerFieldSctp_t sctp; /**< SCTP */
82217 + headerFieldDccp_t dccp; /**< DCCP */
82218 + headerFieldGre_t gre; /**< GRE */
82219 + headerFieldMinencap_t minencap; /**< Minimal Encapsulation */
82220 + headerFieldIpsecAh_t ipsecAh; /**< IPSec AH */
82221 + headerFieldIpsecEsp_t ipsecEsp; /**< IPSec ESP */
82222 + headerFieldUdpEncapEsp_t udpEncapEsp; /**< UDP Encapsulation ESP */
82223 +} t_FmPcdFields;
82224 +
82225 +/**************************************************************************//**
82226 + @Description Parameters for defining header extraction for key generation
82227 +*//***************************************************************************/
82228 +typedef struct t_FmPcdFromHdr {
82229 + uint8_t size; /**< Size in byte */
82230 + uint8_t offset; /**< Byte offset */
82231 +} t_FmPcdFromHdr;
82232 +
82233 +/**************************************************************************//**
82234 + @Description Parameters for defining field extraction for key generation
82235 +*//***************************************************************************/
82236 +typedef struct t_FmPcdFromField {
82237 + t_FmPcdFields field; /**< Field selection */
82238 + uint8_t size; /**< Size in byte */
82239 + uint8_t offset; /**< Byte offset */
82240 +} t_FmPcdFromField;
82241 +
82242 +/**************************************************************************//**
82243 + @Description Parameters for defining a single network environment unit
82244 +
82245 + A distinction unit should be defined if it will later be used
82246 + by one or more PCD engines to distinguish between flows.
82247 +*//***************************************************************************/
82248 +typedef struct t_FmPcdDistinctionUnit {
82249 + struct {
82250 + e_NetHeaderType hdr; /**< One of the headers supported by the FM */
82251 + u_FmPcdHdrProtocolOpt opt; /**< Select only one option ! */
82252 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
82253 +} t_FmPcdDistinctionUnit;
82254 +
82255 +/**************************************************************************//**
82256 + @Description Parameters for defining all different distinction units supported
82257 + by a specific PCD Network Environment Characteristics module.
82258 +
82259 + Each unit represent a protocol or a group of protocols that may
82260 + be used later by the different PCD engines to distinguish
82261 + between flows.
82262 +*//***************************************************************************/
82263 +typedef struct t_FmPcdNetEnvParams {
82264 + uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */
82265 + t_FmPcdDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< An array of numOfDistinctionUnits of the
82266 + different units to be identified */
82267 +} t_FmPcdNetEnvParams;
82268 +
82269 +/**************************************************************************//**
82270 + @Description Parameters for defining a single extraction action when
82271 + creating a key
82272 +*//***************************************************************************/
82273 +typedef struct t_FmPcdExtractEntry {
82274 + e_FmPcdExtractType type; /**< Extraction type select */
82275 + union {
82276 + struct {
82277 + e_NetHeaderType hdr; /**< Header selection */
82278 + bool ignoreProtocolValidation;
82279 + /**< Ignore protocol validation */
82280 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
82281 + IP. Otherwise should be cleared. */
82282 + e_FmPcdExtractByHdrType type; /**< Header extraction type select */
82283 + union {
82284 + t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */
82285 + t_FmPcdFromField fromField; /**< Extract bytes from field parameters */
82286 + t_FmPcdFields fullField; /**< Extract full filed parameters */
82287 + } extractByHdrType;
82288 + } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
82289 + struct {
82290 + e_FmPcdExtractFrom src; /**< Non-header extraction source */
82291 + e_FmPcdAction action; /**< Relevant for CC Only */
82292 + uint16_t icIndxMask; /**< Relevant only for CC when
82293 + action = e_FM_PCD_ACTION_INDEXED_LOOKUP;
82294 + Note that the number of bits that are set within
82295 + this mask must be log2 of the CC-node 'numOfKeys'.
82296 + Note that the mask cannot be set on the lower bits. */
82297 + uint8_t offset; /**< Byte offset */
82298 + uint8_t size; /**< Size in byte */
82299 + } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
82300 + };
82301 +} t_FmPcdExtractEntry;
82302 +
82303 +/**************************************************************************//**
82304 + @Description Parameters for defining masks for each extracted field in the key.
82305 +*//***************************************************************************/
82306 +typedef struct t_FmPcdKgExtractMask {
82307 + uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */
82308 + uint8_t offset; /**< Byte offset */
82309 + uint8_t mask; /**< A byte mask (selected bits will be used) */
82310 +} t_FmPcdKgExtractMask;
82311 +
82312 +/**************************************************************************//**
82313 + @Description Parameters for defining default selection per groups of fields
82314 +*//***************************************************************************/
82315 +typedef struct t_FmPcdKgExtractDflt {
82316 + e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select */
82317 + e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */
82318 +} t_FmPcdKgExtractDflt;
82319 +
82320 +/**************************************************************************//**
82321 + @Description Parameters for defining key extraction and hashing
82322 +*//***************************************************************************/
82323 +typedef struct t_FmPcdKgKeyExtractAndHashParams {
82324 + uint32_t privateDflt0; /**< Scheme default register 0 */
82325 + uint32_t privateDflt1; /**< Scheme default register 1 */
82326 + uint8_t numOfUsedExtracts; /**< defines the valid size of the following array */
82327 + t_FmPcdExtractEntry extractArray [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; /**< An array of extractions definition. */
82328 + uint8_t numOfUsedDflts; /**< defines the valid size of the following array */
82329 + t_FmPcdKgExtractDflt dflts[FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
82330 + /**< For each extraction used in this scheme, specify the required
82331 + default register to be used when header is not found.
82332 + types not specified in this array will get undefined value. */
82333 + uint8_t numOfUsedMasks; /**< defines the valid size of the following array */
82334 + t_FmPcdKgExtractMask masks[FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
82335 + uint8_t hashShift; /**< hash result right shift. Select the 24 bits out of the 64 hash
82336 + result. 0 means using the 24 LSB's, otherwise use the
82337 + 24 LSB's after shifting right.*/
82338 + uint32_t hashDistributionNumOfFqids; /**< must be > 1 and a power of 2. Represents the range
82339 + of queues for the key and hash functionality */
82340 + uint8_t hashDistributionFqidsShift; /**< selects the FQID bits that will be effected by the hash */
82341 + bool symmetricHash; /**< TRUE to generate the same hash for frames with swapped source and
82342 + destination fields on all layers; If TRUE, driver will check that for
82343 + all layers, if SRC extraction is selected, DST extraction must also be
82344 + selected, and vice versa. */
82345 +} t_FmPcdKgKeyExtractAndHashParams;
82346 +
82347 +/**************************************************************************//**
82348 + @Description Parameters for defining a single FQID mask (extracted OR).
82349 +*//***************************************************************************/
82350 +typedef struct t_FmPcdKgExtractedOrParams {
82351 + e_FmPcdExtractType type; /**< Extraction type select */
82352 + union {
82353 + struct { /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
82354 + e_NetHeaderType hdr;
82355 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
82356 + IP. Otherwise should be cleared.*/
82357 + bool ignoreProtocolValidation;
82358 + /**< continue extraction even if protocol is not recognized */
82359 + } extractByHdr; /**< Header to extract by */
82360 + e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
82361 + };
82362 + uint8_t extractionOffset; /**< Offset for extraction (in bytes). */
82363 + e_FmPcdKgExtractDfltSelect dfltValue; /**< Select register from which extraction is taken if
82364 + field not found */
82365 + uint8_t mask; /**< Extraction mask (specified bits are used) */
82366 + uint8_t bitOffsetInFqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
82367 + the extracted byte; Assume byte is placed as the 8 MSB's in
82368 + a 32 bit word where the lower bits
82369 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
82370 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
82371 + extracted byte will effect the 8 LSB's of the FQID,
82372 + if bitOffsetInFqid=31 than the byte's MSB will effect
82373 + the FQID's LSB; 0 means - no effect on FQID;
82374 + Note that one, and only one of
82375 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
82376 + extracted byte must effect either FQID or Policer profile).*/
82377 + uint8_t bitOffsetInPlcrProfile;
82378 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
82379 + effect using the extracted byte; Assume byte is placed
82380 + as the 8 MSB's in a 16 bit word where the lower bits
82381 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
82382 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
82383 + than the extracted byte will effect the whole policer profile id,
82384 + if bitOffsetInFqid=15 than the byte's MSB will effect
82385 + the Policer Profile id's LSB;
82386 + 0 means - no effect on policer profile; Note that one, and only one of
82387 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
82388 + extracted byte must effect either FQID or Policer profile).*/
82389 +} t_FmPcdKgExtractedOrParams;
82390 +
82391 +/**************************************************************************//**
82392 + @Description Parameters for configuring a scheme counter
82393 +*//***************************************************************************/
82394 +typedef struct t_FmPcdKgSchemeCounter {
82395 + bool update; /**< FALSE to keep the current counter state
82396 + and continue from that point, TRUE to update/reset
82397 + the counter when the scheme is written. */
82398 + uint32_t value; /**< If update=TRUE, this value will be written into the
82399 + counter. clear this field to reset the counter. */
82400 +} t_FmPcdKgSchemeCounter;
82401 +
82402 +/**************************************************************************//**
82403 + @Description Parameters for configuring a policer profile for a KeyGen scheme
82404 + (when policer is the next engine after this scheme).
82405 +*//***************************************************************************/
82406 +typedef struct t_FmPcdKgPlcrProfile {
82407 + bool sharedProfile; /**< TRUE if this profile is shared between ports
82408 + (managed by master partition); Must not be TRUE
82409 + if profile is after Coarse Classification*/
82410 + bool direct; /**< if TRUE, directRelativeProfileId only selects the profile
82411 + id, if FALSE fqidOffsetRelativeProfileIdBase is used
82412 + together with fqidOffsetShift and numOfProfiles
82413 + parameters, to define a range of profiles from
82414 + which the KeyGen result will determine the
82415 + destination policer profile. */
82416 + union {
82417 + uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile.
82418 + should indicate the policer profile offset within the
82419 + port's policer profiles or shared window. */
82420 + struct {
82421 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
82422 + final FQID - without the FQID base). */
82423 + uint8_t fqidOffsetRelativeProfileIdBase;
82424 + /**< The base of the FMan Port's relative Storage-Profile ID;
82425 + this value will be "OR'ed" with the KeyGen create FQID
82426 + offset (i.e. not the final FQID - without the FQID base);
82427 + the final result should indicate the Storage-Profile offset
82428 + within the FMan Port's relative Storage-Profiles window/
82429 + (or the SHARED window depends on 'sharedProfile'). */
82430 + uint8_t numOfProfiles; /**< Range of profiles starting at base */
82431 + } indirectProfile; /**< Indirect profile parameters */
82432 + } profileSelect; /**< Direct/indirect profile selection and parameters */
82433 +} t_FmPcdKgPlcrProfile;
82434 +
82435 +#if (DPAA_VERSION >= 11)
82436 +/**************************************************************************//**
82437 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
82438 +*//***************************************************************************/
82439 +typedef struct t_FmPcdKgStorageProfile {
82440 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
82441 + profile id;
82442 + If FALSE, fqidOffsetRelativeProfileIdBase is used
82443 + together with fqidOffsetShift and numOfProfiles
82444 + parameters to define a range of profiles from which
82445 + the KeyGen result will determine the destination
82446 + storage profile. */
82447 + union {
82448 + uint16_t directRelativeProfileId; /**< Used when 'direct' is TRUE, to select a storage profile;
82449 + should indicate the storage profile offset within the
82450 + port's storage profiles window. */
82451 + struct {
82452 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
82453 + final FQID - without the FQID base). */
82454 + uint8_t fqidOffsetRelativeProfileIdBase;
82455 + /**< The base of the FMan Port's relative Storage-Profile ID;
82456 + this value will be "OR'ed" with the KeyGen create FQID
82457 + offset (i.e. not the final FQID - without the FQID base);
82458 + the final result should indicate the Storage-Profile offset
82459 + within the FMan Port's relative Storage-Profiles window. */
82460 + uint8_t numOfProfiles; /**< Range of profiles starting at base. */
82461 + } indirectProfile; /**< Indirect profile parameters. */
82462 + } profileSelect; /**< Direct/indirect profile selection and parameters. */
82463 +} t_FmPcdKgStorageProfile;
82464 +#endif /* (DPAA_VERSION >= 11) */
82465 +
82466 +/**************************************************************************//**
82467 + @Description Parameters for defining CC as the next engine after KeyGen
82468 +*//***************************************************************************/
82469 +typedef struct t_FmPcdKgCc {
82470 + t_Handle h_CcTree; /**< A handle to a CC Tree */
82471 + uint8_t grpId; /**< CC group id within the CC tree */
82472 + bool plcrNext; /**< TRUE if after CC, in case of data frame,
82473 + policing is required. */
82474 + bool bypassPlcrProfileGeneration; /**< TRUE to bypass KeyGen policer profile generation;
82475 + selected profile is the one set at port initialization. */
82476 + t_FmPcdKgPlcrProfile plcrProfile; /**< Valid only if plcrNext = TRUE and
82477 + bypassPlcrProfileGeneration = FALSE */
82478 +} t_FmPcdKgCc;
82479 +
82480 +/**************************************************************************//**
82481 + @Description Parameters for defining initializing a KeyGen scheme
82482 +*//***************************************************************************/
82483 +typedef struct t_FmPcdKgSchemeParams {
82484 + bool modify; /**< TRUE to change an existing scheme */
82485 + union
82486 + {
82487 + uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */
82488 + t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */
82489 + } id;
82490 + bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need
82491 + for match vector; KeyGen will ignore it when matching */
82492 + struct { /**< HL Relevant only if alwaysDirect = FALSE */
82493 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82494 + by FM_PCD_NetEnvCharacteristicsSet() */
82495 + uint8_t numOfDistinctionUnits; /**< Number of NetEnv units listed in unitIds array */
82496 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
82497 + /**< Indexes as passed to SetNetEnvCharacteristics array*/
82498 + } netEnvParams;
82499 + bool useHash; /**< use the KeyGen Hash functionality */
82500 + t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams;
82501 + /**< used only if useHash = TRUE */
82502 + bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
82503 + In such a case FQID after KeyGen will be the default FQID
82504 + defined for the relevant port, or the FQID defined by CC
82505 + in cases where CC was the previous engine. */
82506 + uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE;
82507 + If hash is used and an even distribution is expected
82508 + according to hashDistributionNumOfFqids, baseFqid must be aligned to
82509 + hashDistributionNumOfFqids. */
82510 + uint8_t numOfUsedExtractedOrs; /**< Number of FQID masks listed in extractedOrs array */
82511 + t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS];
82512 + /**< FM_PCD_KG_NUM_OF_GENERIC_REGS
82513 + registers are shared between qidMasks
82514 + functionality and some of the extraction
82515 + actions; Normally only some will be used
82516 + for qidMask. Driver will return error if
82517 + resource is full at initialization time. */
82518 +
82519 +#if (DPAA_VERSION >= 11)
82520 + bool overrideStorageProfile; /**< TRUE if KeyGen override previously decided storage profile */
82521 + t_FmPcdKgStorageProfile storageProfile; /**< Used when overrideStorageProfile TRUE */
82522 +#endif /* (DPAA_VERSION >= 11) */
82523 +
82524 + e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */
82525 + union { /**< depends on nextEngine */
82526 + e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */
82527 + t_FmPcdKgPlcrProfile plcrProfile; /**< Used when next engine is PLCR */
82528 + t_FmPcdKgCc cc; /**< Used when next engine is CC */
82529 + } kgNextEngineParams;
82530 + t_FmPcdKgSchemeCounter schemeCounter; /**< A structure of parameters for updating
82531 + the scheme counter */
82532 +} t_FmPcdKgSchemeParams;
82533 +
82534 +/**************************************************************************//**
82535 + @Collection Definitions for CC statistics
82536 +*//***************************************************************************/
82537 +#if (DPAA_VERSION >= 11)
82538 +#define FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
82539 +#define FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
82540 +#endif /* (DPAA_VERSION >= 11) */
82541 +#define FM_PCD_CC_STATS_COUNTER_SIZE 4 /* Size in bytes of a frame length range counter */
82542 +/* @} */
82543 +
82544 +/**************************************************************************//**
82545 + @Description Parameters for defining CC as the next engine after a CC node.
82546 +*//***************************************************************************/
82547 +typedef struct t_FmPcdCcNextCcParams {
82548 + t_Handle h_CcNode; /**< A handle of the next CC node */
82549 +} t_FmPcdCcNextCcParams;
82550 +
82551 +#if (DPAA_VERSION >= 11)
82552 +/**************************************************************************//**
82553 + @Description Parameters for defining Frame replicator as the next engine after a CC node.
82554 +*//***************************************************************************/
82555 +typedef struct t_FmPcdCcNextFrParams {
82556 + t_Handle h_FrmReplic; /**< A handle of the next frame replicator group */
82557 +} t_FmPcdCcNextFrParams;
82558 +#endif /* (DPAA_VERSION >= 11) */
82559 +
82560 +/**************************************************************************//**
82561 + @Description Parameters for defining Policer as the next engine after a CC node.
82562 +*//***************************************************************************/
82563 +typedef struct t_FmPcdCcNextPlcrParams {
82564 + bool overrideParams; /**< TRUE if CC override previously decided parameters*/
82565 + bool sharedProfile; /**< Relevant only if overrideParams=TRUE:
82566 + TRUE if this profile is shared between ports */
82567 + uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE:
82568 + (otherwise profile id is taken from KeyGen);
82569 + This parameter should indicate the policer
82570 + profile offset within the port's
82571 + policer profiles or from SHARED window.*/
82572 + uint32_t newFqid; /**< Relevant only if overrideParams=TRUE:
82573 + FQID for enqueuing the frame;
82574 + In earlier chips if policer next engine is KEYGEN,
82575 + this parameter can be 0, because the KEYGEN
82576 + always decides the enqueue FQID.*/
82577 +#if (DPAA_VERSION >= 11)
82578 + uint8_t newRelativeStorageProfileId;
82579 + /**< Indicates the relative storage profile offset within
82580 + the port's storage profiles window;
82581 + Relevant only if the port was configured with VSP. */
82582 +#endif /* (DPAA_VERSION >= 11) */
82583 +} t_FmPcdCcNextPlcrParams;
82584 +
82585 +/**************************************************************************//**
82586 + @Description Parameters for defining enqueue as the next action after a CC node.
82587 +*//***************************************************************************/
82588 +typedef struct t_FmPcdCcNextEnqueueParams {
82589 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82590 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82591 + relevant if action = e_FM_PCD_ENQ_FRAME */
82592 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82593 + (otherwise FQID is taken from KeyGen),
82594 + relevant if action = e_FM_PCD_ENQ_FRAME */
82595 +#if (DPAA_VERSION >= 11)
82596 + uint8_t newRelativeStorageProfileId;
82597 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82598 + storage profile offset within the port's storage profiles
82599 + window; Relevant only if the port was configured with VSP. */
82600 +#endif /* (DPAA_VERSION >= 11) */
82601 +} t_FmPcdCcNextEnqueueParams;
82602 +
82603 +/**************************************************************************//**
82604 + @Description Parameters for defining KeyGen as the next engine after a CC node.
82605 +*//***************************************************************************/
82606 +typedef struct t_FmPcdCcNextKgParams {
82607 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82608 + Note - this parameters irrelevant for earlier chips */
82609 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82610 + (otherwise FQID is taken from KeyGen),
82611 + Note - this parameters irrelevant for earlier chips */
82612 +#if (DPAA_VERSION >= 11)
82613 + uint8_t newRelativeStorageProfileId;
82614 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82615 + storage profile offset within the port's storage profiles
82616 + window; Relevant only if the port was configured with VSP. */
82617 +#endif /* (DPAA_VERSION >= 11) */
82618 +
82619 + t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */
82620 +} t_FmPcdCcNextKgParams;
82621 +
82622 +/**************************************************************************//**
82623 + @Description Parameters for defining the next engine after a CC node.
82624 +*//***************************************************************************/
82625 +typedef struct t_FmPcdCcNextEngineParams {
82626 + e_FmPcdEngine nextEngine; /**< User has to initialize parameters
82627 + according to nextEngine definition */
82628 + union {
82629 + t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */
82630 + t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */
82631 + t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */
82632 + t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */
82633 +#if (DPAA_VERSION >= 11)
82634 + t_FmPcdCcNextFrParams frParams; /**< Parameters in case next engine is FR */
82635 +#endif /* (DPAA_VERSION >= 11) */
82636 + } params; /**< union used for all the next-engine parameters options */
82637 +
82638 + t_Handle h_Manip; /**< Handle to Manipulation object.
82639 + Relevant if next engine is of type result
82640 + (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */
82641 +
82642 + bool statisticsEn; /**< If TRUE, statistics counters are incremented
82643 + for each frame passing through this
82644 + Coarse Classification entry. */
82645 +} t_FmPcdCcNextEngineParams;
82646 +
82647 +/**************************************************************************//**
82648 + @Description Parameters for defining a single CC key
82649 +*//***************************************************************************/
82650 +typedef struct t_FmPcdCcKeyParams {
82651 + uint8_t *p_Key; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82652 + pointer to the key of the size defined in keySize */
82653 + uint8_t *p_Mask; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82654 + pointer to the Mask per key of the size defined
82655 + in keySize. p_Key and p_Mask (if defined) has to be
82656 + of the same size defined in the keySize;
82657 + NOTE that if this value is equal for all entries whithin
82658 + this table, the driver will automatically use global-mask
82659 + (i.e. one common mask for all entries) instead of private
82660 + one; that is done in order to spare some memory and for
82661 + better performance. */
82662 + t_FmPcdCcNextEngineParams ccNextEngineParams;
82663 + /**< parameters for the next for the defined Key in
82664 + the p_Key */
82665 +} t_FmPcdCcKeyParams;
82666 +
82667 +/**************************************************************************//**
82668 + @Description Parameters for defining CC keys parameters
82669 + The driver supports two methods for CC node allocation: dynamic and static.
82670 + Static mode was created in order to prevent runtime alloc/free
82671 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
82672 + the driver automatically allocates the memory according to
82673 + 'maxNumOfKeys' parameter. The driver calculates the maximal memory
82674 + size that may be used for this CC-Node taking into consideration
82675 + 'maskSupport' and 'statisticsMode' parameters.
82676 + When 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
82677 + parameters of this node, 'maxNumOfKeys' must be equal to 'numOfKeys'.
82678 + In dynamic mode, 'maxNumOfKeys' must be zero. At initialization,
82679 + all required structures are allocated according to 'numOfKeys'
82680 + parameter. During runtime modification, these structures are
82681 + re-allocated according to the updated number of keys.
82682 +
82683 + Please note that 'action' and 'icIndxMask' mentioned in the
82684 + specific parameter explanations are passed in the extraction
82685 + parameters of the node (fields of extractCcParams.extractNonHdr).
82686 +*//***************************************************************************/
82687 +typedef struct t_KeysParams {
82688 + uint16_t maxNumOfKeys; /**< Maximum number of keys that will (ever) be used in this CC-Node;
82689 + A value of zero may be used for dynamic memory allocation. */
82690 + bool maskSupport; /**< This parameter is relevant only if a node is initialized with
82691 + 'action' = e_FM_PCD_ACTION_EXACT_MATCH and maxNumOfKeys > 0;
82692 + Should be TRUE to reserve table memory for key masks, even if
82693 + initial keys do not contain masks, or if the node was initialized
82694 + as 'empty' (without keys); this will allow user to add keys with
82695 + masks at runtime.
82696 + NOTE that if user want to use only global-masks (i.e. one common mask
82697 + for all the entries within this table, this parameter should set to 'FALSE'. */
82698 + e_FmPcdCcStatsMode statisticsMode; /**< Determines the supported statistics mode for all node's keys.
82699 + To enable statistics gathering, statistics should be enabled per
82700 + every key, using 'statisticsEn' in next engine parameters structure
82701 + of that key;
82702 + If 'maxNumOfKeys' is set, all required structures will be
82703 + preallocated for all keys. */
82704 +#if (DPAA_VERSION >= 11)
82705 + uint16_t frameLengthRanges[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82706 + /**< Relevant only for 'RMON' statistics mode
82707 + (this feature is supported only on B4860 device);
82708 + Holds a list of programmable thresholds - for each received frame,
82709 + its length in bytes is examined against these range thresholds and
82710 + the appropriate counter is incremented by 1 - for example, to belong
82711 + to range i, the following should hold:
82712 + range i-1 threshold < frame length <= range i threshold
82713 + Each range threshold must be larger then its preceding range
82714 + threshold, and last range threshold must be 0xFFFF. */
82715 +#endif /* (DPAA_VERSION >= 11) */
82716 + uint16_t numOfKeys; /**< Number of initial keys;
82717 + Note that in case of 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP,
82718 + this field should be power-of-2 of the number of bits that are
82719 + set in 'icIndxMask'. */
82720 + uint8_t keySize; /**< Size of key - for extraction of type FULL_FIELD, 'keySize' has
82721 + to be the standard size of the selected key; For other extraction
82722 + types, 'keySize' has to be as size of extraction; When 'action' =
82723 + e_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
82724 + t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS];
82725 + /**< An array with 'numOfKeys' entries, each entry specifies the
82726 + corresponding key parameters;
82727 + When 'action' = e_FM_PCD_ACTION_EXACT_MATCH, this value must not
82728 + exceed 255 (FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
82729 + for the 'miss' entry. */
82730 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss;
82731 + /**< Parameters for defining the next engine when a key is not matched;
82732 + Not relevant if action = e_FM_PCD_ACTION_INDEXED_LOOKUP. */
82733 +} t_KeysParams;
82734 +
82735 +
82736 +/**************************************************************************//**
82737 + @Description Parameters for defining a CC node
82738 +*//***************************************************************************/
82739 +typedef struct t_FmPcdCcNodeParams {
82740 + t_FmPcdExtractEntry extractCcParams; /**< Extraction parameters */
82741 + t_KeysParams keysParams; /**< Keys definition matching the selected extraction */
82742 +} t_FmPcdCcNodeParams;
82743 +
82744 +/**************************************************************************//**
82745 + @Description Parameters for defining a hash table
82746 +*//***************************************************************************/
82747 +typedef struct t_FmPcdHashTableParams {
82748 + uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
82749 + e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
82750 + requested statistics mode will be allocated according to maxNumOfKeys. */
82751 + uint8_t kgHashShift; /**< KG-Hash-shift as it was configured in the KG-scheme
82752 + that leads to this hash-table. */
82753 + uint16_t hashResMask; /**< Mask that will be used on the hash-result;
82754 + The number-of-sets for this hash will be calculated
82755 + as (2^(number of bits set in 'hashResMask'));
82756 + The 4 lower bits must be cleared. */
82757 + uint8_t hashShift; /**< Byte offset from the beginning of the KeyGen hash result to the
82758 + 2-bytes to be used as hash index. */
82759 + uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */
82760 +
82761 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */
82762 +
82763 +} t_FmPcdHashTableParams;
82764 +
82765 +/**************************************************************************//**
82766 + @Description Parameters for defining a CC tree group.
82767 +
82768 + This structure defines a CC group in terms of NetEnv units
82769 + and the action to be taken in each case. The unitIds list must
82770 + be given in order from low to high indices.
82771 +
82772 + t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits
82773 + structures where each defines the next action to be taken for
82774 + each units combination. for example:
82775 + numOfDistinctionUnits = 2
82776 + unitIds = {1,3}
82777 + p_NextEnginePerEntriesInGrp[0] = t_FmPcdCcNextEngineParams for the case that
82778 + unit 1 - not found; unit 3 - not found;
82779 + p_NextEnginePerEntriesInGrp[1] = t_FmPcdCcNextEngineParams for the case that
82780 + unit 1 - not found; unit 3 - found;
82781 + p_NextEnginePerEntriesInGrp[2] = t_FmPcdCcNextEngineParams for the case that
82782 + unit 1 - found; unit 3 - not found;
82783 + p_NextEnginePerEntriesInGrp[3] = t_FmPcdCcNextEngineParams for the case that
82784 + unit 1 - found; unit 3 - found;
82785 +*//***************************************************************************/
82786 +typedef struct t_FmPcdCcGrpParams {
82787 + uint8_t numOfDistinctionUnits; /**< Up to 4 */
82788 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS];
82789 + /**< Indices of the units as defined in
82790 + FM_PCD_NetEnvCharacteristicsSet() */
82791 + t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
82792 + /**< Maximum entries per group is 16 */
82793 +} t_FmPcdCcGrpParams;
82794 +
82795 +/**************************************************************************//**
82796 + @Description Parameters for defining CC tree groups
82797 +*//***************************************************************************/
82798 +typedef struct t_FmPcdCcTreeParams {
82799 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82800 + by FM_PCD_NetEnvCharacteristicsSet() */
82801 + uint8_t numOfGrps; /**< Number of CC groups within the CC tree */
82802 + t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
82803 + /**< Parameters for each group. */
82804 +} t_FmPcdCcTreeParams;
82805 +
82806 +
82807 +/**************************************************************************//**
82808 + @Description CC key statistics structure
82809 +*//***************************************************************************/
82810 +typedef struct t_FmPcdCcKeyStatistics {
82811 + uint32_t byteCount; /**< This counter reflects byte count of frames that
82812 + were matched by this key. */
82813 + uint32_t frameCount; /**< This counter reflects count of frames that
82814 + were matched by this key. */
82815 +#if (DPAA_VERSION >= 11)
82816 + uint32_t frameLengthRangeCount[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82817 + /**< These counters reflect how many frames matched
82818 + this key in 'RMON' statistics mode:
82819 + Each counter holds the number of frames of a
82820 + specific frames length range, according to the
82821 + ranges provided at initialization. */
82822 +#endif /* (DPAA_VERSION >= 11) */
82823 +} t_FmPcdCcKeyStatistics;
82824 +
82825 +/**************************************************************************//**
82826 + @Description Parameters for defining policer byte rate
82827 +*//***************************************************************************/
82828 +typedef struct t_FmPcdPlcrByteRateModeParams {
82829 + e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */
82830 + e_FmPcdPlcrRollBackFrameSelect rollBackFrameSelection; /**< relevant option only e_FM_PCD_PLCR_L2_FRM_LEN,
82831 + e_FM_PCD_PLCR_FULL_FRM_LEN */
82832 +} t_FmPcdPlcrByteRateModeParams;
82833 +
82834 +/**************************************************************************//**
82835 + @Description Parameters for defining the policer profile (based on
82836 + RFC-2698 or RFC-4115 attributes).
82837 +*//***************************************************************************/
82838 +typedef struct t_FmPcdPlcrNonPassthroughAlgParams {
82839 + e_FmPcdPlcrRateMode rateMode; /**< Byte mode or Packet mode */
82840 + t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */
82841 + uint32_t committedInfoRate; /**< KBits/Second or Packets/Second */
82842 + uint32_t committedBurstSize; /**< Bytes/Packets */
82843 + uint32_t peakOrExcessInfoRate; /**< KBits/Second or Packets/Second */
82844 + uint32_t peakOrExcessBurstSize; /**< Bytes/Packets */
82845 +} t_FmPcdPlcrNonPassthroughAlgParams;
82846 +
82847 +/**************************************************************************//**
82848 + @Description Parameters for defining the next engine after policer
82849 +*//***************************************************************************/
82850 +typedef union u_FmPcdPlcrNextEngineParams {
82851 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82852 + t_Handle h_Profile; /**< Policer profile handle - used when next engine
82853 + is Policer, must be a SHARED profile */
82854 + t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is KeyGen */
82855 +} u_FmPcdPlcrNextEngineParams;
82856 +
82857 +/**************************************************************************//**
82858 + @Description Parameters for defining the policer profile entry
82859 +*//***************************************************************************/
82860 +typedef struct t_FmPcdPlcrProfileParams {
82861 + bool modify; /**< TRUE to change an existing profile */
82862 + union {
82863 + struct {
82864 + e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */
82865 + t_Handle h_FmPort; /**< Relevant for per-port profiles only */
82866 + uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */
82867 + } newParams; /**< use it when modify = FALSE */
82868 + t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */
82869 + } id;
82870 + e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
82871 + e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */
82872 +
82873 + union {
82874 + e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode; the policer will re-color
82875 + any incoming packet with the default value. */
82876 + e_FmPcdPlcrColor override; /**< For Color-Aware modes; the profile response to a
82877 + pre-color value of 2'b11. */
82878 + } color;
82879 +
82880 + t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 parameters */
82881 +
82882 + e_FmPcdEngine nextEngineOnGreen; /**< Next engine for green-colored frames */
82883 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Next engine parameters for green-colored frames */
82884 +
82885 + e_FmPcdEngine nextEngineOnYellow; /**< Next engine for yellow-colored frames */
82886 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Next engine parameters for yellow-colored frames */
82887 +
82888 + e_FmPcdEngine nextEngineOnRed; /**< Next engine for red-colored frames */
82889 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Next engine parameters for red-colored frames */
82890 +
82891 + bool trapProfileOnFlowA; /**< Obsolete - do not use */
82892 + bool trapProfileOnFlowB; /**< Obsolete - do not use */
82893 + bool trapProfileOnFlowC; /**< Obsolete - do not use */
82894 +} t_FmPcdPlcrProfileParams;
82895 +
82896 +/**************************************************************************//**
82897 + @Description Parameters for selecting a location for requested manipulation
82898 +*//***************************************************************************/
82899 +typedef struct t_FmManipHdrInfo {
82900 + e_NetHeaderType hdr; /**< Header selection */
82901 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
82902 + bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/
82903 + t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */
82904 +} t_FmManipHdrInfo;
82905 +
82906 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82907 +/**************************************************************************//**
82908 + @Description Parameters for defining an insertion manipulation
82909 + of type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE
82910 +*//***************************************************************************/
82911 +typedef struct t_FmPcdManipHdrInsrtByTemplateParams {
82912 + uint8_t size; /**< Size of insert template to the start of the frame. */
82913 + uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE];
82914 + /**< Array of the insertion template. */
82915 +
82916 + bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */
82917 + struct {
82918 + uint16_t ipOuterOffset; /**< Offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/
82919 + uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE.
82920 + in IPV4 dscpEcn only byte - it has to be adjusted to the right*/
82921 + bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/
82922 + uint8_t udpOffset; /**< Offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/
82923 + uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/
82924 + 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.*/
82925 + struct {
82926 + uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP Total Length field.*/
82927 + uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length*/
82928 + uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length.*/
82929 + } recalculateLengthParams; /**< Recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */
82930 + } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */
82931 +
82932 + bool modifyOuterVlan; /**< TRUE if user wants to modify VPri field in the outer VLAN header*/
82933 + struct {
82934 + uint8_t vpri; /**< Value of VPri, relevant if modifyOuterVlan = TRUE
82935 + VPri only 3 bits, it has to be adjusted to the right*/
82936 + } modifyOuterVlanParams;
82937 +} t_FmPcdManipHdrInsrtByTemplateParams;
82938 +
82939 +/**************************************************************************//**
82940 + @Description Parameters for defining CAPWAP fragmentation
82941 +*//***************************************************************************/
82942 +typedef struct t_CapwapFragmentationParams {
82943 + uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/
82944 + bool headerOptionsCompr; /**< TRUE - first fragment include the CAPWAP header options field,
82945 + and all other fragments exclude the CAPWAP options field,
82946 + FALSE - all fragments include CAPWAP header options field. */
82947 +} t_CapwapFragmentationParams;
82948 +
82949 +/**************************************************************************//**
82950 + @Description Parameters for defining CAPWAP reassembly
82951 +*//***************************************************************************/
82952 +typedef struct t_CapwapReassemblyParams {
82953 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be reassembled concurrently; must be power of 2.
82954 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82955 + maxNumFramesInProcess has to be in the range of 4 - 512,
82956 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82957 + maxNumFramesInProcess has to be in the range of 8 - 2048 */
82958 + bool haltOnDuplicationFrag; /**< If TRUE, reassembly process will be halted due to duplicated fragment,
82959 + and all processed fragments will be enqueued with error indication;
82960 + If FALSE, only duplicated fragments will be enqueued with error indication. */
82961 +
82962 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by the reassembly process */
82963 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process */
82964 + uint32_t timeoutRoutineRequestTime;
82965 + /**< Represents the time interval in microseconds between consecutive
82966 + timeout routine requests It has to be power of 2. */
82967 + uint32_t timeoutThresholdForReassmProcess;
82968 + /**< Time interval (microseconds) for marking frames in process as too old;
82969 + Frames in process are those for which at least one fragment was received
82970 + but not all fragments. */
82971 +
82972 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry (needed for the reassembly process) */
82973 +} t_CapwapReassemblyParams;
82974 +
82975 +/**************************************************************************//**
82976 + @Description Parameters for defining fragmentation/reassembly manipulation
82977 +*//***************************************************************************/
82978 +typedef struct t_FmPcdManipFragOrReasmParams {
82979 + bool frag; /**< TRUE if using the structure for fragmentation,
82980 + otherwise this structure is used for reassembly */
82981 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82982 + Same LIODN number is used for these buffers as for
82983 + the received frames buffers, so buffers of this pool
82984 + need to be allocated in the same memory area as the
82985 + received buffers. If the received buffers arrive
82986 + from different sources, the Scatter/Gather BP id
82987 + should be mutual to all these sources. */
82988 + e_NetHeaderType hdr; /**< Header selection */
82989 + union {
82990 + t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation,
82991 + relevant if 'frag' = TRUE, 'hdr' = HEADER_TYPE_CAPWAP */
82992 + t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly,
82993 + relevant if 'frag' = FALSE, 'hdr' = HEADER_TYPE_CAPWAP */
82994 + } u;
82995 +} t_FmPcdManipFragOrReasmParams;
82996 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
82997 +
82998 +
82999 +/**************************************************************************//**
83000 + @Description Parameters for defining header removal by header type
83001 +*//***************************************************************************/
83002 +typedef struct t_FmPcdManipHdrRmvByHdrParams {
83003 + e_FmPcdManipHdrRmvByHdrType type; /**< Selection of header removal location */
83004 + union {
83005 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83006 + struct {
83007 + bool include; /**< If FALSE, remove until the specified header (not including the header);
83008 + If TRUE, remove also the specified header. */
83009 + t_FmManipHdrInfo hdrInfo;
83010 + } fromStartByHdr; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
83011 +#endif /* (DPAA_VERSION >= 11) || ... */
83012 +#if (DPAA_VERSION >= 11)
83013 + t_FmManipHdrInfo hdrInfo; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
83014 +#endif /* (DPAA_VERSION >= 11) */
83015 + e_FmPcdManipHdrRmvSpecificL2 specificL2; /**< Relevant when type = e_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
83016 + Defines which L2 headers to remove. */
83017 + } u;
83018 +} t_FmPcdManipHdrRmvByHdrParams;
83019 +
83020 +/**************************************************************************//**
83021 + @Description Parameters for configuring IP fragmentation manipulation
83022 +
83023 + Restrictions:
83024 + - IP Fragmentation output fragments must not be forwarded to application directly.
83025 + - Maximum number of fragments per frame is 16.
83026 + - Fragmentation of IP fragments is not supported.
83027 + - IPv4 packets containing header Option fields are fragmented by copying all option
83028 + fields to each fragment, regardless of the copy bit value.
83029 + - Transmit confirmation is not supported.
83030 + - Fragmentation after SEC can't handle S/G frames.
83031 + - Fragmentation nodes must be set as the last PCD action (i.e. the
83032 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
83033 + - Only BMan buffers shall be used for frames to be fragmented.
83034 + - IPF does not support VSP. Therefore, on the same port where we have IPF
83035 + we cannot support VSP.
83036 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
83037 + does not support VSP. Therefore, on the same port where we have IPF we
83038 + cannot support VSP.
83039 +*//***************************************************************************/
83040 +typedef struct t_FmPcdManipFragIpParams {
83041 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
83042 + IP fragmentation will be executed.*/
83043 +#if (DPAA_VERSION == 10)
83044 + uint8_t scratchBpid; /**< Absolute buffer pool id according to BM configuration.*/
83045 +#endif /* (DPAA_VERSION == 10) */
83046 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
83047 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
83048 + received frame's buffer. */
83049 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
83050 + This parameters is relevant when 'sgBpidEn=TRUE';
83051 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
83052 + of this pool need to be allocated in the same memory area as the received buffers.
83053 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
83054 + mutual to all these sources. */
83055 + e_FmPcdManipDontFragAction dontFragAction; /**< Don't Fragment Action - If an IP packet is larger
83056 + than MTU and its DF bit is set, then this field will
83057 + determine the action to be taken.*/
83058 +} t_FmPcdManipFragIpParams;
83059 +
83060 +/**************************************************************************//**
83061 + @Description Parameters for configuring IP reassembly manipulation.
83062 +
83063 + This is a common structure for both IPv4 and IPv6 reassembly
83064 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
83065 + set the 'hdr' field in t_FmPcdManipReassemParams to HEADER_TYPE_IPv6.
83066 +
83067 + Restrictions:
83068 + - Application must define at least one scheme to catch the reassembled frames.
83069 + - Maximum number of fragments per frame is 16.
83070 + - Reassembly of IPv4 fragments containing Option fields is supported.
83071 +
83072 +*//***************************************************************************/
83073 +typedef struct t_FmPcdManipReassemIpParams {
83074 + uint8_t relativeSchemeId[2]; /**< Partition relative scheme id:
83075 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
83076 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
83077 + NOTE: The following comment is relevant only for FMAN v2 devices:
83078 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
83079 + the user schemes id to ensure that the reassembly schemes will be first match;
83080 + Rest schemes, if defined, should have higher relative scheme ID. */
83081 +#if (DPAA_VERSION >= 11)
83082 + uint32_t nonConsistentSpFqid; /**< In case that other fragments of the frame corresponds to different storage
83083 + profile than the opening fragment (Non-Consistent-SP state)
83084 + then one of two possible scenarios occurs:
83085 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
83086 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
83087 +#else
83088 + uint8_t sgBpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
83089 +#endif /* (DPAA_VERSION >= 11) */
83090 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
83091 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
83092 + uint16_t minFragSize[2]; /**< Minimum fragment size:
83093 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
83094 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
83095 + /**< Number of frames per hash entry needed for reassembly process:
83096 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
83097 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_FM_PCD_MANIP_SIX_WAYS_HASH). */
83098 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time;
83099 + Must be power of 2;
83100 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
83101 + maxNumFramesInProcess has to be in the range of 4 - 512;
83102 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
83103 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
83104 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
83105 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
83106 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
83107 + uint32_t timeoutThresholdForReassmProcess;
83108 + /**< Represents the time interval in microseconds which defines
83109 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
83110 +} t_FmPcdManipReassemIpParams;
83111 +
83112 +/**************************************************************************//**
83113 + @Description structure for defining IPSEC manipulation
83114 +*//***************************************************************************/
83115 +typedef struct t_FmPcdManipSpecialOffloadIPSecParams {
83116 + bool decryption; /**< TRUE if being used in decryption direction;
83117 + FALSE if being used in encryption direction. */
83118 + bool ecnCopy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
83119 + (direction depends on the 'decryption' field). */
83120 + bool dscpCopy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
83121 + (direction depends on the 'decryption' field). */
83122 + bool variableIpHdrLen; /**< TRUE for supporting variable IP header length in decryption. */
83123 + bool variableIpVersion; /**< TRUE for supporting both IP version on the same SA in encryption */
83124 + uint8_t outerIPHdrLen; /**< if 'variableIpVersion == TRUE' then this field must be set to non-zero value;
83125 + It is specifies the length of the outer IP header that was configured in the
83126 + corresponding SA. */
83127 + uint16_t arwSize; /**< if <> '0' then will perform ARW check for this SA;
83128 + The value must be a multiplication of 16 */
83129 + uintptr_t arwAddr; /**< if arwSize <> '0' then this field must be set to non-zero value;
83130 + MUST be allocated from FMAN's MURAM that the post-sec op-port belongs to;
83131 + Must be 4B aligned. Required MURAM size is 'NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
83132 +} t_FmPcdManipSpecialOffloadIPSecParams;
83133 +
83134 +#if (DPAA_VERSION >= 11)
83135 +/**************************************************************************//**
83136 + @Description Parameters for configuring CAPWAP fragmentation manipulation
83137 +
83138 + Restrictions:
83139 + - Maximum number of fragments per frame is 16.
83140 + - Transmit confirmation is not supported.
83141 + - Fragmentation nodes must be set as the last PCD action (i.e. the
83142 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
83143 + - Only BMan buffers shall be used for frames to be fragmented.
83144 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
83145 + does not support VSP. Therefore, on the same port where we have IPF we
83146 + cannot support VSP.
83147 +*//***************************************************************************/
83148 +typedef struct t_FmPcdManipFragCapwapParams {
83149 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
83150 + CAPWAP fragmentation will be executed.*/
83151 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
83152 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
83153 + received frame's buffer. */
83154 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
83155 + This parameters is relevant when 'sgBpidEn=TRUE';
83156 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
83157 + of this pool need to be allocated in the same memory area as the received buffers.
83158 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
83159 + mutual to all these sources. */
83160 + bool compressModeEn; /**< CAPWAP Header Options Compress Enable mode;
83161 + When this mode is enabled then only the first fragment include the CAPWAP header options
83162 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
83163 + options field (CAPWAP header is updated accordingly).*/
83164 +} t_FmPcdManipFragCapwapParams;
83165 +
83166 +/**************************************************************************//**
83167 + @Description Parameters for configuring CAPWAP reassembly manipulation.
83168 +
83169 + Restrictions:
83170 + - Application must define one scheme to catch the reassembled frames.
83171 + - Maximum number of fragments per frame is 16.
83172 +
83173 +*//***************************************************************************/
83174 +typedef struct t_FmPcdManipReassemCapwapParams {
83175 + uint8_t relativeSchemeId; /**< Partition relative scheme id;
83176 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
83177 + Rest schemes, if defined, should have higher relative scheme ID. */
83178 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
83179 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
83180 + uint16_t maxReassembledFrameLength;/**< The maximum CAPWAP reassembled frame length in bytes;
83181 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
83182 + considered as a valid length;
83183 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
83184 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
83185 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
83186 + /**< Number of frames per hash entry needed for reassembly process */
83187 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by reassembly in the same time;
83188 + Must be power of 2;
83189 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
83190 + maxNumFramesInProcess has to be in the range of 4 - 512;
83191 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
83192 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
83193 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
83194 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
83195 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
83196 + uint32_t timeoutThresholdForReassmProcess;
83197 + /**< Represents the time interval in microseconds which defines
83198 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
83199 +} t_FmPcdManipReassemCapwapParams;
83200 +
83201 +/**************************************************************************//**
83202 + @Description structure for defining CAPWAP manipulation
83203 +*//***************************************************************************/
83204 +typedef struct t_FmPcdManipSpecialOffloadCapwapParams {
83205 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
83206 + e_FmPcdManipHdrQosSrc qosSrc; /**< TODO */
83207 +} t_FmPcdManipSpecialOffloadCapwapParams;
83208 +
83209 +#endif /* (DPAA_VERSION >= 11) */
83210 +
83211 +
83212 +/**************************************************************************//**
83213 + @Description Parameters for defining special offload manipulation
83214 +*//***************************************************************************/
83215 +typedef struct t_FmPcdManipSpecialOffloadParams {
83216 + e_FmPcdManipSpecialOffloadType type; /**< Type of special offload manipulation */
83217 + union
83218 + {
83219 + t_FmPcdManipSpecialOffloadIPSecParams ipsec; /**< Parameters for IPSec; Relevant when
83220 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
83221 +#if (DPAA_VERSION >= 11)
83222 + t_FmPcdManipSpecialOffloadCapwapParams capwap; /**< Parameters for CAPWAP; Relevant when
83223 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
83224 +#endif /* (DPAA_VERSION >= 11) */
83225 + } u;
83226 +} t_FmPcdManipSpecialOffloadParams;
83227 +
83228 +/**************************************************************************//**
83229 + @Description Parameters for defining insertion manipulation
83230 +*//***************************************************************************/
83231 +typedef struct t_FmPcdManipHdrInsrt {
83232 + uint8_t size; /**< size of inserted section */
83233 + uint8_t *p_Data; /**< data to be inserted */
83234 +} t_FmPcdManipHdrInsrt;
83235 +
83236 +
83237 +/**************************************************************************//**
83238 + @Description Parameters for defining generic removal manipulation
83239 +*//***************************************************************************/
83240 +typedef struct t_FmPcdManipHdrRmvGenericParams {
83241 + uint8_t offset; /**< Offset from beginning of header to the start
83242 + location of the removal */
83243 + uint8_t size; /**< Size of removed section */
83244 +} t_FmPcdManipHdrRmvGenericParams;
83245 +
83246 +/**************************************************************************//**
83247 + @Description Parameters for defining generic insertion manipulation
83248 +*//***************************************************************************/
83249 +typedef struct t_FmPcdManipHdrInsrtGenericParams {
83250 + uint8_t offset; /**< Offset from beginning of header to the start
83251 + location of the insertion */
83252 + uint8_t size; /**< Size of inserted section */
83253 + bool replace; /**< TRUE to override (replace) existing data at
83254 + 'offset', FALSE to insert */
83255 + uint8_t *p_Data; /**< Pointer to data to be inserted */
83256 +} t_FmPcdManipHdrInsrtGenericParams;
83257 +
83258 +/**************************************************************************//**
83259 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
83260 +*//***************************************************************************/
83261 +typedef struct t_FmPcdManipHdrFieldUpdateVlanDscpToVpri {
83262 + uint8_t dscpToVpriTable[FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
83263 + /**< A table of VPri values for each DSCP value;
83264 + The index is the DSCP value (0-0x3F) and the
83265 + value is the corresponding VPRI (0-15). */
83266 + uint8_t vpriDefVal; /**< 0-7, Relevant only if if updateType =
83267 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
83268 + this field is the Q Tag default value if the
83269 + IP header is not found. */
83270 +} t_FmPcdManipHdrFieldUpdateVlanDscpToVpri;
83271 +
83272 +/**************************************************************************//**
83273 + @Description Parameters for defining header manipulation VLAN fields updates
83274 +*//***************************************************************************/
83275 +typedef struct t_FmPcdManipHdrFieldUpdateVlan {
83276 + e_FmPcdManipHdrFieldUpdateVlan updateType; /**< Selects VLAN update type */
83277 + union {
83278 + uint8_t vpri; /**< 0-7, Relevant only if If updateType =
83279 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
83280 + is the new VLAN pri. */
83281 + t_FmPcdManipHdrFieldUpdateVlanDscpToVpri dscpToVpri; /**< Parameters structure, Relevant only if updateType
83282 + = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
83283 + } u;
83284 +} t_FmPcdManipHdrFieldUpdateVlan;
83285 +
83286 +/**************************************************************************//**
83287 + @Description Parameters for defining header manipulation IPV4 fields updates
83288 +*//***************************************************************************/
83289 +typedef struct t_FmPcdManipHdrFieldUpdateIpv4 {
83290 + ipv4HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
83291 + uint8_t tos; /**< 8 bit New TOS; Relevant if validUpdates contains
83292 + HDR_MANIP_IPV4_TOS */
83293 + uint16_t id; /**< 16 bit New IP ID; Relevant only if validUpdates
83294 + contains HDR_MANIP_IPV4_ID */
83295 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if validUpdates
83296 + contains HDR_MANIP_IPV4_SRC */
83297 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if validUpdates
83298 + contains HDR_MANIP_IPV4_DST */
83299 +} t_FmPcdManipHdrFieldUpdateIpv4;
83300 +
83301 +/**************************************************************************//**
83302 + @Description Parameters for defining header manipulation IPV6 fields updates
83303 +*//***************************************************************************/
83304 +typedef struct t_FmPcdManipHdrFieldUpdateIpv6 {
83305 + ipv6HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
83306 + uint8_t trafficClass; /**< 8 bit New Traffic Class; Relevant if validUpdates contains
83307 + HDR_MANIP_IPV6_TC */
83308 + uint8_t src[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
83309 + /**< 16 byte new IP SRC; Relevant only if validUpdates
83310 + contains HDR_MANIP_IPV6_SRC */
83311 + uint8_t dst[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
83312 + /**< 16 byte new IP DST; Relevant only if validUpdates
83313 + contains HDR_MANIP_IPV6_DST */
83314 +} t_FmPcdManipHdrFieldUpdateIpv6;
83315 +
83316 +/**************************************************************************//**
83317 + @Description Parameters for defining header manipulation TCP/UDP fields updates
83318 +*//***************************************************************************/
83319 +typedef struct t_FmPcdManipHdrFieldUpdateTcpUdp {
83320 + tcpUdpHdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
83321 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if validUpdates
83322 + contains HDR_MANIP_TCP_UDP_SRC */
83323 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if validUpdates
83324 + contains HDR_MANIP_TCP_UDP_DST */
83325 +} t_FmPcdManipHdrFieldUpdateTcpUdp;
83326 +
83327 +/**************************************************************************//**
83328 + @Description Parameters for defining header manipulation fields updates
83329 +*//***************************************************************************/
83330 +typedef struct t_FmPcdManipHdrFieldUpdateParams {
83331 + e_FmPcdManipHdrFieldUpdateType type; /**< Type of header field update manipulation */
83332 + union {
83333 + t_FmPcdManipHdrFieldUpdateVlan vlan; /**< Parameters for VLAN update. Relevant when
83334 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
83335 + t_FmPcdManipHdrFieldUpdateIpv4 ipv4; /**< Parameters for IPv4 update. Relevant when
83336 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
83337 + t_FmPcdManipHdrFieldUpdateIpv6 ipv6; /**< Parameters for IPv6 update. Relevant when
83338 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
83339 + t_FmPcdManipHdrFieldUpdateTcpUdp tcpUdp; /**< Parameters for TCP/UDP update. Relevant when
83340 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
83341 + } u;
83342 +} t_FmPcdManipHdrFieldUpdateParams;
83343 +
83344 +
83345 +
83346 +/**************************************************************************//**
83347 + @Description Parameters for defining custom header manipulation for generic field replacement
83348 +*//***************************************************************************/
83349 +typedef struct t_FmPcdManipHdrCustomGenFieldReplace {
83350 + uint8_t srcOffset; /**< Location of new data - Offset from
83351 + Parse Result (>= 16, srcOffset+size <= 32, ) */
83352 + uint8_t dstOffset; /**< Location of data to be overwritten - Offset from
83353 + start of frame (dstOffset + size <= 256). */
83354 + uint8_t size; /**< The number of bytes (<=16) to be replaced */
83355 + uint8_t mask; /**< Optional 1 byte mask. Set to select bits for
83356 + replacement (1 - bit will be replaced);
83357 + Clear to use field as is. */
83358 + uint8_t maskOffset; /**< Relevant if mask != 0;
83359 + Mask offset within the replaces "size" */
83360 +} t_FmPcdManipHdrCustomGenFieldReplace;
83361 +
83362 +/**************************************************************************//**
83363 + @Description Parameters for defining custom header manipulation for IP replacement
83364 +*//***************************************************************************/
83365 +typedef struct t_FmPcdManipHdrCustomIpHdrReplace {
83366 + e_FmPcdManipHdrCustomIpReplace replaceType; /**< Selects replace update type */
83367 + bool decTtlHl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
83368 + bool updateIpv4Id; /**< Relevant when replaceType =
83369 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
83370 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
83371 + updateIpv4Id = TRUE */
83372 + uint8_t hdrSize; /**< The size of the new IP header */
83373 + uint8_t hdr[FM_PCD_MANIP_MAX_HDR_SIZE];
83374 + /**< The new IP header */
83375 +} t_FmPcdManipHdrCustomIpHdrReplace;
83376 +
83377 +/**************************************************************************//**
83378 + @Description Parameters for defining custom header manipulation
83379 +*//***************************************************************************/
83380 +typedef struct t_FmPcdManipHdrCustomParams {
83381 + e_FmPcdManipHdrCustomType type; /**< Type of header field update manipulation */
83382 + union {
83383 + t_FmPcdManipHdrCustomIpHdrReplace ipHdrReplace; /**< Parameters IP header replacement */
83384 + t_FmPcdManipHdrCustomGenFieldReplace genFieldReplace; /**< Parameters IP header replacement */
83385 + } u;
83386 +} t_FmPcdManipHdrCustomParams;
83387 +
83388 +/**************************************************************************//**
83389 + @Description Parameters for defining specific L2 insertion manipulation
83390 +*//***************************************************************************/
83391 +typedef struct t_FmPcdManipHdrInsrtSpecificL2Params {
83392 + e_FmPcdManipHdrInsrtSpecificL2 specificL2; /**< Selects which L2 headers to insert */
83393 + bool update; /**< TRUE to update MPLS header */
83394 + uint8_t size; /**< size of inserted section */
83395 + uint8_t *p_Data; /**< data to be inserted */
83396 +} t_FmPcdManipHdrInsrtSpecificL2Params;
83397 +
83398 +#if (DPAA_VERSION >= 11)
83399 +/**************************************************************************//**
83400 + @Description Parameters for defining IP insertion manipulation
83401 +*//***************************************************************************/
83402 +typedef struct t_FmPcdManipHdrInsrtIpParams {
83403 + bool calcL4Checksum; /**< Calculate L4 checksum. */
83404 + e_FmPcdManipHdrQosMappingMode mappingMode; /**< TODO */
83405 + uint8_t lastPidOffset; /**< the offset of the last Protocol within
83406 + the inserted header */
83407 + uint16_t id; /**< 16 bit New IP ID */
83408 + bool dontFragOverwrite;
83409 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
83410 + * This byte is configured to be overwritten when RPD is set. */
83411 + uint8_t lastDstOffset;
83412 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
83413 + * in order to calculate UDP checksum pseudo header;
83414 + * Otherwise set it to '0'. */
83415 + t_FmPcdManipHdrInsrt insrt; /**< size and data to be inserted. */
83416 +} t_FmPcdManipHdrInsrtIpParams;
83417 +#endif /* (DPAA_VERSION >= 11) */
83418 +
83419 +/**************************************************************************//**
83420 + @Description Parameters for defining header insertion manipulation by header type
83421 +*//***************************************************************************/
83422 +typedef struct t_FmPcdManipHdrInsrtByHdrParams {
83423 + e_FmPcdManipHdrInsrtByHdrType type; /**< Selects manipulation type */
83424 + union {
83425 +
83426 + t_FmPcdManipHdrInsrtSpecificL2Params specificL2Params;
83427 + /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
83428 + Selects which L2 headers to insert */
83429 +#if (DPAA_VERSION >= 11)
83430 + t_FmPcdManipHdrInsrtIpParams ipParams; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
83431 + t_FmPcdManipHdrInsrt insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
83432 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
83433 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
83434 +#endif /* (DPAA_VERSION >= 11) */
83435 + } u;
83436 +} t_FmPcdManipHdrInsrtByHdrParams;
83437 +
83438 +/**************************************************************************//**
83439 + @Description Parameters for defining header insertion manipulation
83440 +*//***************************************************************************/
83441 +typedef struct t_FmPcdManipHdrInsrtParams {
83442 + e_FmPcdManipHdrInsrtType type; /**< Type of insertion manipulation */
83443 + union {
83444 + t_FmPcdManipHdrInsrtByHdrParams byHdr; /**< Parameters for defining header insertion manipulation by header type,
83445 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_HDR */
83446 + t_FmPcdManipHdrInsrtGenericParams generic; /**< Parameters for defining generic header insertion manipulation,
83447 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_GENERIC */
83448 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83449 + t_FmPcdManipHdrInsrtByTemplateParams byTemplate; /**< Parameters for defining header insertion manipulation by template,
83450 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
83451 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83452 + } u;
83453 +} t_FmPcdManipHdrInsrtParams;
83454 +
83455 +/**************************************************************************//**
83456 + @Description Parameters for defining header removal manipulation
83457 +*//***************************************************************************/
83458 +typedef struct t_FmPcdManipHdrRmvParams {
83459 + e_FmPcdManipHdrRmvType type; /**< Type of header removal manipulation */
83460 + union {
83461 + t_FmPcdManipHdrRmvByHdrParams byHdr; /**< Parameters for defining header removal manipulation by header type,
83462 + relevant if type = e_FM_PCD_MANIP_RMV_BY_HDR */
83463 + t_FmPcdManipHdrRmvGenericParams generic; /**< Parameters for defining generic header removal manipulation,
83464 + relevant if type = e_FM_PCD_MANIP_RMV_GENERIC */
83465 + } u;
83466 +} t_FmPcdManipHdrRmvParams;
83467 +
83468 +/**************************************************************************//**
83469 + @Description Parameters for defining header manipulation node
83470 +*//***************************************************************************/
83471 +typedef struct t_FmPcdManipHdrParams {
83472 + bool rmv; /**< TRUE, to define removal manipulation */
83473 + t_FmPcdManipHdrRmvParams rmvParams; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
83474 +
83475 + bool insrt; /**< TRUE, to define insertion manipulation */
83476 + t_FmPcdManipHdrInsrtParams insrtParams; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
83477 +
83478 + bool fieldUpdate; /**< TRUE, to define field update manipulation */
83479 + t_FmPcdManipHdrFieldUpdateParams fieldUpdateParams; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
83480 +
83481 + bool custom; /**< TRUE, to define custom manipulation */
83482 + t_FmPcdManipHdrCustomParams customParams; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
83483 +
83484 + bool dontParseAfterManip;/**< TRUE to de-activate the parser after the manipulation defined in this node.
83485 + Restrictions:
83486 + 1. MUST be set if the next engine after the CC is not another CC node
83487 + (but rather Policer or Keygen), and this is the last (no h_NextManip) in a chain
83488 + of manipulation nodes. This includes single nodes (i.e. no h_NextManip and
83489 + also never pointed as h_NextManip of other manipulation nodes)
83490 + 2. MUST be set if the next engine after the CC is another CC node, and
83491 + this is NOT the last manipulation node (i.e. it has h_NextManip).*/
83492 +} t_FmPcdManipHdrParams;
83493 +
83494 +/**************************************************************************//**
83495 + @Description Parameters for defining fragmentation manipulation
83496 +*//***************************************************************************/
83497 +typedef struct t_FmPcdManipFragParams {
83498 + e_NetHeaderType hdr; /**< Header selection */
83499 + union {
83500 +#if (DPAA_VERSION >= 11)
83501 + t_FmPcdManipFragCapwapParams capwapFrag; /**< Parameters for defining CAPWAP fragmentation,
83502 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83503 +#endif /* (DPAA_VERSION >= 11) */
83504 + t_FmPcdManipFragIpParams ipFrag; /**< Parameters for defining IP fragmentation,
83505 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83506 + } u;
83507 +} t_FmPcdManipFragParams;
83508 +
83509 +/**************************************************************************//**
83510 + @Description Parameters for defining reassembly manipulation
83511 +*//***************************************************************************/
83512 +typedef struct t_FmPcdManipReassemParams {
83513 + e_NetHeaderType hdr; /**< Header selection */
83514 + union {
83515 +#if (DPAA_VERSION >= 11)
83516 + t_FmPcdManipReassemCapwapParams capwapReassem; /**< Parameters for defining CAPWAP reassembly,
83517 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83518 +#endif /* (DPAA_VERSION >= 11) */
83519 +
83520 + t_FmPcdManipReassemIpParams ipReassem; /**< Parameters for defining IP reassembly,
83521 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83522 + } u;
83523 +} t_FmPcdManipReassemParams;
83524 +
83525 +/**************************************************************************//**
83526 + @Description Parameters for defining a manipulation node
83527 +*//***************************************************************************/
83528 +typedef struct t_FmPcdManipParams {
83529 + e_FmPcdManipType type; /**< Selects type of manipulation node */
83530 + union{
83531 + t_FmPcdManipHdrParams hdr; /**< Parameters for defining header manipulation node */
83532 + t_FmPcdManipReassemParams reassem; /**< Parameters for defining reassembly manipulation node */
83533 + t_FmPcdManipFragParams frag; /**< Parameters for defining fragmentation manipulation node */
83534 + t_FmPcdManipSpecialOffloadParams specialOffload; /**< Parameters for defining special offload manipulation node */
83535 + } u;
83536 +
83537 + t_Handle h_NextManip; /**< Supported for Header Manipulation only;
83538 + Handle to another (previously defined) manipulation node;
83539 + Allows concatenation of manipulation actions;
83540 + This parameter is optional and may be NULL. */
83541 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83542 + bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */
83543 + t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation,
83544 + relevant if fragOrReasm = TRUE */
83545 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83546 +} t_FmPcdManipParams;
83547 +
83548 +/**************************************************************************//**
83549 + @Description Structure for retrieving IP reassembly statistics
83550 +*//***************************************************************************/
83551 +typedef struct t_FmPcdManipReassemIpStats {
83552 + /* common counters for both IPv4 and IPv6 */
83553 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83554 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83555 + a Reassembly Frame Descriptor */
83556 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83557 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83558 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83559 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83560 +#if (DPAA_VERSION >= 11)
83561 + uint32_t nonConsistentSp; /**< Counts the number of Non Consistent Storage Profile events for
83562 + successfully reassembled frames */
83563 +#endif /* (DPAA_VERSION >= 11) */
83564 + struct {
83565 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83566 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83567 + have been processed for all frames */
83568 + uint32_t processedFragments; /**< Counts the number of processed fragments
83569 + (valid and error fragments) for all frames */
83570 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83571 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83572 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83573 + to access an IP-Reassembly Automatic Learning Hash set */
83574 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83575 + exceeds 16 */
83576 + } specificHdrStatistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
83577 +} t_FmPcdManipReassemIpStats;
83578 +
83579 +/**************************************************************************//**
83580 + @Description Structure for retrieving IP fragmentation statistics
83581 +*//***************************************************************************/
83582 +typedef struct t_FmPcdManipFragIpStats {
83583 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83584 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83585 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83586 +} t_FmPcdManipFragIpStats;
83587 +
83588 +#if (DPAA_VERSION >= 11)
83589 +/**************************************************************************//**
83590 + @Description Structure for retrieving CAPWAP reassembly statistics
83591 +*//***************************************************************************/
83592 +typedef struct t_FmPcdManipReassemCapwapStats {
83593 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83594 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83595 + a Reassembly Frame Descriptor */
83596 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83597 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83598 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83599 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83600 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83601 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83602 + have been processed for all frames */
83603 + uint32_t processedFragments; /**< Counts the number of processed fragments
83604 + (valid and error fragments) for all frames */
83605 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83606 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83607 + to access an Reassembly Automatic Learning Hash set */
83608 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83609 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83610 + exceeds 16 */
83611 + uint32_t exceedMaxReassemblyFrameLen;/**< ounts the number of times that a successful reassembled frame
83612 + length exceeds MaxReassembledFrameLength value */
83613 +} t_FmPcdManipReassemCapwapStats;
83614 +
83615 +/**************************************************************************//**
83616 + @Description Structure for retrieving CAPWAP fragmentation statistics
83617 +*//***************************************************************************/
83618 +typedef struct t_FmPcdManipFragCapwapStats {
83619 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83620 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83621 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83622 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
83623 + uint8_t sgAllocationFailure; /**< Number of allocation failure of s/g buffers */
83624 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
83625 +} t_FmPcdManipFragCapwapStats;
83626 +#endif /* (DPAA_VERSION >= 11) */
83627 +
83628 +/**************************************************************************//**
83629 + @Description Structure for retrieving reassembly statistics
83630 +*//***************************************************************************/
83631 +typedef struct t_FmPcdManipReassemStats {
83632 + union {
83633 + t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */
83634 +#if (DPAA_VERSION >= 11)
83635 + t_FmPcdManipReassemCapwapStats capwapReassem; /**< Structure for CAPWAP reassembly statistics */
83636 +#endif /* (DPAA_VERSION >= 11) */
83637 + } u;
83638 +} t_FmPcdManipReassemStats;
83639 +
83640 +/**************************************************************************//**
83641 + @Description Structure for retrieving fragmentation statistics
83642 +*//***************************************************************************/
83643 +typedef struct t_FmPcdManipFragStats {
83644 + union {
83645 + t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */
83646 +#if (DPAA_VERSION >= 11)
83647 + t_FmPcdManipFragCapwapStats capwapFrag; /**< Structure for CAPWAP fragmentation statistics */
83648 +#endif /* (DPAA_VERSION >= 11) */
83649 + } u;
83650 +} t_FmPcdManipFragStats;
83651 +
83652 +/**************************************************************************//**
83653 + @Description Structure for selecting manipulation statistics
83654 +*//***************************************************************************/
83655 +typedef struct t_FmPcdManipStats {
83656 + union {
83657 + t_FmPcdManipReassemStats reassem; /**< Structure for reassembly statistics */
83658 + t_FmPcdManipFragStats frag; /**< Structure for fragmentation statistics */
83659 + } u;
83660 +} t_FmPcdManipStats;
83661 +
83662 +#if (DPAA_VERSION >= 11)
83663 +/**************************************************************************//**
83664 + @Description Parameters for defining frame replicator group and its members
83665 +*//***************************************************************************/
83666 +typedef struct t_FmPcdFrmReplicGroupParams {
83667 + uint8_t maxNumOfEntries; /**< Maximal number of members in the group;
83668 + Must be at least 2. */
83669 + uint8_t numOfEntries; /**< Number of members in the group;
83670 + Must be at least 1. */
83671 + t_FmPcdCcNextEngineParams nextEngineParams[FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
83672 + /**< Array of members' parameters */
83673 +} t_FmPcdFrmReplicGroupParams;
83674 +#endif /* (DPAA_VERSION >= 11) */
83675 +
83676 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83677 +/**************************************************************************//**
83678 + @Description structure for defining statistics node
83679 +*//***************************************************************************/
83680 +typedef struct t_FmPcdStatsParams {
83681 + e_FmPcdStatsType type; /**< type of statistics node */
83682 +} t_FmPcdStatsParams;
83683 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83684 +
83685 +/**************************************************************************//**
83686 + @Function FM_PCD_NetEnvCharacteristicsSet
83687 +
83688 + @Description Define a set of Network Environment Characteristics.
83689 +
83690 + When setting an environment it is important to understand its
83691 + application. It is not meant to describe the flows that will run
83692 + on the ports using this environment, but what the user means TO DO
83693 + with the PCD mechanisms in order to parse-classify-distribute those
83694 + frames.
83695 + By specifying a distinction unit, the user means it would use that option
83696 + for distinction between frames at either a KeyGen scheme or a coarse
83697 + classification action descriptor. Using interchangeable headers to define a
83698 + unit means that the user is indifferent to which of the interchangeable
83699 + headers is present in the frame, and wants the distinction to be based
83700 + on the presence of either one of them.
83701 +
83702 + Depending on context, there are limitations to the use of environments. A
83703 + port using the PCD functionality is bound to an environment. Some or even
83704 + all ports may share an environment but also an environment per port is
83705 + possible. When initializing a scheme, a classification plan group (see below),
83706 + or a coarse classification tree, one of the initialized environments must be
83707 + stated and related to. When a port is bound to a scheme, a classification
83708 + plan group, or a coarse classification tree, it MUST be bound to the same
83709 + environment.
83710 +
83711 + The different PCD modules, may relate (for flows definition) ONLY on
83712 + distinction units as defined by their environment. When initializing a
83713 + scheme for example, it may not choose to select IPV4 as a match for
83714 + recognizing flows unless it was defined in the relating environment. In
83715 + fact, to guide the user through the configuration of the PCD, each module's
83716 + characterization in terms of flows is not done using protocol names, but using
83717 + environment indexes.
83718 +
83719 + In terms of HW implementation, the list of distinction units sets the LCV vectors
83720 + and later used for match vector, classification plan vectors and coarse classification
83721 + indexing.
83722 +
83723 + @Param[in] h_FmPcd FM PCD module descriptor.
83724 + @Param[in] p_NetEnvParams A structure of parameters for the initialization of
83725 + the network environment.
83726 +
83727 + @Return A handle to the initialized object on success; NULL code otherwise.
83728 +
83729 + @Cautions Allowed only following FM_PCD_Init().
83730 +*//***************************************************************************/
83731 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams);
83732 +
83733 +/**************************************************************************//**
83734 + @Function FM_PCD_NetEnvCharacteristicsDelete
83735 +
83736 + @Description Deletes a set of Network Environment Characteristics.
83737 +
83738 + @Param[in] h_NetEnv A handle to the Network environment.
83739 +
83740 + @Return E_OK on success; Error code otherwise.
83741 +*//***************************************************************************/
83742 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv);
83743 +
83744 +/**************************************************************************//**
83745 + @Function FM_PCD_KgSchemeSet
83746 +
83747 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
83748 + This routine should be called for adding or modifying a scheme.
83749 + When a scheme needs modifying, the API requires that it will be
83750 + rewritten. In such a case 'modify' should be TRUE. If the
83751 + routine is called for a valid scheme and 'modify' is FALSE,
83752 + it will return error.
83753 +
83754 + @Param[in] h_FmPcd If this is a new scheme - A handle to an FM PCD Module.
83755 + Otherwise NULL (ignored by driver).
83756 + @Param[in,out] p_SchemeParams A structure of parameters for defining the scheme
83757 +
83758 + @Return A handle to the initialized scheme on success; NULL code otherwise.
83759 + When used as "modify" (rather than for setting a new scheme),
83760 + p_SchemeParams->id.h_Scheme will return NULL if action fails due to scheme
83761 + BUSY state.
83762 +
83763 + @Cautions Allowed only following FM_PCD_Init().
83764 +*//***************************************************************************/
83765 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd,
83766 + t_FmPcdKgSchemeParams *p_SchemeParams);
83767 +
83768 +/**************************************************************************//**
83769 + @Function FM_PCD_KgSchemeDelete
83770 +
83771 + @Description Deleting an initialized scheme.
83772 +
83773 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet()
83774 +
83775 + @Return E_OK on success; Error code otherwise.
83776 +
83777 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83778 +*//***************************************************************************/
83779 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme);
83780 +
83781 +/**************************************************************************//**
83782 + @Function FM_PCD_KgSchemeGetCounter
83783 +
83784 + @Description Reads scheme packet counter.
83785 +
83786 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83787 +
83788 + @Return Counter's current value.
83789 +
83790 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83791 +*//***************************************************************************/
83792 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme);
83793 +
83794 +/**************************************************************************//**
83795 + @Function FM_PCD_KgSchemeSetCounter
83796 +
83797 + @Description Writes scheme packet counter.
83798 +
83799 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83800 + @Param[in] value New scheme counter value - typically '0' for
83801 + resetting the counter.
83802 +
83803 + @Return E_OK on success; Error code otherwise.
83804 +
83805 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83806 +*//***************************************************************************/
83807 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value);
83808 +
83809 +/**************************************************************************//**
83810 + @Function FM_PCD_PlcrProfileSet
83811 +
83812 + @Description Sets a profile entry in the policer profile table.
83813 + The routine overrides any existing value.
83814 +
83815 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83816 + @Param[in] p_Profile A structure of parameters for defining a
83817 + policer profile entry.
83818 +
83819 + @Return A handle to the initialized object on success; NULL code otherwise.
83820 + When used as "modify" (rather than for setting a new profile),
83821 + p_Profile->id.h_Profile will return NULL if action fails due to profile
83822 + BUSY state.
83823 + @Cautions Allowed only following FM_PCD_Init().
83824 +*//***************************************************************************/
83825 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
83826 + t_FmPcdPlcrProfileParams *p_Profile);
83827 +
83828 +/**************************************************************************//**
83829 + @Function FM_PCD_PlcrProfileDelete
83830 +
83831 + @Description Delete a profile entry in the policer profile table.
83832 + The routine set entry to invalid.
83833 +
83834 + @Param[in] h_Profile A handle to the profile.
83835 +
83836 + @Return E_OK on success; Error code otherwise.
83837 +
83838 + @Cautions Allowed only following FM_PCD_Init().
83839 +*//***************************************************************************/
83840 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile);
83841 +
83842 +/**************************************************************************//**
83843 + @Function FM_PCD_PlcrProfileGetCounter
83844 +
83845 + @Description Sets an entry in the classification plan.
83846 + The routine overrides any existing value.
83847 +
83848 + @Param[in] h_Profile A handle to the profile.
83849 + @Param[in] counter Counter selector.
83850 +
83851 + @Return specific counter value.
83852 +
83853 + @Cautions Allowed only following FM_PCD_Init().
83854 +*//***************************************************************************/
83855 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile,
83856 + e_FmPcdPlcrProfileCounters counter);
83857 +
83858 +/**************************************************************************//**
83859 + @Function FM_PCD_PlcrProfileSetCounter
83860 +
83861 + @Description Sets an entry in the classification plan.
83862 + The routine overrides any existing value.
83863 +
83864 + @Param[in] h_Profile A handle to the profile.
83865 + @Param[in] counter Counter selector.
83866 + @Param[in] value value to set counter with.
83867 +
83868 + @Return E_OK on success; Error code otherwise.
83869 +
83870 + @Cautions Allowed only following FM_PCD_Init().
83871 +*//***************************************************************************/
83872 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile,
83873 + e_FmPcdPlcrProfileCounters counter,
83874 + uint32_t value);
83875 +
83876 +/**************************************************************************//**
83877 + @Function FM_PCD_CcRootBuild
83878 +
83879 + @Description This routine must be called to define a complete coarse
83880 + classification tree. This is the way to define coarse
83881 + classification to a certain flow - the KeyGen schemes
83882 + may point only to trees defined in this way.
83883 +
83884 + @Param[in] h_FmPcd FM PCD module descriptor.
83885 + @Param[in] p_Params A structure of parameters to define the tree.
83886 +
83887 + @Return A handle to the initialized object on success; NULL code otherwise.
83888 +
83889 + @Cautions Allowed only following FM_PCD_Init().
83890 +*//***************************************************************************/
83891 +t_Handle FM_PCD_CcRootBuild (t_Handle h_FmPcd,
83892 + t_FmPcdCcTreeParams *p_Params);
83893 +
83894 +/**************************************************************************//**
83895 + @Function FM_PCD_CcRootDelete
83896 +
83897 + @Description Deleting an built tree.
83898 +
83899 + @Param[in] h_CcTree A handle to a CC tree.
83900 +
83901 + @Return E_OK on success; Error code otherwise.
83902 +
83903 + @Cautions Allowed only following FM_PCD_Init().
83904 +*//***************************************************************************/
83905 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree);
83906 +
83907 +/**************************************************************************//**
83908 + @Function FM_PCD_CcRootModifyNextEngine
83909 +
83910 + @Description Modify the Next Engine Parameters in the entry of the tree.
83911 +
83912 + @Param[in] h_CcTree A handle to the tree
83913 + @Param[in] grpId A Group index in the tree
83914 + @Param[in] index Entry index in the group defined by grpId
83915 + @Param[in] p_FmPcdCcNextEngineParams Pointer to new next engine parameters
83916 +
83917 + @Return E_OK on success; Error code otherwise.
83918 +
83919 + @Cautions Allowed only following FM_PCD_CcBuildTree().
83920 +*//***************************************************************************/
83921 +t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree,
83922 + uint8_t grpId,
83923 + uint8_t index,
83924 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83925 +
83926 +/**************************************************************************//**
83927 + @Function FM_PCD_MatchTableSet
83928 +
83929 + @Description This routine should be called for each CC (coarse classification)
83930 + node. The whole CC tree should be built bottom up so that each
83931 + node points to already defined nodes.
83932 +
83933 + @Param[in] h_FmPcd FM PCD module descriptor.
83934 + @Param[in] p_Param A structure of parameters defining the CC node
83935 +
83936 + @Return A handle to the initialized object on success; NULL code otherwise.
83937 +
83938 + @Cautions Allowed only following FM_PCD_Init().
83939 +*//***************************************************************************/
83940 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_Param);
83941 +
83942 +/**************************************************************************//**
83943 + @Function FM_PCD_MatchTableDelete
83944 +
83945 + @Description Deleting an built node.
83946 +
83947 + @Param[in] h_CcNode A handle to a CC node.
83948 +
83949 + @Return E_OK on success; Error code otherwise.
83950 +
83951 + @Cautions Allowed only following FM_PCD_Init().
83952 +*//***************************************************************************/
83953 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode);
83954 +
83955 +/**************************************************************************//**
83956 + @Function FM_PCD_MatchTableModifyMissNextEngine
83957 +
83958 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
83959 +
83960 + @Param[in] h_CcNode A handle to the node
83961 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83962 +
83963 + @Return E_OK on success; Error code otherwise.
83964 +
83965 + @Cautions Allowed only following FM_PCD_MatchTableSet();
83966 + Not relevant in the case the node is of type 'INDEXED_LOOKUP'.
83967 + When configuring nextEngine = e_FM_PCD_CC, note that
83968 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83969 + from the currently changed table.
83970 +
83971 +*//***************************************************************************/
83972 +t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode,
83973 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83974 +
83975 +/**************************************************************************//**
83976 + @Function FM_PCD_MatchTableRemoveKey
83977 +
83978 + @Description Remove the key (including next engine parameters of this key)
83979 + defined by the index of the relevant node.
83980 +
83981 + @Param[in] h_CcNode A handle to the node
83982 + @Param[in] keyIndex Key index for removing
83983 +
83984 + @Return E_OK on success; Error code otherwise.
83985 +
83986 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83987 + node and the nodes that lead to it.
83988 +*//***************************************************************************/
83989 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex);
83990 +
83991 +/**************************************************************************//**
83992 + @Function FM_PCD_MatchTableAddKey
83993 +
83994 + @Description Add the key (including next engine parameters of this key in the
83995 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
83996 + may be used by user that don't care about the position of the
83997 + key in the table - in that case, the key will be automatically
83998 + added by the driver in the last available entry.
83999 +
84000 + @Param[in] h_CcNode A handle to the node
84001 + @Param[in] keyIndex Key index for adding.
84002 + @Param[in] keySize Key size of added key
84003 + @Param[in] p_KeyParams A pointer to the parameters includes
84004 + new key with Next Engine Parameters
84005 +
84006 + @Return E_OK on success; Error code otherwise.
84007 +
84008 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
84009 + node and the nodes that lead to it.
84010 +*//***************************************************************************/
84011 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode,
84012 + uint16_t keyIndex,
84013 + uint8_t keySize,
84014 + t_FmPcdCcKeyParams *p_KeyParams);
84015 +
84016 +/**************************************************************************//**
84017 + @Function FM_PCD_MatchTableModifyNextEngine
84018 +
84019 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
84020 +
84021 + @Param[in] h_CcNode A handle to the node
84022 + @Param[in] keyIndex Key index for Next Engine modifications
84023 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
84024 +
84025 + @Return E_OK on success; Error code otherwise.
84026 +
84027 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84028 + When configuring nextEngine = e_FM_PCD_CC, note that
84029 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84030 + from the currently changed table.
84031 +
84032 +*//***************************************************************************/
84033 +t_Error FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode,
84034 + uint16_t keyIndex,
84035 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84036 +
84037 +/**************************************************************************//**
84038 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
84039 +
84040 + @Description Modify the key and Next Engine Parameters of this key in the
84041 + index defined by the keyIndex.
84042 +
84043 + @Param[in] h_CcNode A handle to the node
84044 + @Param[in] keyIndex Key index for adding
84045 + @Param[in] keySize Key size of added key
84046 + @Param[in] p_KeyParams A pointer to the parameters includes
84047 + modified key and modified Next Engine Parameters
84048 +
84049 + @Return E_OK on success; Error code otherwise.
84050 +
84051 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
84052 + node and the nodes that lead to it.
84053 + When configuring nextEngine = e_FM_PCD_CC, note that
84054 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84055 + from the currently changed table.
84056 +*//***************************************************************************/
84057 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
84058 + uint16_t keyIndex,
84059 + uint8_t keySize,
84060 + t_FmPcdCcKeyParams *p_KeyParams);
84061 +
84062 +/**************************************************************************//**
84063 + @Function FM_PCD_MatchTableModifyKey
84064 +
84065 + @Description Modify the key in the index defined by the keyIndex.
84066 +
84067 + @Param[in] h_CcNode A handle to the node
84068 + @Param[in] keyIndex Key index for adding
84069 + @Param[in] keySize Key size of added key
84070 + @Param[in] p_Key A pointer to the new key
84071 + @Param[in] p_Mask A pointer to the new mask if relevant,
84072 + otherwise pointer to NULL
84073 +
84074 + @Return E_OK on success; Error code otherwise.
84075 +
84076 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
84077 + node and the nodes that lead to it.
84078 +*//***************************************************************************/
84079 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode,
84080 + uint16_t keyIndex,
84081 + uint8_t keySize,
84082 + uint8_t *p_Key,
84083 + uint8_t *p_Mask);
84084 +
84085 +/**************************************************************************//**
84086 + @Function FM_PCD_MatchTableFindNRemoveKey
84087 +
84088 + @Description Remove the key (including next engine parameters of this key)
84089 + defined by the key and mask. Note that this routine will search
84090 + the node to locate the index of the required key (& mask) to remove.
84091 +
84092 + @Param[in] h_CcNode A handle to the node
84093 + @Param[in] keySize Key size of the one to remove.
84094 + @Param[in] p_Key A pointer to the requested key to remove.
84095 + @Param[in] p_Mask A pointer to the mask if relevant,
84096 + otherwise pointer to NULL
84097 +
84098 + @Return E_OK on success; Error code otherwise.
84099 +
84100 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
84101 + node and the nodes that lead to it.
84102 +*//***************************************************************************/
84103 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode,
84104 + uint8_t keySize,
84105 + uint8_t *p_Key,
84106 + uint8_t *p_Mask);
84107 +
84108 +/**************************************************************************//**
84109 + @Function FM_PCD_MatchTableFindNModifyNextEngine
84110 +
84111 + @Description Modify the Next Engine Parameters in the relevant key entry of
84112 + the node. Note that this routine will search the node to locate
84113 + the index of the required key (& mask) to modify.
84114 +
84115 + @Param[in] h_CcNode A handle to the node
84116 + @Param[in] keySize Key size of the one to modify.
84117 + @Param[in] p_Key A pointer to the requested key to modify.
84118 + @Param[in] p_Mask A pointer to the mask if relevant,
84119 + otherwise pointer to NULL
84120 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
84121 +
84122 + @Return E_OK on success; Error code otherwise.
84123 +
84124 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84125 + When configuring nextEngine = e_FM_PCD_CC, note that
84126 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84127 + from the currently changed table.
84128 +*//***************************************************************************/
84129 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode,
84130 + uint8_t keySize,
84131 + uint8_t *p_Key,
84132 + uint8_t *p_Mask,
84133 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84134 +
84135 +/**************************************************************************//**
84136 + @Function FM_PCD_MatchTableFindNModifyKeyAndNextEngine
84137 +
84138 + @Description Modify the key and Next Engine Parameters of this key in the
84139 + index defined by the keyIndex. Note that this routine will search
84140 + the node to locate the index of the required key (& mask) to modify.
84141 +
84142 + @Param[in] h_CcNode A handle to the node
84143 + @Param[in] keySize Key size of the one to modify.
84144 + @Param[in] p_Key A pointer to the requested key to modify.
84145 + @Param[in] p_Mask A pointer to the mask if relevant,
84146 + otherwise pointer to NULL
84147 + @Param[in] p_KeyParams A pointer to the parameters includes
84148 + modified key and modified Next Engine Parameters
84149 +
84150 + @Return E_OK on success; Error code otherwise.
84151 +
84152 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
84153 + node and the nodes that lead to it.
84154 + When configuring nextEngine = e_FM_PCD_CC, note that
84155 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84156 + from the currently changed table.
84157 +*//***************************************************************************/
84158 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode,
84159 + uint8_t keySize,
84160 + uint8_t *p_Key,
84161 + uint8_t *p_Mask,
84162 + t_FmPcdCcKeyParams *p_KeyParams);
84163 +
84164 +/**************************************************************************//**
84165 + @Function FM_PCD_MatchTableFindNModifyKey
84166 +
84167 + @Description Modify the key in the index defined by the keyIndex. Note that
84168 + this routine will search the node to locate the index of the
84169 + required key (& mask) to modify.
84170 +
84171 + @Param[in] h_CcNode A handle to the node
84172 + @Param[in] keySize Key size of the one to modify.
84173 + @Param[in] p_Key A pointer to the requested key to modify.
84174 + @Param[in] p_Mask A pointer to the mask if relevant,
84175 + otherwise pointer to NULL
84176 + @Param[in] p_NewKey A pointer to the new key
84177 + @Param[in] p_NewMask A pointer to the new mask if relevant,
84178 + otherwise pointer to NULL
84179 +
84180 + @Return E_OK on success; Error code otherwise.
84181 +
84182 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
84183 + node and the nodes that lead to it.
84184 +*//***************************************************************************/
84185 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode,
84186 + uint8_t keySize,
84187 + uint8_t *p_Key,
84188 + uint8_t *p_Mask,
84189 + uint8_t *p_NewKey,
84190 + uint8_t *p_NewMask);
84191 +
84192 +/**************************************************************************//**
84193 + @Function FM_PCD_MatchTableGetKeyCounter
84194 +
84195 + @Description This routine may be used to get a counter of specific key in a CC
84196 + Node; This counter reflects how many frames passed that were matched
84197 + this key.
84198 +
84199 + @Param[in] h_CcNode A handle to the node
84200 + @Param[in] keyIndex Key index for adding
84201 +
84202 + @Return The specific key counter.
84203 +
84204 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84205 +*//***************************************************************************/
84206 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex);
84207 +
84208 +/**************************************************************************//**
84209 + @Function FM_PCD_MatchTableGetKeyStatistics
84210 +
84211 + @Description This routine may be used to get statistics counters of specific key
84212 + in a CC Node.
84213 +
84214 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84215 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84216 + these counters reflect how many frames passed that were matched
84217 + this key; The total frames count will be returned in the counter
84218 + of the first range (as only one frame length range was defined).
84219 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84220 + frame count will be separated to frame length counters, based on
84221 + provided frame length ranges.
84222 +
84223 + @Param[in] h_CcNode A handle to the node
84224 + @Param[in] keyIndex Key index for adding
84225 + @Param[out] p_KeyStatistics Key statistics counters
84226 +
84227 + @Return The specific key statistics.
84228 +
84229 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84230 +*//***************************************************************************/
84231 +t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode,
84232 + uint16_t keyIndex,
84233 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84234 +
84235 +/**************************************************************************//**
84236 + @Function FM_PCD_MatchTableGetMissStatistics
84237 +
84238 + @Description This routine may be used to get statistics counters of miss entry
84239 + in a CC Node.
84240 +
84241 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84242 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84243 + these counters reflect how many frames were not matched to any
84244 + existing key and therefore passed through the miss entry; The
84245 + total frames count will be returned in the counter of the
84246 + first range (as only one frame length range was defined).
84247 +
84248 + @Param[in] h_CcNode A handle to the node
84249 + @Param[out] p_MissStatistics Statistics counters for 'miss'
84250 +
84251 + @Return The statistics for 'miss'.
84252 +
84253 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84254 +*//***************************************************************************/
84255 +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode,
84256 + t_FmPcdCcKeyStatistics *p_MissStatistics);
84257 +
84258 +/**************************************************************************//**
84259 + @Function FM_PCD_MatchTableFindNGetKeyStatistics
84260 +
84261 + @Description This routine may be used to get statistics counters of specific key
84262 + in a CC Node.
84263 +
84264 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84265 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84266 + these counters reflect how many frames passed that were matched
84267 + this key; The total frames count will be returned in the counter
84268 + of the first range (as only one frame length range was defined).
84269 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84270 + frame count will be separated to frame length counters, based on
84271 + provided frame length ranges.
84272 + Note that this routine will search the node to locate the index
84273 + of the required key based on received key parameters.
84274 +
84275 + @Param[in] h_CcNode A handle to the node
84276 + @Param[in] keySize Size of the requested key
84277 + @Param[in] p_Key A pointer to the requested key
84278 + @Param[in] p_Mask A pointer to the mask if relevant,
84279 + otherwise pointer to NULL
84280 + @Param[out] p_KeyStatistics Key statistics counters
84281 +
84282 + @Return The specific key statistics.
84283 +
84284 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84285 +*//***************************************************************************/
84286 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode,
84287 + uint8_t keySize,
84288 + uint8_t *p_Key,
84289 + uint8_t *p_Mask,
84290 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84291 +
84292 +/**************************************************************************//*
84293 + @Function FM_PCD_MatchTableGetNextEngine
84294 +
84295 + @Description Gets NextEngine of the relevant keyIndex.
84296 +
84297 + @Param[in] h_CcNode A handle to the node.
84298 + @Param[in] keyIndex keyIndex in the relevant node.
84299 + @Param[out] p_FmPcdCcNextEngineParams here updated nextEngine parameters for
84300 + the relevant keyIndex of the CC Node
84301 + received as parameter to this function
84302 +
84303 + @Return E_OK on success; Error code otherwise.
84304 +
84305 + @Cautions Allowed only following FM_PCD_Init().
84306 +*//***************************************************************************/
84307 +t_Error FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode,
84308 + uint16_t keyIndex,
84309 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84310 +
84311 +/**************************************************************************//*
84312 + @Function FM_PCD_MatchTableGetIndexedHashBucket
84313 +
84314 + @Description This routine simulates KeyGen operation on the provided key and
84315 + calculates to which hash bucket it will be mapped.
84316 +
84317 + @Param[in] h_CcNode A handle to the node.
84318 + @Param[in] kgKeySize Key size as it was configured in the KG
84319 + scheme that leads to this hash.
84320 + @Param[in] p_KgKey Pointer to the key; must be like the key
84321 + that the KG is generated, i.e. the same
84322 + extraction and with mask if exist.
84323 + @Param[in] kgHashShift Hash-shift as it was configured in the KG
84324 + scheme that leads to this hash.
84325 + @Param[out] p_CcNodeBucketHandle Pointer to the bucket of the provided key.
84326 + @Param[out] p_BucketIndex Index to the bucket of the provided key
84327 + @Param[out] p_LastIndex Pointer to last index in the bucket of the
84328 + provided key.
84329 +
84330 + @Return E_OK on success; Error code otherwise.
84331 +
84332 + @Cautions Allowed only following FM_PCD_HashTableSet()
84333 +*//***************************************************************************/
84334 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
84335 + uint8_t kgKeySize,
84336 + uint8_t *p_KgKey,
84337 + uint8_t kgHashShift,
84338 + t_Handle *p_CcNodeBucketHandle,
84339 + uint8_t *p_BucketIndex,
84340 + uint16_t *p_LastIndex);
84341 +
84342 +/**************************************************************************//**
84343 + @Function FM_PCD_HashTableSet
84344 +
84345 + @Description This routine initializes a hash table structure.
84346 + KeyGen hash result determines the hash bucket.
84347 + Next, KeyGen key is compared against all keys of this
84348 + bucket (exact match).
84349 + Number of sets (number of buckets) of the hash equals to the
84350 + number of 1-s in 'hashResMask' in the provided parameters.
84351 + Number of hash table ways is then calculated by dividing
84352 + 'maxNumOfKeys' equally between the hash sets. This is the maximal
84353 + number of keys that a hash bucket may hold.
84354 + The hash table is initialized empty and keys may be
84355 + added to it following the initialization. Keys masks are not
84356 + supported in current hash table implementation.
84357 + The initialized hash table can be integrated as a node in a
84358 + CC tree.
84359 +
84360 + @Param[in] h_FmPcd FM PCD module descriptor.
84361 + @Param[in] p_Param A structure of parameters defining the hash table
84362 +
84363 + @Return A handle to the initialized object on success; NULL code otherwise.
84364 +
84365 + @Cautions Allowed only following FM_PCD_Init().
84366 +*//***************************************************************************/
84367 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param);
84368 +
84369 +/**************************************************************************//**
84370 + @Function FM_PCD_HashTableDelete
84371 +
84372 + @Description This routine deletes the provided hash table and released all
84373 + its allocated resources.
84374 +
84375 + @Param[in] h_HashTbl A handle to a hash table
84376 +
84377 + @Return E_OK on success; Error code otherwise.
84378 +
84379 + @Cautions Allowed only following FM_PCD_HashTableSet().
84380 +*//***************************************************************************/
84381 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl);
84382 +
84383 +/**************************************************************************//**
84384 + @Function FM_PCD_HashTableAddKey
84385 +
84386 + @Description This routine adds the provided key (including next engine
84387 + parameters of this key) to the hash table.
84388 + The key is added as the last key of the bucket that it is
84389 + mapped to.
84390 +
84391 + @Param[in] h_HashTbl A handle to a hash table
84392 + @Param[in] keySize Key size of added key
84393 + @Param[in] p_KeyParams A pointer to the parameters includes
84394 + new key with next engine parameters; The pointer
84395 + to the key mask must be NULL, as masks are not
84396 + supported in hash table implementation.
84397 +
84398 + @Return E_OK on success; Error code otherwise.
84399 +
84400 + @Cautions Allowed only following FM_PCD_HashTableSet().
84401 +*//***************************************************************************/
84402 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl,
84403 + uint8_t keySize,
84404 + t_FmPcdCcKeyParams *p_KeyParams);
84405 +
84406 +/**************************************************************************//**
84407 + @Function FM_PCD_HashTableRemoveKey
84408 +
84409 + @Description This routine removes the requested key (including next engine
84410 + parameters of this key) from the hash table.
84411 +
84412 + @Param[in] h_HashTbl A handle to a hash table
84413 + @Param[in] keySize Key size of the one to remove.
84414 + @Param[in] p_Key A pointer to the requested key to remove.
84415 +
84416 + @Return E_OK on success; Error code otherwise.
84417 +
84418 + @Cautions Allowed only following FM_PCD_HashTableSet().
84419 +*//***************************************************************************/
84420 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl,
84421 + uint8_t keySize,
84422 + uint8_t *p_Key);
84423 +
84424 +/**************************************************************************//**
84425 + @Function FM_PCD_HashTableModifyNextEngine
84426 +
84427 + @Description This routine modifies the next engine for the provided key. The
84428 + key should be previously added to the hash table.
84429 +
84430 + @Param[in] h_HashTbl A handle to a hash table
84431 + @Param[in] keySize Key size of the key to modify.
84432 + @Param[in] p_Key A pointer to the requested key to modify.
84433 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
84434 + parameters.
84435 +
84436 + @Return E_OK on success; Error code otherwise.
84437 +
84438 + @Cautions Allowed only following FM_PCD_HashTableSet().
84439 + When configuring nextEngine = e_FM_PCD_CC, note that
84440 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84441 + from the currently changed table.
84442 +*//***************************************************************************/
84443 +t_Error FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl,
84444 + uint8_t keySize,
84445 + uint8_t *p_Key,
84446 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84447 +
84448 +/**************************************************************************//**
84449 + @Function FM_PCD_HashTableModifyMissNextEngine
84450 +
84451 + @Description This routine modifies the next engine on key match miss.
84452 +
84453 + @Param[in] h_HashTbl A handle to a hash table
84454 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
84455 + parameters.
84456 +
84457 + @Return E_OK on success; Error code otherwise.
84458 +
84459 + @Cautions Allowed only following FM_PCD_HashTableSet().
84460 + When configuring nextEngine = e_FM_PCD_CC, note that
84461 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84462 + from the currently changed table.
84463 +*//***************************************************************************/
84464 +t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl,
84465 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84466 +
84467 +/**************************************************************************//*
84468 + @Function FM_PCD_HashTableGetMissNextEngine
84469 +
84470 + @Description Gets NextEngine in case of key match miss.
84471 +
84472 + @Param[in] h_HashTbl A handle to a hash table
84473 + @Param[out] p_FmPcdCcNextEngineParams Next engine parameters for the specified
84474 + hash table.
84475 +
84476 + @Return E_OK on success; Error code otherwise.
84477 +
84478 + @Cautions Allowed only following FM_PCD_HashTableSet().
84479 +*//***************************************************************************/
84480 +t_Error FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl,
84481 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84482 +
84483 +/**************************************************************************//**
84484 + @Function FM_PCD_HashTableFindNGetKeyStatistics
84485 +
84486 + @Description This routine may be used to get statistics counters of specific key
84487 + in a hash table.
84488 +
84489 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84490 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84491 + these counters reflect how many frames passed that were matched
84492 + this key; The total frames count will be returned in the counter
84493 + of the first range (as only one frame length range was defined).
84494 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84495 + frame count will be separated to frame length counters, based on
84496 + provided frame length ranges.
84497 + Note that this routine will identify the bucket of this key in
84498 + the hash table and will search the bucket to locate the index
84499 + of the required key based on received key parameters.
84500 +
84501 + @Param[in] h_HashTbl A handle to a hash table
84502 + @Param[in] keySize Size of the requested key
84503 + @Param[in] p_Key A pointer to the requested key
84504 + @Param[out] p_KeyStatistics Key statistics counters
84505 +
84506 + @Return The specific key statistics.
84507 +
84508 + @Cautions Allowed only following FM_PCD_HashTableSet().
84509 +*//***************************************************************************/
84510 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl,
84511 + uint8_t keySize,
84512 + uint8_t *p_Key,
84513 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84514 +
84515 +/**************************************************************************//**
84516 + @Function FM_PCD_HashTableGetMissStatistics
84517 +
84518 + @Description This routine may be used to get statistics counters of 'miss'
84519 + entry of the a hash table.
84520 +
84521 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84522 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84523 + these counters reflect how many frames were not matched to any
84524 + existing key and therefore passed through the miss entry;
84525 +
84526 + @Param[in] h_HashTbl A handle to a hash table
84527 + @Param[out] p_MissStatistics Statistics counters for 'miss'
84528 +
84529 + @Return The statistics for 'miss'.
84530 +
84531 + @Cautions Allowed only following FM_PCD_HashTableSet().
84532 +*//***************************************************************************/
84533 +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl,
84534 + t_FmPcdCcKeyStatistics *p_MissStatistics);
84535 +
84536 +/**************************************************************************//**
84537 + @Function FM_PCD_ManipNodeSet
84538 +
84539 + @Description This routine should be called for defining a manipulation
84540 + node. A manipulation node must be defined before the CC node
84541 + that precedes it.
84542 +
84543 + @Param[in] h_FmPcd FM PCD module descriptor.
84544 + @Param[in] p_FmPcdManipParams A structure of parameters defining the manipulation
84545 +
84546 + @Return A handle to the initialized object on success; NULL code otherwise.
84547 +
84548 + @Cautions Allowed only following FM_PCD_Init().
84549 +*//***************************************************************************/
84550 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams);
84551 +
84552 +/**************************************************************************//**
84553 + @Function FM_PCD_ManipNodeDelete
84554 +
84555 + @Description Delete an existing manipulation node.
84556 +
84557 + @Param[in] h_ManipNode A handle to a manipulation node.
84558 +
84559 + @Return E_OK on success; Error code otherwise.
84560 +
84561 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84562 +*//***************************************************************************/
84563 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode);
84564 +
84565 +/**************************************************************************//**
84566 + @Function FM_PCD_ManipGetStatistics
84567 +
84568 + @Description Retrieve the manipulation statistics.
84569 +
84570 + @Param[in] h_ManipNode A handle to a manipulation node.
84571 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
84572 +
84573 + @Return E_OK on success; Error code otherwise.
84574 +
84575 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84576 +*//***************************************************************************/
84577 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, t_FmPcdManipStats *p_FmPcdManipStats);
84578 +
84579 +/**************************************************************************//**
84580 + @Function FM_PCD_ManipNodeReplace
84581 +
84582 + @Description Change existing manipulation node to be according to new requirement.
84583 +
84584 + @Param[in] h_ManipNode A handle to a manipulation node.
84585 + @Param[out] p_ManipParams A structure of parameters defining the change requirement
84586 +
84587 + @Return E_OK on success; Error code otherwise.
84588 +
84589 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84590 +*//***************************************************************************/
84591 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_ManipNode, t_FmPcdManipParams *p_ManipParams);
84592 +
84593 +#if (DPAA_VERSION >= 11)
84594 +/**************************************************************************//**
84595 + @Function FM_PCD_FrmReplicSetGroup
84596 +
84597 + @Description Initialize a Frame Replicator group.
84598 +
84599 + @Param[in] h_FmPcd FM PCD module descriptor.
84600 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
84601 + the frame replicator group.
84602 +
84603 + @Return A handle to the initialized object on success; NULL code otherwise.
84604 +
84605 + @Cautions Allowed only following FM_PCD_Init().
84606 +*//***************************************************************************/
84607 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, t_FmPcdFrmReplicGroupParams *p_FrmReplicGroupParam);
84608 +
84609 +/**************************************************************************//**
84610 + @Function FM_PCD_FrmReplicDeleteGroup
84611 +
84612 + @Description Delete a Frame Replicator group.
84613 +
84614 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84615 +
84616 + @Return E_OK on success; Error code otherwise.
84617 +
84618 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
84619 +*//***************************************************************************/
84620 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_FrmReplicGroup);
84621 +
84622 +/**************************************************************************//**
84623 + @Function FM_PCD_FrmReplicAddMember
84624 +
84625 + @Description Add the member in the index defined by the memberIndex.
84626 +
84627 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84628 + @Param[in] memberIndex member index for adding.
84629 + @Param[in] p_MemberParams A pointer to the new member parameters.
84630 +
84631 + @Return E_OK on success; Error code otherwise.
84632 +
84633 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84634 +*//***************************************************************************/
84635 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_FrmReplicGroup,
84636 + uint16_t memberIndex,
84637 + t_FmPcdCcNextEngineParams *p_MemberParams);
84638 +
84639 +/**************************************************************************//**
84640 + @Function FM_PCD_FrmReplicRemoveMember
84641 +
84642 + @Description Remove the member defined by the index from the relevant group.
84643 +
84644 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84645 + @Param[in] memberIndex member index for removing.
84646 +
84647 + @Return E_OK on success; Error code otherwise.
84648 +
84649 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84650 +*//***************************************************************************/
84651 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_FrmReplicGroup,
84652 + uint16_t memberIndex);
84653 +#endif /* (DPAA_VERSION >= 11) */
84654 +
84655 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84656 +/**************************************************************************//**
84657 + @Function FM_PCD_StatisticsSetNode
84658 +
84659 + @Description This routine should be called for defining a statistics node.
84660 +
84661 + @Param[in] h_FmPcd FM PCD module descriptor.
84662 + @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics
84663 +
84664 + @Return A handle to the initialized object on success; NULL code otherwise.
84665 +
84666 + @Cautions Allowed only following FM_PCD_Init().
84667 +*//***************************************************************************/
84668 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams);
84669 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84670 +
84671 +/** @} */ /* end of FM_PCD_Runtime_build_grp group */
84672 +/** @} */ /* end of FM_PCD_Runtime_grp group */
84673 +/** @} */ /* end of FM_PCD_grp group */
84674 +/** @} */ /* end of FM_grp group */
84675 +
84676 +
84677 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
84678 +#define FM_PCD_MAX_NUM_OF_INTERCHANGABLE_HDRS FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS
84679 +#define e_FM_PCD_MANIP_ONE_WAYS_HASH e_FM_PCD_MANIP_ONE_WAY_HASH
84680 +#define e_FM_PCD_MANIP_TOW_WAYS_HASH e_FM_PCD_MANIP_TWO_WAYS_HASH
84681 +
84682 +#define e_FM_PCD_MANIP_FRAGMENT_PACKECT e_FM_PCD_MANIP_FRAGMENT_PACKET /* Feb13 */
84683 +
84684 +#define FM_PCD_SetNetEnvCharacteristics(_pcd, _params) \
84685 + FM_PCD_NetEnvCharacteristicsSet(_pcd, _params)
84686 +#define FM_PCD_KgSetScheme(_pcd, _params) FM_PCD_KgSchemeSet(_pcd, _params)
84687 +#define FM_PCD_CcBuildTree(_pcd, _params) FM_PCD_CcRootBuild(_pcd, _params)
84688 +#define FM_PCD_CcSetNode(_pcd, _params) FM_PCD_MatchTableSet(_pcd, _params)
84689 +#define FM_PCD_PlcrSetProfile(_pcd, _params) FM_PCD_PlcrProfileSet(_pcd, _params)
84690 +#define FM_PCD_ManipSetNode(_pcd, _params) FM_PCD_ManipNodeSet(_pcd, _params)
84691 +
84692 +#define FM_PCD_DeleteNetEnvCharacteristics(_pcd, ...) \
84693 + FM_PCD_NetEnvCharacteristicsDelete(__VA_ARGS__)
84694 +#define FM_PCD_KgDeleteScheme(_pcd, ...) \
84695 + FM_PCD_KgSchemeDelete(__VA_ARGS__)
84696 +#define FM_PCD_KgGetSchemeCounter(_pcd, ...) \
84697 + FM_PCD_KgSchemeGetCounter(__VA_ARGS__)
84698 +#define FM_PCD_KgSetSchemeCounter(_pcd, ...) \
84699 + FM_PCD_KgSchemeSetCounter(__VA_ARGS__)
84700 +#define FM_PCD_PlcrDeleteProfile(_pcd, ...) \
84701 + FM_PCD_PlcrProfileDelete(__VA_ARGS__)
84702 +#define FM_PCD_PlcrGetProfileCounter(_pcd, ...) \
84703 + FM_PCD_PlcrProfileGetCounter(__VA_ARGS__)
84704 +#define FM_PCD_PlcrSetProfileCounter(_pcd, ...) \
84705 + FM_PCD_PlcrProfileSetCounter(__VA_ARGS__)
84706 +#define FM_PCD_CcDeleteTree(_pcd, ...) \
84707 + FM_PCD_CcRootDelete(__VA_ARGS__)
84708 +#define FM_PCD_CcTreeModifyNextEngine(_pcd, ...) \
84709 + FM_PCD_CcRootModifyNextEngine(__VA_ARGS__)
84710 +#define FM_PCD_CcDeleteNode(_pcd, ...) \
84711 + FM_PCD_MatchTableDelete(__VA_ARGS__)
84712 +#define FM_PCD_CcNodeModifyMissNextEngine(_pcd, ...) \
84713 + FM_PCD_MatchTableModifyMissNextEngine(__VA_ARGS__)
84714 +#define FM_PCD_CcNodeRemoveKey(_pcd, ...) \
84715 + FM_PCD_MatchTableRemoveKey(__VA_ARGS__)
84716 +#define FM_PCD_CcNodeAddKey(_pcd, ...) \
84717 + FM_PCD_MatchTableAddKey(__VA_ARGS__)
84718 +#define FM_PCD_CcNodeModifyNextEngine(_pcd, ...) \
84719 + FM_PCD_MatchTableModifyNextEngine(__VA_ARGS__)
84720 +#define FM_PCD_CcNodeModifyKeyAndNextEngine(_pcd, ...) \
84721 + FM_PCD_MatchTableModifyKeyAndNextEngine(__VA_ARGS__)
84722 +#define FM_PCD_CcNodeModifyKey(_pcd, ...) \
84723 + FM_PCD_MatchTableModifyKey(__VA_ARGS__)
84724 +#define FM_PCD_CcNodeFindNRemoveKey(_pcd, ...) \
84725 + FM_PCD_MatchTableFindNRemoveKey(__VA_ARGS__)
84726 +#define FM_PCD_CcNodeFindNModifyNextEngine(_pcd, ...) \
84727 + FM_PCD_MatchTableFindNModifyNextEngine(__VA_ARGS__)
84728 +#define FM_PCD_CcNodeFindNModifyKeyAndNextEngine(_pcd, ...) \
84729 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine(__VA_ARGS__)
84730 +#define FM_PCD_CcNodeFindNModifyKey(_pcd, ...) \
84731 + FM_PCD_MatchTableFindNModifyKey(__VA_ARGS__)
84732 +#define FM_PCD_CcIndexedHashNodeGetBucket(_pcd, ...) \
84733 + FM_PCD_MatchTableGetIndexedHashBucket(__VA_ARGS__)
84734 +#define FM_PCD_CcNodeGetNextEngine(_pcd, ...) \
84735 + FM_PCD_MatchTableGetNextEngine(__VA_ARGS__)
84736 +#define FM_PCD_CcNodeGetKeyCounter(_pcd, ...) \
84737 + FM_PCD_MatchTableGetKeyCounter(__VA_ARGS__)
84738 +#define FM_PCD_ManipDeleteNode(_pcd, ...) \
84739 + FM_PCD_ManipNodeDelete(__VA_ARGS__)
84740 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
84741 +
84742 +
84743 +#endif /* __FM_PCD_EXT */
84744 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
84745 new file mode 100644
84746 index 00000000..08a5aa59
84747 --- /dev/null
84748 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
84749 @@ -0,0 +1,2608 @@
84750 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
84751 + * All rights reserved.
84752 + *
84753 + * Redistribution and use in source and binary forms, with or without
84754 + * modification, are permitted provided that the following conditions are met:
84755 + * * Redistributions of source code must retain the above copyright
84756 + * notice, this list of conditions and the following disclaimer.
84757 + * * Redistributions in binary form must reproduce the above copyright
84758 + * notice, this list of conditions and the following disclaimer in the
84759 + * documentation and/or other materials provided with the distribution.
84760 + * * Neither the name of Freescale Semiconductor nor the
84761 + * names of its contributors may be used to endorse or promote products
84762 + * derived from this software without specific prior written permission.
84763 + *
84764 + *
84765 + * ALTERNATIVELY, this software may be distributed under the terms of the
84766 + * GNU General Public License ("GPL") as published by the Free Software
84767 + * Foundation, either version 2 of that License or (at your option) any
84768 + * later version.
84769 + *
84770 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
84771 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
84772 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
84773 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
84774 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
84775 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
84776 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
84777 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
84778 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
84779 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84780 + */
84781 +
84782 +
84783 +/**************************************************************************//**
84784 + @File fm_port_ext.h
84785 +
84786 + @Description FM-Port Application Programming Interface.
84787 +*//***************************************************************************/
84788 +#ifndef __FM_PORT_EXT
84789 +#define __FM_PORT_EXT
84790 +
84791 +#include "error_ext.h"
84792 +#include "std_ext.h"
84793 +#include "fm_pcd_ext.h"
84794 +#include "fm_ext.h"
84795 +#include "net_ext.h"
84796 +
84797 +
84798 +/**************************************************************************//**
84799 +
84800 + @Group FM_grp Frame Manager API
84801 +
84802 + @Description FM API functions, definitions and enums
84803 +
84804 + @{
84805 +*//***************************************************************************/
84806 +
84807 +/**************************************************************************//**
84808 + @Group FM_PORT_grp FM Port
84809 +
84810 + @Description FM Port API
84811 +
84812 + The FM uses a general module called "port" to represent a Tx port
84813 + (MAC), an Rx port (MAC) or Offline Parsing port.
84814 + The number of ports in an FM varies between SOCs.
84815 + The SW driver manages these ports as sub-modules of the FM, i.e.
84816 + after an FM is initialized, its ports may be initialized and
84817 + operated upon.
84818 +
84819 + The port is initialized aware of its type, but other functions on
84820 + a port may be indifferent to its type. When necessary, the driver
84821 + verifies coherence and returns error if applicable.
84822 +
84823 + On initialization, user specifies the port type and it's index
84824 + (relative to the port's type) - always starting at 0.
84825 +
84826 + @{
84827 +*//***************************************************************************/
84828 +
84829 +/**************************************************************************//**
84830 + @Description An enum for defining port PCD modes.
84831 + This enum defines the superset of PCD engines support - i.e. not
84832 + all engines have to be used, but all have to be enabled. The real
84833 + flow of a specific frame depends on the PCD configuration and the
84834 + frame headers and payload.
84835 + Note: the first engine and the first engine after the parser (if
84836 + exists) should be in order, the order is important as it will
84837 + define the flow of the port. However, as for the rest engines
84838 + (the ones that follows), the order is not important anymore as
84839 + it is defined by the PCD graph itself.
84840 +*//***************************************************************************/
84841 +typedef enum e_FmPortPcdSupport {
84842 + e_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
84843 + , e_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
84844 + , e_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
84845 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
84846 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
84847 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
84848 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
84849 + /**< Use all PCD engines */
84850 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
84851 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
84852 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
84853 + , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
84854 +#ifdef FM_CAPWAP_SUPPORT
84855 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
84856 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
84857 +#endif /* FM_CAPWAP_SUPPORT */
84858 +} e_FmPortPcdSupport;
84859 +
84860 +/**************************************************************************//**
84861 + @Description Port interrupts
84862 +*//***************************************************************************/
84863 +typedef enum e_FmPortExceptions {
84864 + e_FM_PORT_EXCEPTION_IM_BUSY /**< Independent-Mode Rx-BUSY */
84865 +} e_FmPortExceptions;
84866 +
84867 +
84868 +/**************************************************************************//**
84869 + @Collection General FM Port defines
84870 +*//***************************************************************************/
84871 +#define FM_PORT_PRS_RESULT_NUM_OF_WORDS 8 /**< Number of 4 bytes words in parser result */
84872 +/* @} */
84873 +
84874 +/**************************************************************************//**
84875 + @Collection FM Frame error
84876 +*//***************************************************************************/
84877 +typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */
84878 +
84879 +#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT FM_FD_ERR_UNSUPPORTED_FORMAT /**< Not for Rx-Port! Unsupported Format */
84880 +#define FM_PORT_FRM_ERR_LENGTH FM_FD_ERR_LENGTH /**< Not for Rx-Port! Length Error */
84881 +#define FM_PORT_FRM_ERR_DMA FM_FD_ERR_DMA /**< DMA Data error */
84882 +#define FM_PORT_FRM_ERR_NON_FM FM_FD_RX_STATUS_ERR_NON_FM /**< non Frame-Manager error; probably come from SEC that
84883 + was chained to FM */
84884 +
84885 +#define FM_PORT_FRM_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) /**< IPR error */
84886 +#define FM_PORT_FRM_ERR_IPR_NCSP (FM_FD_ERR_IPR_NCSP & ~FM_FD_IPR) /**< IPR non-consistent-sp */
84887 +
84888 +#define FM_PORT_FRM_ERR_IPFE 0 /**< Obsolete; will be removed in the future */
84889 +
84890 +#ifdef FM_CAPWAP_SUPPORT
84891 +#define FM_PORT_FRM_ERR_CRE FM_FD_ERR_CRE
84892 +#define FM_PORT_FRM_ERR_CHE FM_FD_ERR_CHE
84893 +#endif /* FM_CAPWAP_SUPPORT */
84894 +
84895 +#define FM_PORT_FRM_ERR_PHYSICAL FM_FD_ERR_PHYSICAL /**< Rx FIFO overflow, FCS error, code error, running disparity
84896 + error (SGMII and TBI modes), FIFO parity error. PHY
84897 + Sequence error, PHY error control character detected. */
84898 +#define FM_PORT_FRM_ERR_SIZE FM_FD_ERR_SIZE /**< Frame too long OR Frame size exceeds max_length_frame */
84899 +#define FM_PORT_FRM_ERR_CLS_DISCARD FM_FD_ERR_CLS_DISCARD /**< indicates a classifier "drop" operation */
84900 +#define FM_PORT_FRM_ERR_EXTRACTION FM_FD_ERR_EXTRACTION /**< Extract Out of Frame */
84901 +#define FM_PORT_FRM_ERR_NO_SCHEME FM_FD_ERR_NO_SCHEME /**< No Scheme Selected */
84902 +#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW FM_FD_ERR_KEYSIZE_OVERFLOW /**< Keysize Overflow */
84903 +#define FM_PORT_FRM_ERR_COLOR_RED FM_FD_ERR_COLOR_RED /**< Frame color is red */
84904 +#define FM_PORT_FRM_ERR_COLOR_YELLOW FM_FD_ERR_COLOR_YELLOW /**< Frame color is yellow */
84905 +#define FM_PORT_FRM_ERR_ILL_PLCR FM_FD_ERR_ILL_PLCR /**< Illegal Policer Profile selected */
84906 +#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN FM_FD_ERR_PLCR_FRAME_LEN /**< Policer frame length error */
84907 +#define FM_PORT_FRM_ERR_PRS_TIMEOUT FM_FD_ERR_PRS_TIMEOUT /**< Parser Time out Exceed */
84908 +#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT FM_FD_ERR_PRS_ILL_INSTRUCT /**< Invalid Soft Parser instruction */
84909 +#define FM_PORT_FRM_ERR_PRS_HDR_ERR FM_FD_ERR_PRS_HDR_ERR /**< Header error was identified during parsing */
84910 +#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED FM_FD_ERR_BLOCK_LIMIT_EXCEEDED /**< Frame parsed beyind 256 first bytes */
84911 +#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */
84912 +/* @} */
84913 +
84914 +
84915 +
84916 +/**************************************************************************//**
84917 + @Group FM_PORT_init_grp FM Port Initialization Unit
84918 +
84919 + @Description FM Port Initialization Unit
84920 +
84921 + @{
84922 +*//***************************************************************************/
84923 +
84924 +/**************************************************************************//**
84925 + @Description Exceptions user callback routine, will be called upon an
84926 + exception passing the exception identification.
84927 +
84928 + @Param[in] h_App - User's application descriptor.
84929 + @Param[in] exception - The exception.
84930 + *//***************************************************************************/
84931 +typedef void (t_FmPortExceptionCallback) (t_Handle h_App, e_FmPortExceptions exception);
84932 +
84933 +/**************************************************************************//**
84934 + @Description User callback function called by driver with received data.
84935 +
84936 + User provides this function. Driver invokes it.
84937 +
84938 + @Param[in] h_App Application's handle originally specified to
84939 + the API Config function
84940 + @Param[in] p_Data A pointer to data received
84941 + @Param[in] length length of received data
84942 + @Param[in] status receive status and errors
84943 + @Param[in] position position of buffer in frame
84944 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84945 +
84946 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
84947 + operation for all ready data.
84948 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
84949 +*//***************************************************************************/
84950 +typedef e_RxStoreResponse (t_FmPortImRxStoreCallback) (t_Handle h_App,
84951 + uint8_t *p_Data,
84952 + uint16_t length,
84953 + uint16_t status,
84954 + uint8_t position,
84955 + t_Handle h_BufContext);
84956 +
84957 +/**************************************************************************//**
84958 + @Description User callback function called by driver when transmit completed.
84959 +
84960 + User provides this function. Driver invokes it.
84961 +
84962 + @Param[in] h_App Application's handle originally specified to
84963 + the API Config function
84964 + @Param[in] p_Data A pointer to data received
84965 + @Param[in] status transmit status and errors
84966 + @Param[in] lastBuffer is last buffer in frame
84967 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84968 + *//***************************************************************************/
84969 +typedef void (t_FmPortImTxConfCallback) (t_Handle h_App,
84970 + uint8_t *p_Data,
84971 + uint16_t status,
84972 + t_Handle h_BufContext);
84973 +
84974 +/**************************************************************************//**
84975 + @Description A structure for additional Rx port parameters
84976 +*//***************************************************************************/
84977 +typedef struct t_FmPortRxParams {
84978 + uint32_t errFqid; /**< Error Queue Id. */
84979 + uint32_t dfltFqid; /**< Default Queue Id. */
84980 + uint16_t liodnOffset; /**< Port's LIODN offset. */
84981 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
84982 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */
84983 +} t_FmPortRxParams;
84984 +
84985 +/**************************************************************************//**
84986 + @Description A structure for additional non-Rx port parameters
84987 +*//***************************************************************************/
84988 +typedef struct t_FmPortNonRxParams {
84989 + uint32_t errFqid; /**< Error Queue Id. */
84990 + uint32_t dfltFqid; /**< For Tx - Default Confirmation queue,
84991 + 0 means no Tx confirmation for processed
84992 + frames. For OP port - default Rx queue. */
84993 + uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used
84994 + by the FM for dequeue. */
84995 +} t_FmPortNonRxParams;
84996 +
84997 +/**************************************************************************//**
84998 + @Description A structure for additional Rx port parameters
84999 +*//***************************************************************************/
85000 +typedef struct t_FmPortImRxTxParams {
85001 + t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */
85002 + uint16_t liodnOffset; /**< For Rx ports only. Port's LIODN Offset. */
85003 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
85004 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
85005 + t_BufferPoolInfo rxPoolParams; /**< For Rx ports only. */
85006 + t_FmPortImRxStoreCallback *f_RxStore; /**< For Rx ports only. */
85007 + t_FmPortImTxConfCallback *f_TxConf; /**< For Tx ports only. */
85008 +} t_FmPortImRxTxParams;
85009 +
85010 +/**************************************************************************//**
85011 + @Description A union for additional parameters depending on port type
85012 +*//***************************************************************************/
85013 +typedef union u_FmPortSpecificParams {
85014 + t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */
85015 + t_FmPortRxParams rxParams; /**< Rx port parameters structure */
85016 + t_FmPortNonRxParams nonRxParams; /**< Non-Rx port parameters structure */
85017 +} u_FmPortSpecificParams;
85018 +
85019 +/**************************************************************************//**
85020 + @Description A structure representing FM initialization parameters
85021 +*//***************************************************************************/
85022 +typedef struct t_FmPortParams {
85023 + uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/
85024 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
85025 + e_FmPortType portType; /**< Port type */
85026 + uint8_t portId; /**< Port Id - relative to type;
85027 + NOTE: When configuring Offline Parsing port for
85028 + FMANv3 devices (DPAA_VERSION 11 and higher),
85029 + it is highly recommended NOT to use portId=0 due to lack
85030 + of HW resources on portId=0. */
85031 + bool independentModeEnable;
85032 + /**< This port is Independent-Mode - Used for Rx/Tx ports only! */
85033 + uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be
85034 + used together with LIODN offset. */
85035 + u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port
85036 + type. */
85037 +
85038 + t_FmPortExceptionCallback *f_Exception; /**< Relevant for IM only Callback routine to be called on BUSY exception */
85039 + t_Handle h_App; /**< A handle to an application layer object; This handle will
85040 + be passed by the driver upon calling the above callbacks */
85041 +} t_FmPortParams;
85042 +
85043 +
85044 +/**************************************************************************//**
85045 + @Function FM_PORT_Config
85046 +
85047 + @Description Creates a descriptor for the FM PORT module.
85048 +
85049 + The routine returns a handle (descriptor) to the FM PORT object.
85050 + This descriptor must be passed as first parameter to all other
85051 + FM PORT function calls.
85052 +
85053 + No actual initialization or configuration of FM hardware is
85054 + done by this routine.
85055 +
85056 + @Param[in] p_FmPortParams - Pointer to data structure of parameters
85057 +
85058 + @Retval Handle to FM object, or NULL for Failure.
85059 +*//***************************************************************************/
85060 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams);
85061 +
85062 +/**************************************************************************//**
85063 + @Function FM_PORT_Init
85064 +
85065 + @Description Initializes the FM PORT module by defining the software structure
85066 + and configuring the hardware registers.
85067 +
85068 + @Param[in] h_FmPort - FM PORT module descriptor
85069 +
85070 + @Return E_OK on success; Error code otherwise.
85071 +*//***************************************************************************/
85072 +t_Error FM_PORT_Init(t_Handle h_FmPort);
85073 +
85074 +/**************************************************************************//**
85075 + @Function FM_PORT_Free
85076 +
85077 + @Description Frees all resources that were assigned to FM PORT module.
85078 +
85079 + Calling this routine invalidates the descriptor.
85080 +
85081 + @Param[in] h_FmPort - FM PORT module descriptor
85082 +
85083 + @Return E_OK on success; Error code otherwise.
85084 +*//***************************************************************************/
85085 +t_Error FM_PORT_Free(t_Handle h_FmPort);
85086 +
85087 +
85088 +/**************************************************************************//**
85089 + @Group FM_PORT_advanced_init_grp FM Port Advanced Configuration Unit
85090 +
85091 + @Description Configuration functions used to change default values.
85092 +
85093 + @{
85094 +*//***************************************************************************/
85095 +
85096 +/**************************************************************************//**
85097 + @Description enum for defining QM frame dequeue
85098 +*//***************************************************************************/
85099 +typedef enum e_FmPortDeqType {
85100 + e_FM_PORT_DEQ_TYPE1, /**< Dequeue from the SP channel - with priority precedence,
85101 + and Intra-Class Scheduling respected. */
85102 + e_FM_PORT_DEQ_TYPE2, /**< Dequeue from the SP channel - with active FQ precedence,
85103 + and Intra-Class Scheduling respected. */
85104 + e_FM_PORT_DEQ_TYPE3 /**< Dequeue from the SP channel - with active FQ precedence,
85105 + and override Intra-Class Scheduling */
85106 +} e_FmPortDeqType;
85107 +
85108 +/**************************************************************************//**
85109 + @Description enum for defining QM frame dequeue
85110 +*//***************************************************************************/
85111 +typedef enum e_FmPortDeqPrefetchOption {
85112 + e_FM_PORT_DEQ_NO_PREFETCH, /**< QMI preforms a dequeue action for a single frame
85113 + only when a dedicated portID Tnum is waiting. */
85114 + e_FM_PORT_DEQ_PARTIAL_PREFETCH, /**< QMI preforms a dequeue action for 3 frames when
85115 + one dedicated portId tnum is waiting. */
85116 + e_FM_PORT_DEQ_FULL_PREFETCH /**< QMI preforms a dequeue action for 3 frames when
85117 + no dedicated portId tnums are waiting. */
85118 +
85119 +} e_FmPortDeqPrefetchOption;
85120 +
85121 +/**************************************************************************//**
85122 + @Description enum for defining port default color
85123 +*//***************************************************************************/
85124 +typedef enum e_FmPortColor {
85125 + e_FM_PORT_COLOR_GREEN, /**< Default port color is green */
85126 + e_FM_PORT_COLOR_YELLOW, /**< Default port color is yellow */
85127 + e_FM_PORT_COLOR_RED, /**< Default port color is red */
85128 + e_FM_PORT_COLOR_OVERRIDE /**< Ignore color */
85129 +} e_FmPortColor;
85130 +
85131 +/**************************************************************************//**
85132 + @Description A structure for defining Dual Tx rate limiting scale
85133 +*//***************************************************************************/
85134 +typedef enum e_FmPortDualRateLimiterScaleDown {
85135 + e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
85136 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
85137 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
85138 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
85139 +} e_FmPortDualRateLimiterScaleDown;
85140 +
85141 +
85142 +/**************************************************************************//**
85143 + @Description A structure for defining FM port resources
85144 +*//***************************************************************************/
85145 +typedef struct t_FmPortRsrc {
85146 + uint32_t num; /**< Committed required resource */
85147 + uint32_t extra; /**< Extra (not committed) required resource */
85148 +} t_FmPortRsrc;
85149 +
85150 +/**************************************************************************//**
85151 + @Description A structure for defining observed pool depletion
85152 +*//***************************************************************************/
85153 +typedef struct t_FmPortObservedBufPoolDepletion {
85154 + t_FmBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */
85155 + t_FmExtPools poolsParams; /**< Which external buffer pools are observed
85156 + (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS),
85157 + and their sizes. */
85158 +} t_FmPortObservedBufPoolDepletion;
85159 +
85160 +/**************************************************************************//**
85161 + @Description A structure for defining Tx rate limiting
85162 +*//***************************************************************************/
85163 +typedef struct t_FmPortRateLimit {
85164 + uint16_t maxBurstSize; /**< in KBytes for Tx ports, in frames
85165 + for OP ports. (note that
85166 + for early chips burst size is
85167 + rounded up to a multiply of 1000 frames).*/
85168 + uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for
85169 + OP ports. Rate limit refers to
85170 + data rate (rather than line rate). */
85171 + e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For OP ports only. Not-valid
85172 + for some earlier chip revisions */
85173 +} t_FmPortRateLimit;
85174 +
85175 +/**************************************************************************//**
85176 + @Description A structure for defining the parameters of
85177 + the Rx port performance counters
85178 +*//***************************************************************************/
85179 +typedef struct t_FmPortPerformanceCnt {
85180 + uint8_t taskCompVal; /**< Task compare value */
85181 + uint8_t queueCompVal; /**< Rx queue/Tx confirm queue compare
85182 + value (unused for H/O) */
85183 + uint8_t dmaCompVal; /**< Dma compare value */
85184 + uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */
85185 +} t_FmPortPerformanceCnt;
85186 +
85187 +
85188 +/**************************************************************************//**
85189 + @Description A structure for defining the sizes of the Deep Sleep
85190 + the Auto Response tables
85191 +*//***************************************************************************/
85192 +typedef struct t_FmPortDsarTablesSizes
85193 +{
85194 + uint16_t maxNumOfArpEntries;
85195 + uint16_t maxNumOfEchoIpv4Entries;
85196 + uint16_t maxNumOfNdpEntries;
85197 + uint16_t maxNumOfEchoIpv6Entries;
85198 + uint16_t maxNumOfSnmpIPV4Entries;
85199 + uint16_t maxNumOfSnmpIPV6Entries;
85200 + uint16_t maxNumOfSnmpOidEntries;
85201 + uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */
85202 +
85203 + uint16_t maxNumOfIpProtFiltering;
85204 + uint16_t maxNumOfTcpPortFiltering;
85205 + uint16_t maxNumOfUdpPortFiltering;
85206 +} t_FmPortDsarTablesSizes;
85207 +
85208 +
85209 +/**************************************************************************//**
85210 + @Function FM_PORT_ConfigDsarSupport
85211 +
85212 + @Description This function will allocate the amount of MURAM needed for
85213 + this max number of entries for Deep Sleep Auto Response.
85214 + it will calculate all needed MURAM for autoresponse including
85215 + necesary common stuff.
85216 +
85217 +
85218 + @Param[in] h_FmPort A handle to a FM Port module.
85219 + @Param[in] params A pointer to a structure containing the maximum
85220 + sizes of the auto response tables
85221 +
85222 + @Return E_OK on success; Error code otherwise.
85223 +
85224 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85225 +*//***************************************************************************/
85226 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params);
85227 +
85228 +/**************************************************************************//**
85229 + @Function FM_PORT_ConfigNumOfOpenDmas
85230 +
85231 + @Description Calling this routine changes the max number of open DMA's
85232 + available for this port. It changes this parameter in the
85233 + internal driver data base from its default configuration
85234 + [OP: 1]
85235 + [1G-RX, 1G-TX: 1 (+1)]
85236 + [10G-RX, 10G-TX: 8 (+8)]
85237 +
85238 + @Param[in] h_FmPort A handle to a FM Port module.
85239 + @Param[in] p_OpenDmas A pointer to a structure of parameters defining
85240 + the open DMA allocation.
85241 +
85242 + @Return E_OK on success; Error code otherwise.
85243 +
85244 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85245 +*//***************************************************************************/
85246 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas);
85247 +
85248 +/**************************************************************************//**
85249 + @Function FM_PORT_ConfigNumOfTasks
85250 +
85251 + @Description Calling this routine changes the max number of tasks
85252 + available for this port. It changes this parameter in the
85253 + internal driver data base from its default configuration
85254 + [OP: 1]
85255 + [1G-RX, 1G-TX: 3 (+2)]
85256 + [10G-RX, 10G-TX: 16 (+8)]
85257 +
85258 + @Param[in] h_FmPort A handle to a FM Port module.
85259 + @Param[in] p_NumOfTasks A pointer to a structure of parameters defining
85260 + the tasks allocation.
85261 +
85262 + @Return E_OK on success; Error code otherwise.
85263 +
85264 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85265 +*//***************************************************************************/
85266 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
85267 +
85268 +/**************************************************************************//**
85269 + @Function FM_PORT_ConfigSizeOfFifo
85270 +
85271 + @Description Calling this routine changes the max FIFO size configured for this port.
85272 +
85273 + This function changes the internal driver data base from its
85274 + default configuration. Please refer to the driver's User Guide for
85275 + information on default FIFO sizes in the various devices.
85276 + [OP: 2KB]
85277 + [1G-RX, 1G-TX: 11KB]
85278 + [10G-RX, 10G-TX: 12KB]
85279 +
85280 + @Param[in] h_FmPort A handle to a FM Port module.
85281 + @Param[in] p_SizeOfFifo A pointer to a structure of parameters defining
85282 + the FIFO allocation.
85283 +
85284 + @Return E_OK on success; Error code otherwise.
85285 +
85286 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85287 +*//***************************************************************************/
85288 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
85289 +
85290 +/**************************************************************************//**
85291 + @Function FM_PORT_ConfigDeqHighPriority
85292 +
85293 + @Description Calling this routine changes the dequeue priority in the
85294 + internal driver data base from its default configuration
85295 + 1G: [DEFAULT_PORT_deqHighPriority_1G]
85296 + 10G: [DEFAULT_PORT_deqHighPriority_10G]
85297 +
85298 + May be used for Non-Rx ports only
85299 +
85300 + @Param[in] h_FmPort A handle to a FM Port module.
85301 + @Param[in] highPri TRUE to select high priority, FALSE for normal operation.
85302 +
85303 + @Return E_OK on success; Error code otherwise.
85304 +
85305 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85306 +*//***************************************************************************/
85307 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri);
85308 +
85309 +/**************************************************************************//**
85310 + @Function FM_PORT_ConfigDeqType
85311 +
85312 + @Description Calling this routine changes the dequeue type parameter in the
85313 + internal driver data base from its default configuration
85314 + [DEFAULT_PORT_deqType].
85315 +
85316 + May be used for Non-Rx ports only
85317 +
85318 + @Param[in] h_FmPort A handle to a FM Port module.
85319 + @Param[in] deqType According to QM definition.
85320 +
85321 + @Return E_OK on success; Error code otherwise.
85322 +
85323 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85324 +*//***************************************************************************/
85325 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType);
85326 +
85327 +/**************************************************************************//**
85328 + @Function FM_PORT_ConfigDeqPrefetchOption
85329 +
85330 + @Description Calling this routine changes the dequeue prefetch option parameter in the
85331 + internal driver data base from its default configuration
85332 + [DEFAULT_PORT_deqPrefetchOption]
85333 + Note: Available for some chips only
85334 +
85335 + May be used for Non-Rx ports only
85336 +
85337 + @Param[in] h_FmPort A handle to a FM Port module.
85338 + @Param[in] deqPrefetchOption New option
85339 +
85340 + @Return E_OK on success; Error code otherwise.
85341 +
85342 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85343 +*//***************************************************************************/
85344 +t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption);
85345 +
85346 +/**************************************************************************//**
85347 + @Function FM_PORT_ConfigDeqByteCnt
85348 +
85349 + @Description Calling this routine changes the dequeue byte count parameter in
85350 + the internal driver data base from its default configuration
85351 + 1G:[DEFAULT_PORT_deqByteCnt_1G].
85352 + 10G:[DEFAULT_PORT_deqByteCnt_10G].
85353 +
85354 + May be used for Non-Rx ports only
85355 +
85356 + @Param[in] h_FmPort A handle to a FM Port module.
85357 + @Param[in] deqByteCnt New byte count
85358 +
85359 + @Return E_OK on success; Error code otherwise.
85360 +
85361 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85362 +*//***************************************************************************/
85363 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt);
85364 +
85365 +/**************************************************************************//**
85366 + @Function FM_PORT_ConfigBufferPrefixContent
85367 +
85368 + @Description Defines the structure, size and content of the application buffer.
85369 + The prefix will
85370 + In Tx ports, if 'passPrsResult', the application
85371 + should set a value to their offsets in the prefix of
85372 + the FM will save the first 'privDataSize', than,
85373 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
85374 + and timeStamp, and the packet itself (in this order), to the
85375 + application buffer, and to offset.
85376 + Calling this routine changes the buffer margins definitions
85377 + in the internal driver data base from its default
85378 + configuration: Data size: [DEFAULT_PORT_bufferPrefixContent_privDataSize]
85379 + Pass Parser result: [DEFAULT_PORT_bufferPrefixContent_passPrsResult].
85380 + Pass timestamp: [DEFAULT_PORT_bufferPrefixContent_passTimeStamp].
85381 +
85382 + May be used for all ports
85383 +
85384 + @Param[in] h_FmPort A handle to a FM Port module.
85385 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
85386 + structure of the buffer.
85387 + Out parameter: Start margin - offset
85388 + of data from start of external buffer.
85389 +
85390 + @Return E_OK on success; Error code otherwise.
85391 +
85392 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85393 +*//***************************************************************************/
85394 +t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort,
85395 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
85396 +
85397 +/**************************************************************************//**
85398 + @Function FM_PORT_ConfigCheksumLastBytesIgnore
85399 +
85400 + @Description Calling this routine changes the number of checksum bytes to ignore
85401 + parameter in the internal driver data base from its default configuration
85402 + [DEFAULT_PORT_cheksumLastBytesIgnore]
85403 +
85404 + May be used by Tx & Rx ports only
85405 +
85406 + @Param[in] h_FmPort A handle to a FM Port module.
85407 + @Param[in] cheksumLastBytesIgnore New value
85408 +
85409 + @Return E_OK on success; Error code otherwise.
85410 +
85411 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85412 +*//***************************************************************************/
85413 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore);
85414 +
85415 +/**************************************************************************//**
85416 + @Function FM_PORT_ConfigCutBytesFromEnd
85417 +
85418 + @Description Calling this routine changes the number of bytes to cut from a
85419 + frame's end parameter in the internal driver data base
85420 + from its default configuration [DEFAULT_PORT_cutBytesFromEnd]
85421 + Note that if the result of (frame length before chop - cutBytesFromEnd) is
85422 + less than 14 bytes, the chop operation is not executed.
85423 +
85424 + May be used for Rx ports only
85425 +
85426 + @Param[in] h_FmPort A handle to a FM Port module.
85427 + @Param[in] cutBytesFromEnd New value
85428 +
85429 + @Return E_OK on success; Error code otherwise.
85430 +
85431 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85432 +*//***************************************************************************/
85433 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd);
85434 +
85435 +/**************************************************************************//**
85436 + @Function FM_PORT_ConfigPoolDepletion
85437 +
85438 + @Description Calling this routine enables pause frame generation depending on the
85439 + depletion status of BM pools. It also defines the conditions to activate
85440 + this functionality. By default, this functionality is disabled.
85441 +
85442 + May be used for Rx ports only
85443 +
85444 + @Param[in] h_FmPort A handle to a FM Port module.
85445 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
85446 +
85447 + @Return E_OK on success; Error code otherwise.
85448 +
85449 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85450 +*//***************************************************************************/
85451 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmBufPoolDepletion *p_BufPoolDepletion);
85452 +
85453 +/**************************************************************************//**
85454 + @Function FM_PORT_ConfigObservedPoolDepletion
85455 +
85456 + @Description Calling this routine enables a mechanism to stop port enqueue
85457 + depending on the depletion status of selected BM pools.
85458 + It also defines the conditions to activate
85459 + this functionality. By default, this functionality is disabled.
85460 +
85461 + Note: Available for some chips only
85462 +
85463 + May be used for OP ports only
85464 +
85465 + @Param[in] h_FmPort A handle to a FM Port module.
85466 + @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion.
85467 +
85468 + @Return E_OK on success; Error code otherwise.
85469 +
85470 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85471 +*//***************************************************************************/
85472 +t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort,
85473 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion);
85474 +
85475 +/**************************************************************************//**
85476 + @Function FM_PORT_ConfigExtBufPools
85477 +
85478 + @Description This routine should be called for OP ports
85479 + that internally use BM buffer pools. In such cases, e.g. for fragmentation and
85480 + re-assembly, the FM needs new BM buffers. By calling this routine the user
85481 + specifies the BM buffer pools that should be used.
85482 +
85483 + Note: Available for some chips only
85484 +
85485 + May be used for OP ports only
85486 +
85487 + @Param[in] h_FmPort A handle to a FM Port module.
85488 + @Param[in] p_FmExtPools A structure of parameters for the external pools.
85489 +
85490 + @Return E_OK on success; Error code otherwise.
85491 +
85492 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85493 +*//***************************************************************************/
85494 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools);
85495 +
85496 +/**************************************************************************//**
85497 + @Function FM_PORT_ConfigBackupPools
85498 +
85499 + @Description Calling this routine allows the configuration of some of the BM pools
85500 + defined for this port as backup pools.
85501 + A pool configured to be a backup pool will be used only if all other
85502 + enabled non-backup pools are depleted.
85503 +
85504 + May be used for Rx ports only
85505 +
85506 + @Param[in] h_FmPort A handle to a FM Port module.
85507 + @Param[in] p_FmPortBackupBmPools An array of pool id's. All pools specified here will
85508 + be defined as backup pools.
85509 +
85510 + @Return E_OK on success; Error code otherwise.
85511 +
85512 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85513 +*//***************************************************************************/
85514 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmBackupBmPools *p_FmPortBackupBmPools);
85515 +
85516 +/**************************************************************************//**
85517 + @Function FM_PORT_ConfigFrmDiscardOverride
85518 +
85519 + @Description Calling this routine changes the error frames destination parameter
85520 + in the internal driver data base from its default configuration:
85521 + override = [DEFAULT_PORT_frmDiscardOverride]
85522 +
85523 + May be used for Rx and OP ports only
85524 +
85525 + @Param[in] h_FmPort A handle to a FM Port module.
85526 + @Param[in] override TRUE to override discarding of error frames and
85527 + enqueueing them to error queue.
85528 +
85529 + @Return E_OK on success; Error code otherwise.
85530 +
85531 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85532 +*//***************************************************************************/
85533 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override);
85534 +
85535 +/**************************************************************************//**
85536 + @Function FM_PORT_ConfigErrorsToDiscard
85537 +
85538 + @Description Calling this routine changes the behaviour on error parameter
85539 + in the internal driver data base from its default configuration:
85540 + [DEFAULT_PORT_errorsToDiscard].
85541 + If a requested error was previously defined as "ErrorsToEnqueue" it's
85542 + definition will change and the frame will be discarded.
85543 + Errors that were not defined either as "ErrorsToEnqueue" nor as
85544 + "ErrorsToDiscard", will be forwarded to CPU.
85545 +
85546 + May be used for Rx and OP ports only
85547 +
85548 + @Param[in] h_FmPort A handle to a FM Port module.
85549 + @Param[in] errs A list of errors to discard
85550 +
85551 + @Return E_OK on success; Error code otherwise.
85552 +
85553 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85554 +*//***************************************************************************/
85555 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
85556 +
85557 +/**************************************************************************//**
85558 + @Function FM_PORT_ConfigDmaSwapData
85559 +
85560 + @Description Calling this routine changes the DMA swap data aparameter
85561 + in the internal driver data base from its default
85562 + configuration [DEFAULT_PORT_dmaSwapData]
85563 +
85564 + May be used for all port types
85565 +
85566 + @Param[in] h_FmPort A handle to a FM Port module.
85567 + @Param[in] swapData New selection
85568 +
85569 + @Return E_OK on success; Error code otherwise.
85570 +
85571 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85572 +*//***************************************************************************/
85573 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData);
85574 +
85575 +/**************************************************************************//**
85576 + @Function FM_PORT_ConfigDmaIcCacheAttr
85577 +
85578 + @Description Calling this routine changes the internal context cache
85579 + attribute parameter in the internal driver data base
85580 + from its default configuration [DEFAULT_PORT_dmaIntContextCacheAttr]
85581 +
85582 + May be used for all port types
85583 +
85584 + @Param[in] h_FmPort A handle to a FM Port module.
85585 + @Param[in] intContextCacheAttr New selection
85586 +
85587 + @Return E_OK on success; Error code otherwise.
85588 +
85589 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85590 +*//***************************************************************************/
85591 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmDmaCacheOption intContextCacheAttr);
85592 +
85593 +/**************************************************************************//**
85594 + @Function FM_PORT_ConfigDmaHdrAttr
85595 +
85596 + @Description Calling this routine changes the header cache
85597 + attribute parameter in the internal driver data base
85598 + from its default configuration [DEFAULT_PORT_dmaHeaderCacheAttr]
85599 +
85600 + May be used for all port types
85601 +
85602 + @Param[in] h_FmPort A handle to a FM Port module.
85603 + @Param[in] headerCacheAttr New selection
85604 +
85605 + @Return E_OK on success; Error code otherwise.
85606 +
85607 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85608 +*//***************************************************************************/
85609 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmDmaCacheOption headerCacheAttr);
85610 +
85611 +/**************************************************************************//**
85612 + @Function FM_PORT_ConfigDmaScatterGatherAttr
85613 +
85614 + @Description Calling this routine changes the scatter gather cache
85615 + attribute parameter in the internal driver data base
85616 + from its default configuration [DEFAULT_PORT_dmaScatterGatherCacheAttr]
85617 +
85618 + May be used for all port types
85619 +
85620 + @Param[in] h_FmPort A handle to a FM Port module.
85621 + @Param[in] scatterGatherCacheAttr New selection
85622 +
85623 + @Return E_OK on success; Error code otherwise.
85624 +
85625 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85626 +*//***************************************************************************/
85627 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr);
85628 +
85629 +/**************************************************************************//**
85630 + @Function FM_PORT_ConfigDmaWriteOptimize
85631 +
85632 + @Description Calling this routine changes the write optimization
85633 + parameter in the internal driver data base
85634 + from its default configuration: By default optimize = [DEFAULT_PORT_dmaWriteOptimize].
85635 + Note:
85636 +
85637 + 1. For head optimization, data alignment must be >= 16 (supported by default).
85638 +
85639 + 3. For tail optimization, note that the optimization is performed by extending the write transaction
85640 + of the frame payload at the tail as needed to achieve optimal bus transfers, so that the last write
85641 + is extended to be on 16/64 bytes aligned block (chip dependent).
85642 +
85643 + Relevant for non-Tx port types
85644 +
85645 + @Param[in] h_FmPort A handle to a FM Port module.
85646 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
85647 +
85648 + @Return E_OK on success; Error code otherwise.
85649 +
85650 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85651 +*//***************************************************************************/
85652 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize);
85653 +
85654 +/**************************************************************************//**
85655 + @Function FM_PORT_ConfigNoScatherGather
85656 +
85657 + @Description Calling this routine changes the noScatherGather parameter in internal driver data base
85658 + from its default configuration.
85659 +
85660 + @Param[in] h_FmPort A handle to a FM Port module.
85661 + @Param[in] noScatherGather (TRUE - frame is discarded if can not be stored in single buffer,
85662 + FALSE - frame can be stored in scatter gather (S/G) format).
85663 +
85664 + @Return E_OK on success; Error code otherwise.
85665 +
85666 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85667 +*//***************************************************************************/
85668 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather);
85669 +
85670 +/**************************************************************************//**
85671 + @Function FM_PORT_ConfigDfltColor
85672 +
85673 + @Description Calling this routine changes the internal default color parameter
85674 + in the internal driver data base
85675 + from its default configuration [DEFAULT_PORT_color]
85676 +
85677 + May be used for all port types
85678 +
85679 + @Param[in] h_FmPort A handle to a FM Port module.
85680 + @Param[in] color New selection
85681 +
85682 + @Return E_OK on success; Error code otherwise.
85683 +
85684 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85685 +*//***************************************************************************/
85686 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color);
85687 +
85688 +/**************************************************************************//**
85689 + @Function FM_PORT_ConfigSyncReq
85690 +
85691 + @Description Calling this routine changes the synchronization attribute parameter
85692 + in the internal driver data base from its default configuration:
85693 + syncReq = [DEFAULT_PORT_syncReq]
85694 +
85695 + May be used for all port types
85696 +
85697 + @Param[in] h_FmPort A handle to a FM Port module.
85698 + @Param[in] syncReq TRUE to request synchronization, FALSE otherwize.
85699 +
85700 + @Return E_OK on success; Error code otherwise.
85701 +
85702 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85703 +*//***************************************************************************/
85704 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq);
85705 +
85706 +/**************************************************************************//**
85707 + @Function FM_PORT_ConfigForwardReuseIntContext
85708 +
85709 + @Description This routine is relevant for Rx ports that are routed to OP port.
85710 + It changes the internal context reuse option in the internal
85711 + driver data base from its default configuration:
85712 + reuse = [DEFAULT_PORT_forwardIntContextReuse]
85713 +
85714 + May be used for Rx ports only
85715 +
85716 + @Param[in] h_FmPort A handle to a FM Port module.
85717 + @Param[in] reuse TRUE to reuse internal context on frames
85718 + forwarded to OP port.
85719 +
85720 + @Return E_OK on success; Error code otherwise.
85721 +
85722 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85723 +*//***************************************************************************/
85724 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool reuse);
85725 +
85726 +/**************************************************************************//**
85727 + @Function FM_PORT_ConfigDontReleaseTxBufToBM
85728 +
85729 + @Description This routine should be called if no Tx confirmation
85730 + is done, and yet buffers should not be released to the BM.
85731 + Normally, buffers are returned using the Tx confirmation
85732 + process. When Tx confirmation is not used (defFqid=0),
85733 + buffers are typically released to the BM. This routine
85734 + may be called to avoid this behavior and not release the
85735 + buffers.
85736 +
85737 + May be used for Tx ports only
85738 +
85739 + @Param[in] h_FmPort A handle to a FM Port module.
85740 +
85741 + @Return E_OK on success; Error code otherwise.
85742 +
85743 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85744 +*//***************************************************************************/
85745 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort);
85746 +
85747 +/**************************************************************************//**
85748 + @Function FM_PORT_ConfigIMMaxRxBufLength
85749 +
85750 + @Description Changes the maximum receive buffer length from its default
85751 + configuration: Closest rounded down power of 2 value of the
85752 + data buffer size.
85753 +
85754 + The maximum receive buffer length directly affects the structure
85755 + of received frames (single- or multi-buffered) and the performance
85756 + of both the FM and the driver.
85757 +
85758 + The selection between single- or multi-buffered frames should be
85759 + done according to the characteristics of the specific application.
85760 + The recommended mode is to use a single data buffer per packet,
85761 + as this mode provides the best performance. However, the user can
85762 + select to use multiple data buffers per packet.
85763 +
85764 + @Param[in] h_FmPort A handle to a FM Port module.
85765 + @Param[in] newVal Maximum receive buffer length (in bytes).
85766 +
85767 + @Return E_OK on success; Error code otherwise.
85768 +
85769 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85770 + This routine is to be used only if Independent-Mode is enabled.
85771 +*//***************************************************************************/
85772 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal);
85773 +
85774 +/**************************************************************************//**
85775 + @Function FM_PORT_ConfigIMRxBdRingLength
85776 +
85777 + @Description Changes the receive BD ring length from its default
85778 + configuration:[DEFAULT_PORT_rxBdRingLength]
85779 +
85780 + @Param[in] h_FmPort A handle to a FM Port module.
85781 + @Param[in] newVal The desired BD ring length.
85782 +
85783 + @Return E_OK on success; Error code otherwise.
85784 +
85785 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85786 + This routine is to be used only if Independent-Mode is enabled.
85787 +*//***************************************************************************/
85788 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85789 +
85790 +/**************************************************************************//**
85791 + @Function FM_PORT_ConfigIMTxBdRingLength
85792 +
85793 + @Description Changes the transmit BD ring length from its default
85794 + configuration:[DEFAULT_PORT_txBdRingLength]
85795 +
85796 + @Param[in] h_FmPort A handle to a FM Port module.
85797 + @Param[in] newVal The desired BD ring length.
85798 +
85799 + @Return E_OK on success; Error code otherwise.
85800 +
85801 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85802 + This routine is to be used only if Independent-Mode is enabled.
85803 +*//***************************************************************************/
85804 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85805 +
85806 +/**************************************************************************//**
85807 + @Function FM_PORT_ConfigIMFmanCtrlExternalStructsMemory
85808 +
85809 + @Description Configures memory partition and attributes for FMan-Controller
85810 + data structures (e.g. BD rings).
85811 + Calling this routine changes the internal driver data base
85812 + from its default configuration
85813 + [DEFAULT_PORT_ImfwExtStructsMemId, DEFAULT_PORT_ImfwExtStructsMemAttr].
85814 +
85815 + @Param[in] h_FmPort A handle to a FM Port module.
85816 + @Param[in] memId Memory partition ID.
85817 + @Param[in] memAttributes Memory attributes mask (a combination of MEMORY_ATTR_x flags).
85818 +
85819 + @Return E_OK on success; Error code otherwise.
85820 +*//***************************************************************************/
85821 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
85822 + uint8_t memId,
85823 + uint32_t memAttributes);
85824 +
85825 +/**************************************************************************//**
85826 + @Function FM_PORT_ConfigIMPolling
85827 +
85828 + @Description Changes the Rx flow from interrupt driven (default) to polling.
85829 +
85830 + @Param[in] h_FmPort A handle to a FM Port module.
85831 +
85832 + @Return E_OK on success; Error code otherwise.
85833 +
85834 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85835 + This routine is to be used only if Independent-Mode is enabled.
85836 +*//***************************************************************************/
85837 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort);
85838 +
85839 +/**************************************************************************//**
85840 + @Function FM_PORT_ConfigMaxFrameLength
85841 +
85842 + @Description Changes the definition of the max size of frame that should be
85843 + transmitted/received on this port from its default value [DEFAULT_PORT_maxFrameLength].
85844 + This parameter is used for confirmation of the minimum Fifo
85845 + size calculations and only for Tx ports or ports working in
85846 + independent mode. This should be larger than the maximum possible
85847 + MTU that will be used for this port (i.e. its MAC).
85848 +
85849 + @Param[in] h_FmPort A handle to a FM Port module.
85850 + @Param[in] length Max size of frame
85851 +
85852 + @Return E_OK on success; Error code otherwise.
85853 +
85854 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85855 + This routine is to be used only if Independent-Mode is enabled.
85856 +*//***************************************************************************/
85857 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length);
85858 +
85859 +/**************************************************************************//*
85860 + @Function FM_PORT_ConfigTxFifoMinFillLevel
85861 +
85862 + @Description Calling this routine changes the fifo minimum
85863 + fill level parameter in the internal driver data base
85864 + from its default configuration [DEFAULT_PORT_txFifoMinFillLevel]
85865 +
85866 + May be used for Tx ports only
85867 +
85868 + @Param[in] h_FmPort A handle to a FM Port module.
85869 + @Param[in] minFillLevel New value
85870 +
85871 + @Return E_OK on success; Error code otherwise.
85872 +
85873 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85874 +*//***************************************************************************/
85875 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel);
85876 +
85877 +/**************************************************************************//*
85878 + @Function FM_PORT_ConfigFifoDeqPipelineDepth
85879 +
85880 + @Description Calling this routine changes the fifo dequeue
85881 + pipeline depth parameter in the internal driver data base
85882 +
85883 + from its default configuration: 1G ports: [DEFAULT_PORT_fifoDeqPipelineDepth_1G],
85884 + 10G port: [DEFAULT_PORT_fifoDeqPipelineDepth_10G],
85885 + OP port: [DEFAULT_PORT_fifoDeqPipelineDepth_OH]
85886 +
85887 + May be used for Tx/OP ports only
85888 +
85889 + @Param[in] h_FmPort A handle to a FM Port module.
85890 + @Param[in] deqPipelineDepth New value
85891 +
85892 + @Return E_OK on success; Error code otherwise.
85893 +
85894 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85895 +*//***************************************************************************/
85896 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth);
85897 +
85898 +/**************************************************************************//*
85899 + @Function FM_PORT_ConfigTxFifoLowComfLevel
85900 +
85901 + @Description Calling this routine changes the fifo low comfort level
85902 + parameter in internal driver data base
85903 + from its default configuration [DEFAULT_PORT_txFifoLowComfLevel]
85904 +
85905 + May be used for Tx ports only
85906 +
85907 + @Param[in] h_FmPort A handle to a FM Port module.
85908 + @Param[in] fifoLowComfLevel New value
85909 +
85910 + @Return E_OK on success; Error code otherwise.
85911 +
85912 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85913 +*//***************************************************************************/
85914 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel);
85915 +
85916 +/**************************************************************************//*
85917 + @Function FM_PORT_ConfigRxFifoThreshold
85918 +
85919 + @Description Calling this routine changes the threshold of the FIFO
85920 + fill level parameter in the internal driver data base
85921 + from its default configuration [DEFAULT_PORT_rxFifoThreshold]
85922 +
85923 + If the total number of buffers which are
85924 + currently in use and associated with the
85925 + specific RX port exceed this threshold, the
85926 + BMI will signal the MAC to send a pause frame
85927 + over the link.
85928 +
85929 + May be used for Rx ports only
85930 +
85931 + @Param[in] h_FmPort A handle to a FM Port module.
85932 + @Param[in] fifoThreshold New value
85933 +
85934 + @Return E_OK on success; Error code otherwise.
85935 +
85936 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85937 +*//***************************************************************************/
85938 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold);
85939 +
85940 +/**************************************************************************//*
85941 + @Function FM_PORT_ConfigRxFifoPriElevationLevel
85942 +
85943 + @Description Calling this routine changes the priority elevation level
85944 + parameter in the internal driver data base from its default
85945 + configuration [DEFAULT_PORT_rxFifoPriElevationLevel]
85946 +
85947 + If the total number of buffers which are currently in use and
85948 + associated with the specific RX port exceed the amount specified
85949 + in priElevationLevel, BMI will signal the main FM's DMA to
85950 + elevate the FM priority on the system bus.
85951 +
85952 + May be used for Rx ports only
85953 +
85954 + @Param[in] h_FmPort A handle to a FM Port module.
85955 + @Param[in] priElevationLevel New value
85956 +
85957 + @Return E_OK on success; Error code otherwise.
85958 +
85959 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85960 +*//***************************************************************************/
85961 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel);
85962 +
85963 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
85964 +/**************************************************************************//*
85965 + @Function FM_PORT_ConfigBCBWorkaround
85966 +
85967 + @Description Configures BCB errata workaround.
85968 +
85969 + When BCB errata is applicable, the workaround is always
85970 + performed by FM Controller. Thus, this functions doesn't
85971 + actually enable errata workaround but rather allows driver
85972 + to perform adjustments required due to errata workaround
85973 + execution in FM controller.
85974 +
85975 + Applying BCB workaround also configures FM_PORT_FRM_ERR_PHYSICAL
85976 + errors to be discarded. Thus FM_PORT_FRM_ERR_PHYSICAL can't be
85977 + set by FM_PORT_SetErrorsRoute() function.
85978 +
85979 + @Param[in] h_FmPort A handle to a FM Port module.
85980 +
85981 + @Return E_OK on success; Error code otherwise.
85982 +
85983 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85984 +*//***************************************************************************/
85985 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort);
85986 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
85987 +
85988 +#if (DPAA_VERSION >= 11)
85989 +/**************************************************************************//*
85990 + @Function FM_PORT_ConfigInternalBuffOffset
85991 +
85992 + @Description Configures internal buffer offset.
85993 +
85994 + May be used for Rx and OP ports only
85995 +
85996 + @Param[in] h_FmPort A handle to a FM Port module.
85997 + @Param[in] val New value
85998 +
85999 + @Return E_OK on success; Error code otherwise.
86000 +
86001 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86002 +*//***************************************************************************/
86003 +t_Error FM_PORT_ConfigInternalBuffOffset(t_Handle h_FmPort, uint8_t val);
86004 +#endif /* (DPAA_VERSION >= 11) */
86005 +
86006 +/** @} */ /* end of FM_PORT_advanced_init_grp group */
86007 +/** @} */ /* end of FM_PORT_init_grp group */
86008 +
86009 +
86010 +/**************************************************************************//**
86011 + @Group FM_PORT_runtime_control_grp FM Port Runtime Control Unit
86012 +
86013 + @Description FM Port Runtime control unit API functions, definitions and enums.
86014 +
86015 + @{
86016 +*//***************************************************************************/
86017 +
86018 +/**************************************************************************//**
86019 + @Description enum for defining FM Port counters
86020 +*//***************************************************************************/
86021 +typedef enum e_FmPortCounters {
86022 + e_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
86023 + e_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
86024 + e_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
86025 + e_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
86026 + e_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
86027 + e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
86028 + e_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
86029 + e_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
86030 + e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
86031 + e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
86032 + e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
86033 + e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
86034 + e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
86035 + e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
86036 + e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
86037 + e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
86038 + e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
86039 + e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
86040 + e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
86041 + e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
86042 + e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
86043 + e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
86044 +} e_FmPortCounters;
86045 +
86046 +typedef struct t_FmPortBmiStats {
86047 + uint32_t cntCycle;
86048 + uint32_t cntTaskUtil;
86049 + uint32_t cntQueueUtil;
86050 + uint32_t cntDmaUtil;
86051 + uint32_t cntFifoUtil;
86052 + uint32_t cntRxPauseActivation;
86053 + uint32_t cntFrame;
86054 + uint32_t cntDiscardFrame;
86055 + uint32_t cntDeallocBuf;
86056 + uint32_t cntRxBadFrame;
86057 + uint32_t cntRxLargeFrame;
86058 + uint32_t cntRxFilterFrame;
86059 + uint32_t cntRxListDmaErr;
86060 + uint32_t cntRxOutOfBuffersDiscard;
86061 + uint32_t cntWredDiscard;
86062 + uint32_t cntLengthErr;
86063 + uint32_t cntUnsupportedFormat;
86064 +} t_FmPortBmiStats;
86065 +
86066 +/**************************************************************************//**
86067 + @Description Structure for Port id parameters.
86068 + Fields commented 'IN' are passed by the port module to be used
86069 + by the FM module.
86070 + Fields commented 'OUT' will be filled by FM before returning to port.
86071 +*//***************************************************************************/
86072 +typedef struct t_FmPortCongestionGrps {
86073 + uint16_t numOfCongestionGrpsToConsider; /**< The number of required CGs
86074 + to define the size of the following array */
86075 + uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS];
86076 + /**< An array of CG indexes;
86077 + Note that the size of the array should be
86078 + 'numOfCongestionGrpsToConsider'. */
86079 +#if (DPAA_VERSION >= 11)
86080 + bool pfcPrioritiesEn[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
86081 + /**< a matrix that represents the map between the CG ids
86082 + defined in 'congestionGrpsToConsider' to the priorties
86083 + mapping array. */
86084 +#endif /* (DPAA_VERSION >= 11) */
86085 +} t_FmPortCongestionGrps;
86086 +
86087 +/**************************************************************************//**
86088 + @Description Structure for Deep Sleep Auto Response ARP Entry
86089 +*//***************************************************************************/
86090 +typedef struct t_FmPortDsarArpEntry
86091 +{
86092 + uint32_t ipAddress;
86093 + uint8_t mac[6];
86094 + bool isVlan;
86095 + uint16_t vid;
86096 +} t_FmPortDsarArpEntry;
86097 +
86098 +/**************************************************************************//**
86099 + @Description Structure for Deep Sleep Auto Response ARP info
86100 +*//***************************************************************************/
86101 +typedef struct t_FmPortDsarArpInfo
86102 +{
86103 + uint8_t tableSize;
86104 + t_FmPortDsarArpEntry *p_AutoResTable;
86105 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
86106 +} t_FmPortDsarArpInfo;
86107 +
86108 +/**************************************************************************//**
86109 + @Description Structure for Deep Sleep Auto Response NDP Entry
86110 +*//***************************************************************************/
86111 +typedef struct t_FmPortDsarNdpEntry
86112 +{
86113 + uint32_t ipAddress[4];
86114 + uint8_t mac[6];
86115 + bool isVlan;
86116 + uint16_t vid;
86117 +} t_FmPortDsarNdpEntry;
86118 +
86119 +/**************************************************************************//**
86120 + @Description Structure for Deep Sleep Auto Response NDP info
86121 +*//***************************************************************************/
86122 +typedef struct t_FmPortDsarNdpInfo
86123 +{
86124 + uint32_t multicastGroup;
86125 +
86126 + uint8_t tableSizeAssigned;
86127 + t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses.
86128 + Note that all IP adresses must be from the same multicast group.
86129 + This will be checked and if not operation will fail. */
86130 + uint8_t tableSizeTmp;
86131 + t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses.
86132 + Note that all temp IP adresses must be from the same multicast group.
86133 + This will be checked and if not operation will fail. */
86134 +
86135 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
86136 +
86137 +} t_FmPortDsarNdpInfo;
86138 +
86139 +/**************************************************************************//**
86140 + @Description Structure for Deep Sleep Auto Response ICMPV4 info
86141 +*//***************************************************************************/
86142 +typedef struct t_FmPortDsarEchoIpv4Info
86143 +{
86144 + uint8_t tableSize;
86145 + t_FmPortDsarArpEntry *p_AutoResTable;
86146 +} t_FmPortDsarEchoIpv4Info;
86147 +
86148 +/**************************************************************************//**
86149 + @Description Structure for Deep Sleep Auto Response ICMPV6 info
86150 +*//***************************************************************************/
86151 +typedef struct t_FmPortDsarEchoIpv6Info
86152 +{
86153 + uint8_t tableSize;
86154 + t_FmPortDsarNdpEntry *p_AutoResTable;
86155 +} t_FmPortDsarEchoIpv6Info;
86156 +
86157 +/**************************************************************************//**
86158 +@Description Deep Sleep Auto Response SNMP OIDs table entry
86159 +
86160 +*//***************************************************************************/
86161 +typedef struct {
86162 + uint16_t oidSize;
86163 + uint8_t *oidVal; /* only the oid string */
86164 + uint16_t resSize;
86165 + uint8_t *resVal; /* resVal will be the entire reply,
86166 + i.e. "Type|Length|Value" */
86167 +} t_FmPortDsarOidsEntry;
86168 +
86169 +/**************************************************************************//**
86170 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
86171 + Refer to the FMan Controller spec for more details.
86172 +*//***************************************************************************/
86173 +typedef struct
86174 +{
86175 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
86176 + bool isVlan;
86177 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
86178 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
86179 +} t_FmPortDsarSnmpIpv4AddrTblEntry;
86180 +
86181 +/**************************************************************************//**
86182 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
86183 + Refer to the FMan Controller spec for more details.
86184 +*//***************************************************************************/
86185 +typedef struct
86186 +{
86187 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
86188 + bool isVlan;
86189 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
86190 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
86191 +} t_FmPortDsarSnmpIpv6AddrTblEntry;
86192 +
86193 +/**************************************************************************//**
86194 + @Description Deep Sleep Auto Response SNMP Descriptor
86195 +
86196 +*//***************************************************************************/
86197 +typedef struct
86198 +{
86199 + uint16_t control; /**< Control bits [0-15]. */
86200 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
86201 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
86202 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
86203 + t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
86204 + t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
86205 + uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
86206 + uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
86207 + t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */
86208 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
86209 +} t_FmPortDsarSnmpInfo;
86210 +
86211 +/**************************************************************************//**
86212 + @Description Structure for Deep Sleep Auto Response filtering Entry
86213 +*//***************************************************************************/
86214 +typedef struct t_FmPortDsarFilteringEntry
86215 +{
86216 + uint16_t srcPort;
86217 + uint16_t dstPort;
86218 + uint16_t srcPortMask;
86219 + uint16_t dstPortMask;
86220 +} t_FmPortDsarFilteringEntry;
86221 +
86222 +/**************************************************************************//**
86223 + @Description Structure for Deep Sleep Auto Response filtering info
86224 +*//***************************************************************************/
86225 +typedef struct t_FmPortDsarFilteringInfo
86226 +{
86227 + /* IP protocol filtering parameters */
86228 + uint8_t ipProtTableSize;
86229 + uint8_t *p_IpProtTablePtr;
86230 + bool ipProtPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
86231 + hit will pass the packet to UDP/TCP filters if needed and if not
86232 + to the classification tree. If the classification tree will pass
86233 + the packet to a queue it will cause a wake interupt.
86234 + When FALSE it the other way around. */
86235 + /* UDP port filtering parameters */
86236 + uint8_t udpPortsTableSize;
86237 + t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr;
86238 + bool udpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
86239 + hit will pass the packet to classification tree.
86240 + If the classification tree will pass the packet to a queue it
86241 + will cause a wake interupt.
86242 + When FALSE it the other way around. */
86243 + /* TCP port filtering parameters */
86244 + uint16_t tcpFlagsMask;
86245 + uint8_t tcpPortsTableSize;
86246 + t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr;
86247 + bool tcpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
86248 + hit will pass the packet to classification tree.
86249 + If the classification tree will pass the packet to a queue it
86250 + will cause a wake interupt.
86251 + When FALSE it the other way around. */
86252 +} t_FmPortDsarFilteringInfo;
86253 +
86254 +/**************************************************************************//**
86255 + @Description Structure for Deep Sleep Auto Response parameters
86256 +*//***************************************************************************/
86257 +typedef struct t_FmPortDsarParams
86258 +{
86259 + t_Handle h_FmPortTx;
86260 + t_FmPortDsarArpInfo *p_AutoResArpInfo;
86261 + t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info;
86262 + t_FmPortDsarNdpInfo *p_AutoResNdpInfo;
86263 + t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info;
86264 + t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo;
86265 + t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo;
86266 +} t_FmPortDsarParams;
86267 +
86268 +/**************************************************************************//**
86269 + @Function FM_PORT_EnterDsar
86270 +
86271 + @Description Enter Deep Sleep Auto Response mode.
86272 + This function write the apropriate values to in the relevant
86273 + tables in the MURAM.
86274 +
86275 + @Param[in] h_FmPortRx - FM PORT module descriptor
86276 + @Param[in] params - Auto Response parameters
86277 +
86278 + @Return E_OK on success; Error code otherwise.
86279 +
86280 + @Cautions Allowed only following FM_PORT_Init().
86281 +*//***************************************************************************/
86282 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params);
86283 +
86284 +/**************************************************************************//**
86285 + @Function FM_PORT_EnterDsarFinal
86286 +
86287 + @Description Enter Deep Sleep Auto Response mode.
86288 + This function sets the Tx port in independent mode as needed
86289 + and redirect the receive flow to go through the
86290 + Dsar Fman-ctrl code
86291 +
86292 + @Param[in] h_DsarRxPort - FM Rx PORT module descriptor
86293 + @Param[in] h_DsarTxPort - FM Tx PORT module descriptor
86294 +
86295 + @Return E_OK on success; Error code otherwise.
86296 +
86297 + @Cautions Allowed only following FM_PORT_Init().
86298 +*//***************************************************************************/
86299 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort);
86300 +
86301 +/**************************************************************************//**
86302 + @Function FM_PORT_ExitDsar
86303 +
86304 + @Description Exit Deep Sleep Auto Response mode.
86305 + This function reverse the AR mode and put the ports back into
86306 + their original wake mode
86307 +
86308 + @Param[in] h_FmPortRx - FM PORT Rx module descriptor
86309 + @Param[in] h_FmPortTx - FM PORT Tx module descriptor
86310 +
86311 + @Return E_OK on success; Error code otherwise.
86312 +
86313 + @Cautions Allowed only following FM_PORT_EnterDsar().
86314 +*//***************************************************************************/
86315 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx);
86316 +
86317 +/**************************************************************************//**
86318 + @Function FM_PORT_IsInDsar
86319 +
86320 + @Description This function returns TRUE if the port was set as Auto Response
86321 + and FALSE if not. Once Exit AR mode it will return FALSE as well
86322 + until re-enabled once more.
86323 +
86324 + @Param[in] h_FmPort - FM PORT module descriptor
86325 +
86326 + @Return E_OK on success; Error code otherwise.
86327 +*//***************************************************************************/
86328 +bool FM_PORT_IsInDsar(t_Handle h_FmPort);
86329 +
86330 +typedef struct t_FmPortDsarStats
86331 +{
86332 + uint32_t arpArCnt;
86333 + uint32_t echoIcmpv4ArCnt;
86334 + uint32_t ndpArCnt;
86335 + uint32_t echoIcmpv6ArCnt;
86336 + uint32_t snmpGetCnt;
86337 + uint32_t snmpGetNextCnt;
86338 +} t_FmPortDsarStats;
86339 +
86340 +/**************************************************************************//**
86341 + @Function FM_PORT_GetDsarStats
86342 +
86343 + @Description Return statistics for Deep Sleep Auto Response
86344 +
86345 + @Param[in] h_FmPortRx - FM PORT module descriptor
86346 + @Param[out] stats - structure containing the statistics counters
86347 +
86348 + @Return E_OK on success; Error code otherwise.
86349 +*//***************************************************************************/
86350 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats);
86351 +
86352 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
86353 +/**************************************************************************//**
86354 + @Function FM_PORT_DumpRegs
86355 +
86356 + @Description Dump all regs.
86357 +
86358 + Calling this routine invalidates the descriptor.
86359 +
86360 + @Param[in] h_FmPort - FM PORT module descriptor
86361 +
86362 + @Return E_OK on success; Error code otherwise.
86363 +
86364 + @Cautions Allowed only following FM_PORT_Init().
86365 +*//***************************************************************************/
86366 +t_Error FM_PORT_DumpRegs(t_Handle h_FmPort);
86367 +#endif /* (defined(DEBUG_ERRORS) && ... */
86368 +
86369 +/**************************************************************************//**
86370 + @Function FM_PORT_GetBufferDataOffset
86371 +
86372 + @Description Relevant for Rx ports.
86373 + Returns the data offset from the beginning of the data buffer
86374 +
86375 + @Param[in] h_FmPort - FM PORT module descriptor
86376 +
86377 + @Return data offset.
86378 +
86379 + @Cautions Allowed only following FM_PORT_Init().
86380 +*//***************************************************************************/
86381 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort);
86382 +
86383 +/**************************************************************************//**
86384 + @Function FM_PORT_GetBufferICInfo
86385 +
86386 + @Description Returns the Internal Context offset from the beginning of the data buffer
86387 +
86388 + @Param[in] h_FmPort - FM PORT module descriptor
86389 + @Param[in] p_Data - A pointer to the data buffer.
86390 +
86391 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
86392 + configured for this port.
86393 +
86394 + @Cautions Allowed only following FM_PORT_Init().
86395 +*//***************************************************************************/
86396 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data);
86397 +
86398 +/**************************************************************************//**
86399 + @Function FM_PORT_GetBufferPrsResult
86400 +
86401 + @Description Returns the pointer to the parse result in the data buffer.
86402 + In Rx ports this is relevant after reception, if parse
86403 + result is configured to be part of the data passed to the
86404 + application. For non Rx ports it may be used to get the pointer
86405 + of the area in the buffer where parse result should be
86406 + initialized - if so configured.
86407 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
86408 + configuration.
86409 +
86410 + @Param[in] h_FmPort - FM PORT module descriptor
86411 + @Param[in] p_Data - A pointer to the data buffer.
86412 +
86413 + @Return Parse result pointer on success, NULL if parse result was not
86414 + configured for this port.
86415 +
86416 + @Cautions Allowed only following FM_PORT_Init().
86417 +*//***************************************************************************/
86418 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data);
86419 +
86420 +/**************************************************************************//**
86421 + @Function FM_PORT_GetBufferTimeStamp
86422 +
86423 + @Description Returns the time stamp in the data buffer.
86424 + Relevant for Rx ports for getting the buffer time stamp.
86425 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
86426 + configuration.
86427 +
86428 + @Param[in] h_FmPort - FM PORT module descriptor
86429 + @Param[in] p_Data - A pointer to the data buffer.
86430 +
86431 + @Return A pointer to the hash result on success, NULL otherwise.
86432 +
86433 + @Cautions Allowed only following FM_PORT_Init().
86434 +*//***************************************************************************/
86435 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data);
86436 +
86437 +/**************************************************************************//**
86438 + @Function FM_PORT_GetBufferHashResult
86439 +
86440 + @Description Given a data buffer, on the condition that hash result was defined
86441 + as a part of the buffer content (see FM_PORT_ConfigBufferPrefixContent)
86442 + this routine will return the pointer to the hash result location in the
86443 + buffer prefix.
86444 +
86445 + @Param[in] h_FmPort - FM PORT module descriptor
86446 + @Param[in] p_Data - A pointer to the data buffer.
86447 +
86448 + @Return A pointer to the hash result on success, NULL otherwise.
86449 +
86450 + @Cautions Allowed only following FM_PORT_Init().
86451 +*//***************************************************************************/
86452 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data);
86453 +
86454 +/**************************************************************************//**
86455 + @Function FM_PORT_Disable
86456 +
86457 + @Description Gracefully disable an FM port. The port will not start new tasks after all
86458 + tasks associated with the port are terminated.
86459 +
86460 + @Param[in] h_FmPort A handle to a FM Port module.
86461 +
86462 + @Return E_OK on success; Error code otherwise.
86463 +
86464 + @Cautions Allowed only following FM_PORT_Init().
86465 + This is a blocking routine, it returns after port is
86466 + gracefully stopped, i.e. the port will not except new frames,
86467 + but it will finish all frames or tasks which were already began
86468 +*//***************************************************************************/
86469 +t_Error FM_PORT_Disable(t_Handle h_FmPort);
86470 +
86471 +/**************************************************************************//**
86472 + @Function FM_PORT_Enable
86473 +
86474 + @Description A runtime routine provided to allow disable/enable of port.
86475 +
86476 + @Param[in] h_FmPort A handle to a FM Port module.
86477 +
86478 + @Return E_OK on success; Error code otherwise.
86479 +
86480 + @Cautions Allowed only following FM_PORT_Init().
86481 +*//***************************************************************************/
86482 +t_Error FM_PORT_Enable(t_Handle h_FmPort);
86483 +
86484 +/**************************************************************************//**
86485 + @Function FM_PORT_SetRateLimit
86486 +
86487 + @Description Calling this routine enables rate limit algorithm.
86488 + By default, this functionality is disabled.
86489 + Note that rate-limit mechanism uses the FM time stamp.
86490 + The selected rate limit specified here would be
86491 + rounded DOWN to the nearest 16M.
86492 +
86493 + May be used for Tx and OP ports only
86494 +
86495 + @Param[in] h_FmPort A handle to a FM Port module.
86496 + @Param[in] p_RateLimit A structure of rate limit parameters
86497 +
86498 + @Return E_OK on success; Error code otherwise.
86499 +
86500 + @Cautions Allowed only following FM_PORT_Init().
86501 + If rate limit is set on a port that need to send PFC frames,
86502 + it might violate the stop transmit timing.
86503 +*//***************************************************************************/
86504 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit);
86505 +
86506 +/**************************************************************************//**
86507 + @Function FM_PORT_DeleteRateLimit
86508 +
86509 + @Description Calling this routine disables and clears rate limit
86510 + initialization.
86511 +
86512 + May be used for Tx and OP ports only
86513 +
86514 + @Param[in] h_FmPort A handle to a FM Port module.
86515 +
86516 + @Return E_OK on success; Error code otherwise.
86517 +
86518 + @Cautions Allowed only following FM_PORT_Init().
86519 +*//***************************************************************************/
86520 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort);
86521 +
86522 +/**************************************************************************//**
86523 + @Function FM_PORT_SetPfcPrioritiesMappingToQmanWQ
86524 +
86525 + @Description Calling this routine maps each PFC received priority to the transmit WQ.
86526 + This WQ will be blocked upon receiving a PFC frame with this priority.
86527 +
86528 + May be used for Tx ports only.
86529 +
86530 + @Param[in] h_FmPort A handle to a FM Port module.
86531 + @Param[in] prio PFC priority (0-7).
86532 + @Param[in] wq Work Queue (0-7).
86533 +
86534 + @Return E_OK on success; Error code otherwise.
86535 +
86536 + @Cautions Allowed only following FM_PORT_Init().
86537 +*//***************************************************************************/
86538 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, uint8_t wq);
86539 +
86540 +/**************************************************************************//**
86541 + @Function FM_PORT_SetStatisticsCounters
86542 +
86543 + @Description Calling this routine enables/disables port's statistics counters.
86544 + By default, counters are enabled.
86545 +
86546 + May be used for all port types
86547 +
86548 + @Param[in] h_FmPort A handle to a FM Port module.
86549 + @Param[in] enable TRUE to enable, FALSE to disable.
86550 +
86551 + @Return E_OK on success; Error code otherwise.
86552 +
86553 + @Cautions Allowed only following FM_PORT_Init().
86554 +*//***************************************************************************/
86555 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable);
86556 +
86557 +/**************************************************************************//**
86558 + @Function FM_PORT_SetFrameQueueCounters
86559 +
86560 + @Description Calling this routine enables/disables port's enqueue/dequeue counters.
86561 + By default, counters are enabled.
86562 +
86563 + May be used for all ports
86564 +
86565 + @Param[in] h_FmPort A handle to a FM Port module.
86566 + @Param[in] enable TRUE to enable, FALSE to disable.
86567 +
86568 + @Return E_OK on success; Error code otherwise.
86569 +
86570 + @Cautions Allowed only following FM_PORT_Init().
86571 +*//***************************************************************************/
86572 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable);
86573 +
86574 +/**************************************************************************//**
86575 + @Function FM_PORT_AnalyzePerformanceParams
86576 +
86577 + @Description User may call this routine to so the driver will analyze if the
86578 + basic performance parameters are correct and also the driver may
86579 + suggest of improvements; The basic parameters are FIFO sizes, number
86580 + of DMAs and number of TNUMs for the port.
86581 +
86582 + May be used for all port types
86583 +
86584 + @Param[in] h_FmPort A handle to a FM Port module.
86585 +
86586 + @Return E_OK on success; Error code otherwise.
86587 +
86588 + @Cautions Allowed only following FM_PORT_Init().
86589 +*//***************************************************************************/
86590 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort);
86591 +
86592 +
86593 +/**************************************************************************//**
86594 + @Function FM_PORT_SetAllocBufCounter
86595 +
86596 + @Description Calling this routine enables/disables BM pool allocate
86597 + buffer counters.
86598 + By default, counters are enabled.
86599 +
86600 + May be used for Rx ports only
86601 +
86602 + @Param[in] h_FmPort A handle to a FM Port module.
86603 + @Param[in] poolId BM pool id.
86604 + @Param[in] enable TRUE to enable, FALSE to disable.
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_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable);
86611 +
86612 +/**************************************************************************//**
86613 + @Function FM_PORT_GetBmiCounters
86614 +
86615 + @Description Read port's BMI stat counters and place them into
86616 + a designated structure of counters.
86617 +
86618 + @Param[in] h_FmPort A handle to a FM Port module.
86619 + @Param[out] p_BmiStats counters structure
86620 +
86621 + @Return E_OK on success; Error code otherwise.
86622 +
86623 + @Cautions Allowed only following FM_PORT_Init().
86624 +*//***************************************************************************/
86625 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats);
86626 +
86627 +/**************************************************************************//**
86628 + @Function FM_PORT_GetCounter
86629 +
86630 + @Description Reads one of the FM PORT counters.
86631 +
86632 + @Param[in] h_FmPort A handle to a FM Port module.
86633 + @Param[in] fmPortCounter The requested counter.
86634 +
86635 + @Return Counter's current value.
86636 +
86637 + @Cautions Allowed only following FM_PORT_Init().
86638 + Note that it is user's responsibility to call this routine only
86639 + for enabled counters, and there will be no indication if a
86640 + disabled counter is accessed.
86641 +*//***************************************************************************/
86642 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter);
86643 +
86644 +/**************************************************************************//**
86645 + @Function FM_PORT_ModifyCounter
86646 +
86647 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86648 +
86649 + @Param[in] h_FmPort A handle to a FM Port module.
86650 + @Param[in] fmPortCounter The requested counter.
86651 + @Param[in] value The requested value to be written into the counter.
86652 +
86653 + @Return E_OK on success; Error code otherwise.
86654 +
86655 + @Cautions Allowed only following FM_PORT_Init().
86656 +*//***************************************************************************/
86657 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter, uint32_t value);
86658 +
86659 +/**************************************************************************//**
86660 + @Function FM_PORT_GetAllocBufCounter
86661 +
86662 + @Description Reads one of the FM PORT buffer counters.
86663 +
86664 + @Param[in] h_FmPort A handle to a FM Port module.
86665 + @Param[in] poolId The requested pool.
86666 +
86667 + @Return Counter's current value.
86668 +
86669 + @Cautions Allowed only following FM_PORT_Init().
86670 + Note that it is user's responsibility to call this routine only
86671 + for enabled counters, and there will be no indication if a
86672 + disabled counter is accessed.
86673 +*//***************************************************************************/
86674 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId);
86675 +
86676 +/**************************************************************************//**
86677 + @Function FM_PORT_ModifyAllocBufCounter
86678 +
86679 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86680 +
86681 + @Param[in] h_FmPort A handle to a FM Port module.
86682 + @Param[in] poolId The requested pool.
86683 + @Param[in] value The requested value to be written into the counter.
86684 +
86685 + @Return E_OK on success; Error code otherwise.
86686 +
86687 + @Cautions Allowed only following FM_PORT_Init().
86688 +*//***************************************************************************/
86689 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value);
86690 +
86691 +/**************************************************************************//**
86692 + @Function FM_PORT_AddCongestionGrps
86693 +
86694 + @Description This routine effects the corresponding Tx port.
86695 + It should be called in order to enable pause
86696 + frame transmission in case of congestion in one or more
86697 + of the congestion groups relevant to this port.
86698 + Each call to this routine may add one or more congestion
86699 + groups to be considered relevant to this port.
86700 +
86701 + May be used for Rx, or RX+OP ports only (depending on chip)
86702 +
86703 + @Param[in] h_FmPort A handle to a FM Port module.
86704 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86705 + id's to consider.
86706 +
86707 + @Return E_OK on success; Error code otherwise.
86708 +
86709 + @Cautions Allowed only following FM_PORT_Init().
86710 +*//***************************************************************************/
86711 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86712 +
86713 +/**************************************************************************//**
86714 + @Function FM_PORT_RemoveCongestionGrps
86715 +
86716 + @Description This routine effects the corresponding Tx port. It should be
86717 + called when congestion groups were
86718 + defined for this port and are no longer relevant, or pause
86719 + frames transmitting is not required on their behalf.
86720 + Each call to this routine may remove one or more congestion
86721 + groups to be considered relevant to this port.
86722 +
86723 + May be used for Rx, or RX+OP ports only (depending on chip)
86724 +
86725 + @Param[in] h_FmPort A handle to a FM Port module.
86726 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86727 + id's to consider.
86728 +
86729 + @Return E_OK on success; Error code otherwise.
86730 +
86731 + @Cautions Allowed only following FM_PORT_Init().
86732 +*//***************************************************************************/
86733 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86734 +
86735 +/**************************************************************************//**
86736 + @Function FM_PORT_IsStalled
86737 +
86738 + @Description A routine for checking whether the specified port is stalled.
86739 +
86740 + @Param[in] h_FmPort A handle to a FM Port module.
86741 +
86742 + @Return TRUE if port is stalled, FALSE otherwize
86743 +
86744 + @Cautions Allowed only following FM_PORT_Init().
86745 +*//***************************************************************************/
86746 +bool FM_PORT_IsStalled(t_Handle h_FmPort);
86747 +
86748 +/**************************************************************************//**
86749 + @Function FM_PORT_ReleaseStalled
86750 +
86751 + @Description This routine may be called in case the port was stalled and may
86752 + now be released.
86753 + Note that this routine is available only on older FMan revisions
86754 + (FMan v2, DPAA v1.0 only).
86755 +
86756 + @Param[in] h_FmPort A handle to a FM Port module.
86757 +
86758 + @Return E_OK on success; Error code otherwise.
86759 +
86760 + @Cautions Allowed only following FM_PORT_Init().
86761 +*//***************************************************************************/
86762 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort);
86763 +
86764 +/**************************************************************************//**
86765 + @Function FM_PORT_SetRxL4ChecksumVerify
86766 +
86767 + @Description This routine is relevant for Rx ports (1G and 10G). The routine
86768 + set/clear the L3/L4 checksum verification (on RX side).
86769 + Note that this takes affect only if hw-parser is enabled!
86770 +
86771 + @Param[in] h_FmPort A handle to a FM Port module.
86772 + @Param[in] l4Checksum boolean indicates whether to do L3/L4 checksum
86773 + on frames or not.
86774 +
86775 + @Return E_OK on success; Error code otherwise.
86776 +
86777 + @Cautions Allowed only following FM_PORT_Init().
86778 +*//***************************************************************************/
86779 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum);
86780 +
86781 +/**************************************************************************//**
86782 + @Function FM_PORT_SetErrorsRoute
86783 +
86784 + @Description Errors selected for this routine will cause a frame with that error
86785 + to be enqueued to error queue.
86786 + Errors not selected for this routine will cause a frame with that error
86787 + to be enqueued to the one of the other port queues.
86788 + By default all errors are defined to be enqueued to error queue.
86789 + Errors that were configured to be discarded (at initialization)
86790 + may not be selected here.
86791 +
86792 + May be used for Rx and OP ports only
86793 +
86794 + @Param[in] h_FmPort A handle to a FM Port module.
86795 + @Param[in] errs A list of errors to enqueue to error queue
86796 +
86797 + @Return E_OK on success; Error code otherwise.
86798 +
86799 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86800 +*//***************************************************************************/
86801 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
86802 +
86803 +/**************************************************************************//**
86804 + @Function FM_PORT_SetIMExceptions
86805 +
86806 + @Description Calling this routine enables/disables FM PORT interrupts.
86807 +
86808 + @Param[in] h_FmPort FM PORT module descriptor.
86809 + @Param[in] exception The exception to be selected.
86810 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
86811 +
86812 + @Return E_OK on success; Error code otherwise.
86813 +
86814 + @Cautions Allowed only following FM_PORT_Init().
86815 + This routine should NOT be called from guest-partition
86816 + (i.e. guestId != NCSW_MASTER_ID)
86817 +*//***************************************************************************/
86818 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable);
86819 +
86820 +/**************************************************************************//*
86821 + @Function FM_PORT_SetPerformanceCounters
86822 +
86823 + @Description Calling this routine enables/disables port's performance counters.
86824 + By default, counters are enabled.
86825 +
86826 + May be used for all port types
86827 +
86828 + @Param[in] h_FmPort A handle to a FM Port module.
86829 + @Param[in] enable TRUE to enable, FALSE to disable.
86830 +
86831 + @Return E_OK on success; Error code otherwise.
86832 +
86833 + @Cautions Allowed only following FM_PORT_Init().
86834 +*//***************************************************************************/
86835 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable);
86836 +
86837 +/**************************************************************************//*
86838 + @Function FM_PORT_SetPerformanceCountersParams
86839 +
86840 + @Description Calling this routine defines port's performance
86841 + counters parameters.
86842 +
86843 + May be used for all port types
86844 +
86845 + @Param[in] h_FmPort A handle to a FM Port module.
86846 + @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance
86847 + counters parameters.
86848 +
86849 + @Return E_OK on success; Error code otherwise.
86850 +
86851 + @Cautions Allowed only following FM_PORT_Init().
86852 +*//***************************************************************************/
86853 +t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt);
86854 +
86855 +/**************************************************************************//**
86856 + @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
86857 +
86858 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
86859 +
86860 + @{
86861 +*//***************************************************************************/
86862 +
86863 +/**************************************************************************//**
86864 + @Description A structure defining the KG scheme after the parser.
86865 + This is relevant only to change scheme selection mode - from
86866 + direct to indirect and vice versa, or when the scheme is selected directly,
86867 + to select the scheme id.
86868 +
86869 +*//***************************************************************************/
86870 +typedef struct t_FmPcdKgSchemeSelect {
86871 + bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV. */
86872 + t_Handle h_DirectScheme; /**< Scheme handle, selects the scheme after parser;
86873 + Relevant only when 'direct' is TRUE. */
86874 +} t_FmPcdKgSchemeSelect;
86875 +
86876 +/**************************************************************************//**
86877 + @Description A structure of scheme parameters
86878 +*//***************************************************************************/
86879 +typedef struct t_FmPcdPortSchemesParams {
86880 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86881 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'numOfSchemes' schemes for the
86882 + port to be bound to */
86883 +} t_FmPcdPortSchemesParams;
86884 +
86885 +/**************************************************************************//**
86886 + @Description Union for defining port protocol parameters for parser
86887 +*//***************************************************************************/
86888 +typedef union u_FmPcdHdrPrsOpts {
86889 + /* MPLS */
86890 + struct {
86891 + bool labelInterpretationEnable; /**< When this bit is set, the last MPLS label will be
86892 + interpreted as described in HW spec table. When the bit
86893 + is cleared, the parser will advance to MPLS next parse */
86894 + e_NetHeaderType nextParse; /**< must be equal or higher than IPv4 */
86895 + } mplsPrsOptions;
86896 + /* VLAN */
86897 + struct {
86898 + uint16_t tagProtocolId1; /**< User defined Tag Protocol Identifier, to be recognized
86899 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86900 + uint16_t tagProtocolId2; /**< User defined Tag Protocol Identifier, to be recognized
86901 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86902 + } vlanPrsOptions;
86903 + /* PPP */
86904 + struct{
86905 + bool enableMTUCheck; /**< Check validity of MTU according to RFC2516 */
86906 + } pppoePrsOptions;
86907 +
86908 + /* IPV6 */
86909 + struct{
86910 + bool routingHdrEnable; /**< TRUE to enable routing header, otherwise ignore */
86911 + } ipv6PrsOptions;
86912 +
86913 + /* UDP */
86914 + struct{
86915 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86916 + } udpPrsOptions;
86917 +
86918 + /* TCP */
86919 + struct {
86920 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86921 + } tcpPrsOptions;
86922 +} u_FmPcdHdrPrsOpts;
86923 +
86924 +/**************************************************************************//**
86925 + @Description A structure for defining each header for the parser
86926 +*//***************************************************************************/
86927 +typedef struct t_FmPcdPrsAdditionalHdrParams {
86928 + e_NetHeaderType hdr; /**< Selected header; use HEADER_TYPE_NONE
86929 + to indicate that sw parser is to run first
86930 + (before HW parser, and independent of the
86931 + existence of any protocol), in this case,
86932 + swPrsEnable must be set, and all other
86933 + parameters are irrelevant. */
86934 + bool errDisable; /**< TRUE to disable error indication */
86935 + bool swPrsEnable; /**< Enable jump to SW parser when this
86936 + header is recognized by the HW parser. */
86937 + uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser
86938 + attachments exists for the same header,
86939 + (in the main sw parser code) use this
86940 + index to distinguish between them. */
86941 + bool usePrsOpts; /**< TRUE to use parser options. */
86942 + u_FmPcdHdrPrsOpts prsOpts; /**< A union according to header type,
86943 + defining the parser options selected.*/
86944 +} t_FmPcdPrsAdditionalHdrParams;
86945 +
86946 +/**************************************************************************//**
86947 + @Description struct for defining port PCD parameters
86948 +*//***************************************************************************/
86949 +typedef struct t_FmPortPcdPrsParams {
86950 + uint8_t prsResultPrivateInfo; /**< The private info provides a method of inserting
86951 + port information into the parser result. This information
86952 + may be extracted by Keygen and be used for frames
86953 + distribution when a per-port distinction is required,
86954 + it may also be used as a port logical id for analyzing
86955 + incoming frames. */
86956 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */
86957 + e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */
86958 + bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics;
86959 + NOTE: this field is not valid when the FM is in "guest" mode
86960 + and IPC is not available. */
86961 + uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get
86962 + special parameters */
86963 + t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS];
86964 + /**< 'numOfHdrsWithAdditionalParams' structures
86965 + of additional parameters
86966 + for each header that requires them */
86967 + bool setVlanTpid1; /**< TRUE to configure user selection of Ethertype to
86968 + indicate a VLAN tag (in addition to the TPID values
86969 + 0x8100 and 0x88A8). */
86970 + uint16_t vlanTpid1; /**< extra tag to use if setVlanTpid1=TRUE. */
86971 + bool setVlanTpid2; /**< TRUE to configure user selection of Ethertype to
86972 + indicate a VLAN tag (in addition to the TPID values
86973 + 0x8100 and 0x88A8). */
86974 + uint16_t vlanTpid2; /**< extra tag to use if setVlanTpid1=TRUE. */
86975 +} t_FmPortPcdPrsParams;
86976 +
86977 +/**************************************************************************//**
86978 + @Description struct for defining coarse alassification parameters
86979 +*//***************************************************************************/
86980 +typedef struct t_FmPortPcdCcParams {
86981 + t_Handle h_CcTree; /**< A handle to a CC tree */
86982 +} t_FmPortPcdCcParams;
86983 +
86984 +/**************************************************************************//**
86985 + @Description struct for defining keygen parameters
86986 +*//***************************************************************************/
86987 +typedef struct t_FmPortPcdKgParams {
86988 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86989 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
86990 + /**< Array of 'numOfSchemes' schemes handles for the
86991 + port to be bound to */
86992 + bool directScheme; /**< TRUE for going from parser to a specific scheme,
86993 + regardless of parser result */
86994 + t_Handle h_DirectScheme; /**< relevant only if direct == TRUE, Scheme handle,
86995 + as returned by FM_PCD_KgSetScheme */
86996 +} t_FmPortPcdKgParams;
86997 +
86998 +/**************************************************************************//**
86999 + @Description struct for defining policer parameters
87000 +*//***************************************************************************/
87001 +typedef struct t_FmPortPcdPlcrParams {
87002 + t_Handle h_Profile; /**< Selected profile handle */
87003 +} t_FmPortPcdPlcrParams;
87004 +
87005 +/**************************************************************************//**
87006 + @Description struct for defining port PCD parameters
87007 +*//***************************************************************************/
87008 +typedef struct t_FmPortPcdParams {
87009 + e_FmPortPcdSupport pcdSupport; /**< Relevant for Rx and offline ports only.
87010 + Describes the active PCD engines for this port. */
87011 + t_Handle h_NetEnv; /**< HL Unused in PLCR only mode */
87012 + t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */
87013 + t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */
87014 + t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */
87015 + t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port; Relevant for one of
87016 + following cases:
87017 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
87018 + e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
87019 + or if any flow uses a KG scheme were policer
87020 + profile is not generated
87021 + ('bypassPlcrProfileGeneration selected'). */
87022 + t_Handle h_IpReassemblyManip; /**< IP Reassembly manipulation */
87023 +#if (DPAA_VERSION >= 11)
87024 + t_Handle h_CapwapReassemblyManip;/**< CAPWAP Reassembly manipulation */
87025 +#endif /* (DPAA_VERSION >= 11) */
87026 +} t_FmPortPcdParams;
87027 +
87028 +/**************************************************************************//**
87029 + @Description A structure for defining the Parser starting point
87030 +*//***************************************************************************/
87031 +typedef struct t_FmPcdPrsStart {
87032 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to
87033 + start parsing */
87034 + e_NetHeaderType firstPrsHdr; /**< The type of the first header axpected at
87035 + 'parsingOffset' */
87036 +} t_FmPcdPrsStart;
87037 +
87038 +#if (DPAA_VERSION >= 11)
87039 +/**************************************************************************//**
87040 + @Description struct for defining external buffer margins
87041 +*//***************************************************************************/
87042 +typedef struct t_FmPortVSPAllocParams {
87043 + uint8_t numOfProfiles; /**< Number of Virtual Storage Profiles; must be a power of 2 */
87044 + uint8_t dfltRelativeId; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
87045 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
87046 + if relevant function called for Rx port */
87047 + t_Handle h_FmTxPort; /**< Handle to coupled Tx Port; not relevant for OP port. */
87048 +} t_FmPortVSPAllocParams;
87049 +#endif /* (DPAA_VERSION >= 11) */
87050 +
87051 +
87052 +/**************************************************************************//**
87053 + @Function FM_PORT_SetPCD
87054 +
87055 + @Description Calling this routine defines the port's PCD configuration.
87056 + It changes it from its default configuration which is PCD
87057 + disabled (BMI to BMI) and configures it according to the passed
87058 + parameters.
87059 +
87060 + May be used for Rx and OP ports only
87061 +
87062 + @Param[in] h_FmPort A handle to a FM Port module.
87063 + @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD
87064 + configuration.
87065 +
87066 + @Return E_OK on success; Error code otherwise.
87067 +
87068 + @Cautions Allowed only following FM_PORT_Init().
87069 +*//***************************************************************************/
87070 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd);
87071 +
87072 +/**************************************************************************//**
87073 + @Function FM_PORT_DeletePCD
87074 +
87075 + @Description Calling this routine releases the port's PCD configuration.
87076 + The port returns to its default configuration which is PCD
87077 + disabled (BMI to BMI) and all PCD configuration is removed.
87078 +
87079 + May be used for Rx and OP ports which are
87080 + in PCD mode only
87081 +
87082 + @Param[in] h_FmPort A handle to a FM Port module.
87083 +
87084 + @Return E_OK on success; Error code otherwise.
87085 +
87086 + @Cautions Allowed only following FM_PORT_Init().
87087 +*//***************************************************************************/
87088 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort);
87089 +
87090 +/**************************************************************************//**
87091 + @Function FM_PORT_AttachPCD
87092 +
87093 + @Description This routine may be called after FM_PORT_DetachPCD was called,
87094 + to return to the originally configured PCD support flow.
87095 + The couple of routines are used to allow PCD configuration changes
87096 + that demand that PCD will not be used while changes take place.
87097 +
87098 + May be used for Rx and OP ports which are
87099 + in PCD mode only
87100 +
87101 + @Param[in] h_FmPort A handle to a FM Port module.
87102 +
87103 + @Return E_OK on success; Error code otherwise.
87104 +
87105 + @Cautions Allowed only following FM_PORT_Init().
87106 +*//***************************************************************************/
87107 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort);
87108 +
87109 +/**************************************************************************//**
87110 + @Function FM_PORT_DetachPCD
87111 +
87112 + @Description Calling this routine detaches the port from its PCD functionality.
87113 + The port returns to its default flow which is BMI to BMI.
87114 +
87115 + May be used for Rx and OP ports which are
87116 + in PCD mode only
87117 +
87118 + @Param[in] h_FmPort A handle to a FM Port module.
87119 +
87120 + @Return E_OK on success; Error code otherwise.
87121 +
87122 + @Cautions Allowed only following FM_PORT_AttachPCD().
87123 +*//***************************************************************************/
87124 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort);
87125 +
87126 +/**************************************************************************//**
87127 + @Function FM_PORT_PcdPlcrAllocProfiles
87128 +
87129 + @Description This routine may be called only for ports that use the Policer in
87130 + order to allocate private policer profiles.
87131 +
87132 + @Param[in] h_FmPort A handle to a FM Port module.
87133 + @Param[in] numOfProfiles The number of required policer profiles
87134 +
87135 + @Return E_OK on success; Error code otherwise.
87136 +
87137 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
87138 + and before FM_PORT_SetPCD().
87139 +*//***************************************************************************/
87140 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles);
87141 +
87142 +/**************************************************************************//**
87143 + @Function FM_PORT_PcdPlcrFreeProfiles
87144 +
87145 + @Description This routine should be called for freeing private policer profiles.
87146 +
87147 + @Param[in] h_FmPort A handle to a FM Port module.
87148 +
87149 + @Return E_OK on success; Error code otherwise.
87150 +
87151 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
87152 + and before FM_PORT_SetPCD().
87153 +*//***************************************************************************/
87154 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort);
87155 +
87156 +#if (DPAA_VERSION >= 11)
87157 +/**************************************************************************//**
87158 + @Function FM_PORT_VSPAlloc
87159 +
87160 + @Description This routine allocated VSPs per port and forces the port to work
87161 + in VSP mode. Note that the port is initialized by default with the
87162 + physical-storage-profile only.
87163 +
87164 + @Param[in] h_FmPort A handle to a FM Port module.
87165 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
87166 +
87167 + @Return E_OK on success; Error code otherwise.
87168 +
87169 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
87170 + and also before FM_PORT_Enable(); i.e. the port should be disabled.
87171 +*//***************************************************************************/
87172 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_Params);
87173 +#endif /* (DPAA_VERSION >= 11) */
87174 +
87175 +/**************************************************************************//**
87176 + @Function FM_PORT_PcdKgModifyInitialScheme
87177 +
87178 + @Description This routine may be called only for ports that use the keygen in
87179 + order to change the initial scheme frame should be routed to.
87180 + The change may be of a scheme id (in case of direct mode),
87181 + from direct to indirect, or from indirect to direct - specifying the scheme id.
87182 +
87183 + @Param[in] h_FmPort A handle to a FM Port module.
87184 + @Param[in] p_FmPcdKgScheme A structure of parameters for defining whether
87185 + a scheme is direct/indirect, and if direct - scheme id.
87186 +
87187 + @Return E_OK on success; Error code otherwise.
87188 +
87189 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87190 +*//***************************************************************************/
87191 +t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme);
87192 +
87193 +/**************************************************************************//**
87194 + @Function FM_PORT_PcdPlcrModifyInitialProfile
87195 +
87196 + @Description This routine may be called for ports with flows
87197 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR
87198 + only, to change the initial Policer profile frame should be
87199 + routed to. The change may be of a profile and/or absolute/direct
87200 + mode selection.
87201 +
87202 + @Param[in] h_FmPort A handle to a FM Port module.
87203 + @Param[in] h_Profile Policer profile handle
87204 +
87205 + @Return E_OK on success; Error code otherwise.
87206 +
87207 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87208 +*//***************************************************************************/
87209 +t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile);
87210 +
87211 +/**************************************************************************//**
87212 + @Function FM_PORT_PcdCcModifyTree
87213 +
87214 + @Description This routine may be called for ports that use coarse classification tree
87215 + if the user wishes to replace the tree. The routine may not be called while port
87216 + receives packets using the PCD functionalities, therefor port must be first detached
87217 + from the PCD, only than the routine may be called, and than port be attached to PCD again.
87218 +
87219 + @Param[in] h_FmPort A handle to a FM Port module.
87220 + @Param[in] h_CcTree A CC tree that was already built. The tree id as returned from
87221 + the BuildTree routine.
87222 +
87223 + @Return E_OK on success; Error code otherwise.
87224 +
87225 + @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetachPCD()
87226 +*//***************************************************************************/
87227 +t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree);
87228 +
87229 +/**************************************************************************//**
87230 + @Function FM_PORT_PcdKgBindSchemes
87231 +
87232 + @Description These routines may be called for adding more schemes for the
87233 + port to be bound to. The selected schemes are not added,
87234 + just this specific port starts using them.
87235 +
87236 + @Param[in] h_FmPort A handle to a FM Port module.
87237 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
87238 +
87239 + @Return E_OK on success; Error code otherwise.
87240 +
87241 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87242 +*//***************************************************************************/
87243 +t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
87244 +
87245 +/**************************************************************************//**
87246 + @Function FM_PORT_PcdKgUnbindSchemes
87247 +
87248 + @Description These routines may be called for adding more schemes for the
87249 + port to be bound to. The selected schemes are not removed or invalidated,
87250 + just this specific port stops using them.
87251 +
87252 + @Param[in] h_FmPort A handle to a FM Port module.
87253 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
87254 +
87255 + @Return E_OK on success; Error code otherwise.
87256 +
87257 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87258 +*//***************************************************************************/
87259 +t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
87260 +
87261 +/**************************************************************************//**
87262 + @Function FM_PORT_GetIPv4OptionsCount
87263 +
87264 + @Description TODO
87265 +
87266 + @Param[in] h_FmPort A handle to a FM Port module.
87267 + @Param[out] p_Ipv4OptionsCount will hold the counter value
87268 +
87269 + @Return E_OK on success; Error code otherwise.
87270 +
87271 + @Cautions Allowed only following FM_PORT_Init()
87272 +*//***************************************************************************/
87273 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCount);
87274 +
87275 +/** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */
87276 +/** @} */ /* end of FM_PORT_runtime_control_grp group */
87277 +
87278 +
87279 +/**************************************************************************//**
87280 + @Group FM_PORT_runtime_data_grp FM Port Runtime Data-path Unit
87281 +
87282 + @Description FM Port Runtime data unit API functions, definitions and enums.
87283 + This API is valid only if working in Independent-Mode.
87284 +
87285 + @{
87286 +*//***************************************************************************/
87287 +
87288 +/**************************************************************************//**
87289 + @Function FM_PORT_ImTx
87290 +
87291 + @Description Tx function, called to transmit a data buffer on the port.
87292 +
87293 + @Param[in] h_FmPort A handle to a FM Port module.
87294 + @Param[in] p_Data A pointer to an LCP data buffer.
87295 + @Param[in] length Size of data for transmission.
87296 + @Param[in] lastBuffer Buffer position - TRUE for the last buffer
87297 + of a frame, including a single buffer frame
87298 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
87299 +
87300 + @Return E_OK on success; Error code otherwise.
87301 +
87302 + @Cautions Allowed only following FM_PORT_Init().
87303 + NOTE - This routine can be used only when working in
87304 + Independent-Mode mode.
87305 +*//***************************************************************************/
87306 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
87307 + uint8_t *p_Data,
87308 + uint16_t length,
87309 + bool lastBuffer,
87310 + t_Handle h_BufContext);
87311 +
87312 +/**************************************************************************//**
87313 + @Function FM_PORT_ImTxConf
87314 +
87315 + @Description Tx port confirmation routine, optional, may be called to verify
87316 + transmission of all frames. The procedure performed by this
87317 + routine will be performed automatically on next buffer transmission,
87318 + but if desired, calling this routine will invoke this action on
87319 + demand.
87320 +
87321 + @Param[in] h_FmPort A handle to a FM Port module.
87322 +
87323 + @Cautions Allowed only following FM_PORT_Init().
87324 + NOTE - This routine can be used only when working in
87325 + Independent-Mode mode.
87326 +*//***************************************************************************/
87327 +void FM_PORT_ImTxConf(t_Handle h_FmPort);
87328 +
87329 +/**************************************************************************//**
87330 + @Function FM_PORT_ImRx
87331 +
87332 + @Description Rx function, may be called to poll for received buffers.
87333 + Normally, Rx process is invoked by the driver on Rx interrupt.
87334 + Alternatively, this routine may be called on demand.
87335 +
87336 + @Param[in] h_FmPort A handle to a FM Port module.
87337 +
87338 + @Return E_OK on success; Error code otherwise.
87339 +
87340 + @Cautions Allowed only following FM_PORT_Init().
87341 + NOTE - This routine can be used only when working in
87342 + Independent-Mode mode.
87343 +*//***************************************************************************/
87344 +t_Error FM_PORT_ImRx(t_Handle h_FmPort);
87345 +
87346 +/** @} */ /* end of FM_PORT_runtime_data_grp group */
87347 +/** @} */ /* end of FM_PORT_grp group */
87348 +/** @} */ /* end of FM_grp group */
87349 +
87350 +
87351 +
87352 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
87353 +#define FM_PORT_ConfigTxFifoDeqPipelineDepth FM_PORT_ConfigFifoDeqPipelineDepth
87354 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
87355 +
87356 +
87357 +#endif /* __FM_PORT_EXT */
87358 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
87359 new file mode 100644
87360 index 00000000..72078ac4
87361 --- /dev/null
87362 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
87363 @@ -0,0 +1,619 @@
87364 +/*
87365 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87366 + *
87367 + * Redistribution and use in source and binary forms, with or without
87368 + * modification, are permitted provided that the following conditions are met:
87369 + * * Redistributions of source code must retain the above copyright
87370 + * notice, this list of conditions and the following disclaimer.
87371 + * * Redistributions in binary form must reproduce the above copyright
87372 + * notice, this list of conditions and the following disclaimer in the
87373 + * documentation and/or other materials provided with the distribution.
87374 + * * Neither the name of Freescale Semiconductor nor the
87375 + * names of its contributors may be used to endorse or promote products
87376 + * derived from this software without specific prior written permission.
87377 + *
87378 + *
87379 + * ALTERNATIVELY, this software may be distributed under the terms of the
87380 + * GNU General Public License ("GPL") as published by the Free Software
87381 + * Foundation, either version 2 of that License or (at your option) any
87382 + * later version.
87383 + *
87384 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87385 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87386 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87387 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87388 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87389 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87390 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87391 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87392 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87393 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87394 + */
87395 +
87396 +
87397 +/**************************************************************************//**
87398 + @File fm_rtc_ext.h
87399 +
87400 + @Description External definitions and API for FM RTC IEEE1588 Timer Module.
87401 +
87402 + @Cautions None.
87403 +*//***************************************************************************/
87404 +
87405 +#ifndef __FM_RTC_EXT_H__
87406 +#define __FM_RTC_EXT_H__
87407 +
87408 +
87409 +#include "error_ext.h"
87410 +#include "std_ext.h"
87411 +#include "fsl_fman_rtc.h"
87412 +
87413 +/**************************************************************************//**
87414 +
87415 + @Group FM_grp Frame Manager API
87416 +
87417 + @Description FM API functions, definitions and enums
87418 +
87419 + @{
87420 +*//***************************************************************************/
87421 +
87422 +/**************************************************************************//**
87423 + @Group fm_rtc_grp FM RTC
87424 +
87425 + @Description FM RTC functions, definitions and enums.
87426 +
87427 + @{
87428 +*//***************************************************************************/
87429 +
87430 +/**************************************************************************//**
87431 + @Group fm_rtc_init_grp FM RTC Initialization Unit
87432 +
87433 + @Description FM RTC initialization API.
87434 +
87435 + @{
87436 +*//***************************************************************************/
87437 +
87438 +/**************************************************************************//**
87439 + @Description FM RTC Alarm Polarity Options.
87440 +*//***************************************************************************/
87441 +typedef enum e_FmRtcAlarmPolarity
87442 +{
87443 + e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
87444 + e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
87445 +} e_FmRtcAlarmPolarity;
87446 +
87447 +/**************************************************************************//**
87448 + @Description FM RTC Trigger Polarity Options.
87449 +*//***************************************************************************/
87450 +typedef enum e_FmRtcTriggerPolarity
87451 +{
87452 + e_FM_RTC_TRIGGER_ON_RISING_EDGE = E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
87453 + e_FM_RTC_TRIGGER_ON_FALLING_EDGE = E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
87454 +} e_FmRtcTriggerPolarity;
87455 +
87456 +/**************************************************************************//**
87457 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
87458 +*//***************************************************************************/
87459 +typedef enum e_FmSrcClock
87460 +{
87461 + e_FM_RTC_SOURCE_CLOCK_EXTERNAL = E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */
87462 + e_FM_RTC_SOURCE_CLOCK_SYSTEM = E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
87463 + e_FM_RTC_SOURCE_CLOCK_OSCILATOR = E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
87464 +}e_FmSrcClk;
87465 +
87466 +/**************************************************************************//**
87467 + @Description FM RTC configuration parameters structure.
87468 +
87469 + This structure should be passed to FM_RTC_Config().
87470 +*//***************************************************************************/
87471 +typedef struct t_FmRtcParams
87472 +{
87473 + t_Handle h_Fm; /**< FM Handle*/
87474 + uintptr_t baseAddress; /**< Base address of FM RTC registers */
87475 + t_Handle h_App; /**< A handle to an application layer object; This handle will
87476 + be passed by the driver upon calling the above callbacks */
87477 +} t_FmRtcParams;
87478 +
87479 +
87480 +/**************************************************************************//**
87481 + @Function FM_RTC_Config
87482 +
87483 + @Description Configures the FM RTC module according to user's parameters.
87484 +
87485 + The driver assigns default values to some FM RTC parameters.
87486 + These parameters can be overwritten using the advanced
87487 + configuration routines.
87488 +
87489 + @Param[in] p_FmRtcParam - FM RTC configuration parameters.
87490 +
87491 + @Return Handle to the new FM RTC object; NULL pointer on failure.
87492 +
87493 + @Cautions None
87494 +*//***************************************************************************/
87495 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam);
87496 +
87497 +/**************************************************************************//**
87498 + @Function FM_RTC_Init
87499 +
87500 + @Description Initializes the FM RTC driver and hardware.
87501 +
87502 + @Param[in] h_FmRtc - Handle to FM RTC object.
87503 +
87504 + @Return E_OK on success; Error code otherwise.
87505 +
87506 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87507 +*//***************************************************************************/
87508 +t_Error FM_RTC_Init(t_Handle h_FmRtc);
87509 +
87510 +/**************************************************************************//**
87511 + @Function FM_RTC_Free
87512 +
87513 + @Description Frees the FM RTC object and all allocated resources.
87514 +
87515 + @Param[in] h_FmRtc - Handle to FM RTC object.
87516 +
87517 + @Return E_OK on success; Error code otherwise.
87518 +
87519 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87520 +*//***************************************************************************/
87521 +t_Error FM_RTC_Free(t_Handle h_FmRtc);
87522 +
87523 +
87524 +/**************************************************************************//**
87525 + @Group fm_rtc_adv_config_grp FM RTC Advanced Configuration Unit
87526 +
87527 + @Description FM RTC advanced configuration functions.
87528 +
87529 + @{
87530 +*//***************************************************************************/
87531 +
87532 +/**************************************************************************//**
87533 + @Function FM_RTC_ConfigPeriod
87534 +
87535 + @Description Configures the period of the timestamp if different than
87536 + default [DEFAULT_clockPeriod].
87537 +
87538 + @Param[in] h_FmRtc - Handle to FM RTC object.
87539 + @Param[in] period - Period in nano-seconds.
87540 +
87541 + @Return E_OK on success; Error code otherwise.
87542 +
87543 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87544 +*//***************************************************************************/
87545 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period);
87546 +
87547 +/**************************************************************************//**
87548 + @Function FM_RTC_ConfigSourceClock
87549 +
87550 + @Description Configures the source clock of the RTC.
87551 +
87552 + @Param[in] h_FmRtc - Handle to FM RTC object.
87553 + @Param[in] srcClk - Source clock selection.
87554 + @Param[in] freqInMhz - the source-clock frequency (in MHz).
87555 +
87556 + @Return E_OK on success; Error code otherwise.
87557 +
87558 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87559 +*//***************************************************************************/
87560 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
87561 + e_FmSrcClk srcClk,
87562 + uint32_t freqInMhz);
87563 +
87564 +/**************************************************************************//**
87565 + @Function FM_RTC_ConfigPulseRealignment
87566 +
87567 + @Description Configures the RTC to automatic FIPER pulse realignment in
87568 + response to timer adjustments [DEFAULT_pulseRealign]
87569 +
87570 + In this mode, the RTC clock is identical to the source clock.
87571 + This feature can be useful when the system contains an external
87572 + RTC with inherent frequency compensation.
87573 +
87574 + @Param[in] h_FmRtc - Handle to FM RTC object.
87575 + @Param[in] enable - TRUE to enable automatic realignment.
87576 +
87577 + @Return E_OK on success; Error code otherwise.
87578 +
87579 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87580 +*//***************************************************************************/
87581 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable);
87582 +
87583 +/**************************************************************************//**
87584 + @Function FM_RTC_ConfigFrequencyBypass
87585 +
87586 + @Description Configures the RTC to bypass the frequency compensation
87587 + mechanism. [DEFAULT_bypass]
87588 +
87589 + In this mode, the RTC clock is identical to the source clock.
87590 + This feature can be useful when the system contains an external
87591 + RTC with inherent frequency compensation.
87592 +
87593 + @Param[in] h_FmRtc - Handle to FM RTC object.
87594 + @Param[in] enabled - TRUE to bypass frequency compensation;
87595 + FALSE otherwise.
87596 +
87597 + @Return E_OK on success; Error code otherwise.
87598 +
87599 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87600 +*//***************************************************************************/
87601 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled);
87602 +
87603 +/**************************************************************************//**
87604 + @Function FM_RTC_ConfigInvertedInputClockPhase
87605 +
87606 + @Description Configures the RTC to invert the source clock phase on input.
87607 + [DEFAULT_invertInputClkPhase]
87608 +
87609 + @Param[in] h_FmRtc - Handle to FM RTC object.
87610 + @Param[in] inverted - TRUE to invert the source clock phase on input.
87611 + FALSE otherwise.
87612 +
87613 + @Return E_OK on success; Error code otherwise.
87614 +
87615 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87616 +*//***************************************************************************/
87617 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted);
87618 +
87619 +/**************************************************************************//**
87620 + @Function FM_RTC_ConfigInvertedOutputClockPhase
87621 +
87622 + @Description Configures the RTC to invert the output clock phase.
87623 + [DEFAULT_invertOutputClkPhase]
87624 +
87625 + @Param[in] h_FmRtc - Handle to FM RTC object.
87626 + @Param[in] inverted - TRUE to invert the output clock phase.
87627 + FALSE otherwise.
87628 +
87629 + @Return E_OK on success; Error code otherwise.
87630 +
87631 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87632 +*//***************************************************************************/
87633 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted);
87634 +
87635 +/**************************************************************************//**
87636 + @Function FM_RTC_ConfigOutputClockDivisor
87637 +
87638 + @Description Configures the divisor for generating the output clock from
87639 + the RTC clock. [DEFAULT_outputClockDivisor]
87640 +
87641 + @Param[in] h_FmRtc - Handle to FM RTC object.
87642 + @Param[in] divisor - Divisor for generation of the output clock.
87643 +
87644 + @Return E_OK on success; Error code otherwise.
87645 +
87646 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87647 +*//***************************************************************************/
87648 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor);
87649 +
87650 +/**************************************************************************//**
87651 + @Function FM_RTC_ConfigAlarmPolarity
87652 +
87653 + @Description Configures the polarity (active-high/active-low) of a specific
87654 + alarm signal. [DEFAULT_alarmPolarity]
87655 +
87656 + @Param[in] h_FmRtc - Handle to FM RTC object.
87657 + @Param[in] alarmId - Alarm ID.
87658 + @Param[in] alarmPolarity - Alarm polarity.
87659 +
87660 + @Return E_OK on success; Error code otherwise.
87661 +
87662 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87663 +*//***************************************************************************/
87664 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
87665 + uint8_t alarmId,
87666 + e_FmRtcAlarmPolarity alarmPolarity);
87667 +
87668 +/**************************************************************************//**
87669 + @Function FM_RTC_ConfigExternalTriggerPolarity
87670 +
87671 + @Description Configures the polarity (rising/falling edge) of a specific
87672 + external trigger signal. [DEFAULT_triggerPolarity]
87673 +
87674 + @Param[in] h_FmRtc - Handle to FM RTC object.
87675 + @Param[in] triggerId - Trigger ID.
87676 + @Param[in] triggerPolarity - Trigger polarity.
87677 +
87678 + @Return E_OK on success; Error code otherwise.
87679 +
87680 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87681 +*//***************************************************************************/
87682 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
87683 + uint8_t triggerId,
87684 + e_FmRtcTriggerPolarity triggerPolarity);
87685 +
87686 +/** @} */ /* end of fm_rtc_adv_config_grp */
87687 +/** @} */ /* end of fm_rtc_init_grp */
87688 +
87689 +
87690 +/**************************************************************************//**
87691 + @Group fm_rtc_control_grp FM RTC Control Unit
87692 +
87693 + @Description FM RTC runtime control API.
87694 +
87695 + @{
87696 +*//***************************************************************************/
87697 +
87698 +/**************************************************************************//**
87699 + @Function t_FmRtcExceptionsCallback
87700 +
87701 + @Description Exceptions user callback routine, used for RTC different mechanisms.
87702 +
87703 + @Param[in] h_App - User's application descriptor.
87704 + @Param[in] id - source id.
87705 +*//***************************************************************************/
87706 +typedef void (t_FmRtcExceptionsCallback) ( t_Handle h_App, uint8_t id);
87707 +
87708 +/**************************************************************************//**
87709 + @Description FM RTC alarm parameters.
87710 +*//***************************************************************************/
87711 +typedef struct t_FmRtcAlarmParams {
87712 + uint8_t alarmId; /**< 0 or 1 */
87713 + uint64_t alarmTime; /**< In nanoseconds, the time when the alarm
87714 + should go off - must be a multiple of
87715 + the RTC period */
87716 + t_FmRtcExceptionsCallback *f_AlarmCallback; /**< This routine will be called when RTC
87717 + reaches alarmTime */
87718 + bool clearOnExpiration; /**< TRUE to turn off the alarm once expired. */
87719 +} t_FmRtcAlarmParams;
87720 +
87721 +/**************************************************************************//**
87722 + @Description FM RTC Periodic Pulse parameters.
87723 +*//***************************************************************************/
87724 +typedef struct t_FmRtcPeriodicPulseParams {
87725 + uint8_t periodicPulseId; /**< 0 or 1 */
87726 + uint64_t periodicPulsePeriod; /**< In Nanoseconds. Must be
87727 + a multiple of the RTC period */
87728 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; /**< This routine will be called every
87729 + periodicPulsePeriod. */
87730 +} t_FmRtcPeriodicPulseParams;
87731 +
87732 +/**************************************************************************//**
87733 + @Description FM RTC Periodic Pulse parameters.
87734 +*//***************************************************************************/
87735 +typedef struct t_FmRtcExternalTriggerParams {
87736 + uint8_t externalTriggerId; /**< 0 or 1 */
87737 + bool usePulseAsInput; /**< Use the pulse interrupt instead of
87738 + an external signal */
87739 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; /**< This routine will be called every
87740 + periodicPulsePeriod. */
87741 +} t_FmRtcExternalTriggerParams;
87742 +
87743 +
87744 +/**************************************************************************//**
87745 + @Function FM_RTC_Enable
87746 +
87747 + @Description Enable the RTC (time count is started).
87748 +
87749 + The user can select to resume the time count from previous
87750 + point, or to restart the time count.
87751 +
87752 + @Param[in] h_FmRtc - Handle to FM RTC object.
87753 + @Param[in] resetClock - Restart the time count from zero.
87754 +
87755 + @Return E_OK on success; Error code otherwise.
87756 +
87757 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87758 +*//***************************************************************************/
87759 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock);
87760 +
87761 +/**************************************************************************//**
87762 + @Function FM_RTC_Disable
87763 +
87764 + @Description Disables the RTC (time count is stopped).
87765 +
87766 + @Param[in] h_FmRtc - Handle to FM RTC object.
87767 +
87768 + @Return E_OK on success; Error code otherwise.
87769 +
87770 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87771 +*//***************************************************************************/
87772 +t_Error FM_RTC_Disable(t_Handle h_FmRtc);
87773 +
87774 +/**************************************************************************//**
87775 + @Function FM_RTC_SetClockOffset
87776 +
87777 + @Description Sets the clock offset (usually relative to another clock).
87778 +
87779 + The user can pass a negative offset value.
87780 +
87781 + @Param[in] h_FmRtc - Handle to FM RTC object.
87782 + @Param[in] offset - New clock offset (in nanoseconds).
87783 +
87784 + @Return E_OK on success; Error code otherwise.
87785 +
87786 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87787 +*//***************************************************************************/
87788 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset);
87789 +
87790 +/**************************************************************************//**
87791 + @Function FM_RTC_SetAlarm
87792 +
87793 + @Description Schedules an alarm event to a given RTC time.
87794 +
87795 + @Param[in] h_FmRtc - Handle to FM RTC object.
87796 + @Param[in] p_FmRtcAlarmParams - Alarm parameters.
87797 +
87798 + @Return E_OK on success; Error code otherwise.
87799 +
87800 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87801 + Must be called only prior to FM_RTC_Enable().
87802 +*//***************************************************************************/
87803 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams);
87804 +
87805 +/**************************************************************************//**
87806 + @Function FM_RTC_SetPeriodicPulse
87807 +
87808 + @Description Sets a periodic pulse.
87809 +
87810 + @Param[in] h_FmRtc - Handle to FM RTC object.
87811 + @Param[in] p_FmRtcPeriodicPulseParams - Periodic pulse parameters.
87812 +
87813 + @Return E_OK on success; Error code otherwise.
87814 +
87815 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87816 + Must be called only prior to FM_RTC_Enable().
87817 +*//***************************************************************************/
87818 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams);
87819 +
87820 +/**************************************************************************//**
87821 + @Function FM_RTC_ClearPeriodicPulse
87822 +
87823 + @Description Clears a periodic pulse.
87824 +
87825 + @Param[in] h_FmRtc - Handle to FM RTC object.
87826 + @Param[in] periodicPulseId - Periodic pulse id.
87827 +
87828 + @Return E_OK on success; Error code otherwise.
87829 +
87830 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87831 +*//***************************************************************************/
87832 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId);
87833 +
87834 +/**************************************************************************//**
87835 + @Function FM_RTC_SetExternalTrigger
87836 +
87837 + @Description Sets an external trigger indication and define a callback
87838 + routine to be called on such event.
87839 +
87840 + @Param[in] h_FmRtc - Handle to FM RTC object.
87841 + @Param[in] p_FmRtcExternalTriggerParams - External Trigger parameters.
87842 +
87843 + @Return E_OK on success; Error code otherwise.
87844 +
87845 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87846 +*//***************************************************************************/
87847 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams);
87848 +
87849 +/**************************************************************************//**
87850 + @Function FM_RTC_ClearExternalTrigger
87851 +
87852 + @Description Clears external trigger indication.
87853 +
87854 + @Param[in] h_FmRtc - Handle to FM RTC object.
87855 + @Param[in] id - External Trigger id.
87856 +
87857 + @Return E_OK on success; Error code otherwise.
87858 +
87859 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87860 +*//***************************************************************************/
87861 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t id);
87862 +
87863 +/**************************************************************************//**
87864 + @Function FM_RTC_GetExternalTriggerTimeStamp
87865 +
87866 + @Description Reads the External Trigger TimeStamp.
87867 +
87868 + @Param[in] h_FmRtc - Handle to FM RTC object.
87869 + @Param[in] triggerId - External Trigger id.
87870 + @Param[out] p_TimeStamp - External Trigger timestamp (in nanoseconds).
87871 +
87872 + @Return E_OK on success; Error code otherwise.
87873 +
87874 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87875 +*//***************************************************************************/
87876 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
87877 + uint8_t triggerId,
87878 + uint64_t *p_TimeStamp);
87879 +
87880 +/**************************************************************************//**
87881 + @Function FM_RTC_GetCurrentTime
87882 +
87883 + @Description Returns the current RTC time.
87884 +
87885 + @Param[in] h_FmRtc - Handle to FM RTC object.
87886 + @Param[out] p_Ts - returned time stamp (in nanoseconds).
87887 +
87888 + @Return E_OK on success; Error code otherwise.
87889 +
87890 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87891 +*//***************************************************************************/
87892 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts);
87893 +
87894 +/**************************************************************************//**
87895 + @Function FM_RTC_SetCurrentTime
87896 +
87897 + @Description Sets the current RTC time.
87898 +
87899 + @Param[in] h_FmRtc - Handle to FM RTC object.
87900 + @Param[in] ts - The new time stamp (in nanoseconds).
87901 +
87902 + @Return E_OK on success; Error code otherwise.
87903 +
87904 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87905 +*//***************************************************************************/
87906 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts);
87907 +
87908 +/**************************************************************************//**
87909 + @Function FM_RTC_GetFreqCompensation
87910 +
87911 + @Description Retrieves the frequency compensation value
87912 +
87913 + @Param[in] h_FmRtc - Handle to FM RTC object.
87914 + @Param[out] p_Compensation - A pointer to the returned value of compensation.
87915 +
87916 + @Return E_OK on success; Error code otherwise.
87917 +
87918 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87919 +*//***************************************************************************/
87920 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation);
87921 +
87922 +/**************************************************************************//**
87923 + @Function FM_RTC_SetFreqCompensation
87924 +
87925 + @Description Sets a new frequency compensation value.
87926 +
87927 + @Param[in] h_FmRtc - Handle to FM RTC object.
87928 + @Param[in] freqCompensation - The new frequency compensation value to set.
87929 +
87930 + @Return E_OK on success; Error code otherwise.
87931 +
87932 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87933 +*//***************************************************************************/
87934 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation);
87935 +
87936 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
87937 +/**************************************************************************//**
87938 +*@Function FM_RTC_EnableInterrupt
87939 +*
87940 +*@Description Enable interrupt of FM RTC.
87941 +*
87942 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87943 +*@Param[in] events - Interrupt events.
87944 +*
87945 +*@Return E_OK on success; Error code otherwise.
87946 +*//***************************************************************************/
87947 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events);
87948 +
87949 +/**************************************************************************//**
87950 +*@Function FM_RTC_DisableInterrupt
87951 +*
87952 +*@Description Disable interrupt of FM RTC.
87953 +*
87954 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87955 +*@Param[in] events - Interrupt events.
87956 +*
87957 +*@Return E_OK on success; Error code otherwise.
87958 +*//***************************************************************************/
87959 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events);
87960 +#endif
87961 +
87962 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
87963 +/**************************************************************************//**
87964 + @Function FM_RTC_DumpRegs
87965 +
87966 + @Description Dumps all FM registers
87967 +
87968 + @Param[in] h_FmRtc A handle to an FM RTC Module.
87969 +
87970 + @Return E_OK on success;
87971 +
87972 + @Cautions Allowed only FM_Init().
87973 +*//***************************************************************************/
87974 +t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc);
87975 +#endif /* (defined(DEBUG_ERRORS) && ... */
87976 +
87977 +/** @} */ /* end of fm_rtc_control_grp */
87978 +/** @} */ /* end of fm_rtc_grp */
87979 +/** @} */ /* end of FM_grp group */
87980 +
87981 +
87982 +#endif /* __FM_RTC_EXT_H__ */
87983 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
87984 new file mode 100644
87985 index 00000000..f9aed036
87986 --- /dev/null
87987 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
87988 @@ -0,0 +1,411 @@
87989 +/*
87990 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87991 + *
87992 + * Redistribution and use in source and binary forms, with or without
87993 + * modification, are permitted provided that the following conditions are met:
87994 + * * Redistributions of source code must retain the above copyright
87995 + * notice, this list of conditions and the following disclaimer.
87996 + * * Redistributions in binary form must reproduce the above copyright
87997 + * notice, this list of conditions and the following disclaimer in the
87998 + * documentation and/or other materials provided with the distribution.
87999 + * * Neither the name of Freescale Semiconductor nor the
88000 + * names of its contributors may be used to endorse or promote products
88001 + * derived from this software without specific prior written permission.
88002 + *
88003 + *
88004 + * ALTERNATIVELY, this software may be distributed under the terms of the
88005 + * GNU General Public License ("GPL") as published by the Free Software
88006 + * Foundation, either version 2 of that License or (at your option) any
88007 + * later version.
88008 + *
88009 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88010 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88011 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88012 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88013 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88014 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88015 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88016 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88017 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88018 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88019 + */
88020 +
88021 +
88022 +/**************************************************************************//**
88023 + @File fm_vsp_ext.h
88024 +
88025 + @Description FM Virtual Storage-Profile ...
88026 +*//***************************************************************************/
88027 +#ifndef __FM_VSP_EXT_H
88028 +#define __FM_VSP_EXT_H
88029 +
88030 +#include "std_ext.h"
88031 +#include "error_ext.h"
88032 +#include "string_ext.h"
88033 +#include "debug_ext.h"
88034 +
88035 +#include "fm_ext.h"
88036 +
88037 +
88038 +/**************************************************************************//**
88039 +
88040 + @Group FM_grp Frame Manager API
88041 +
88042 + @Description FM API functions, definitions and enums
88043 +
88044 + @{
88045 +*//***************************************************************************/
88046 +
88047 +/**************************************************************************//**
88048 + @Group FM_VSP_grp FM Virtual-Storage-Profile
88049 +
88050 + @Description FM Virtual-Storage-Profile API
88051 +
88052 + @{
88053 +*//***************************************************************************/
88054 +
88055 +/**************************************************************************//**
88056 + @Group FM_VSP_init_grp FM VSP Initialization Unit
88057 +
88058 + @Description FM VSP initialization API.
88059 +
88060 + @{
88061 +*//***************************************************************************/
88062 +
88063 +/**************************************************************************//**
88064 + @Description Virtual Storage Profile
88065 +*//***************************************************************************/
88066 +typedef struct t_FmVspParams {
88067 + t_Handle h_Fm; /**< A handle to the FM object this VSP related to */
88068 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
88069 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
88070 + parameter associated with Rx / OP port */
88071 + uint16_t liodnOffset; /**< VSP's LIODN offset */
88072 + struct {
88073 + e_FmPortType portType; /**< Port type */
88074 + uint8_t portId; /**< Port Id - relative to type */
88075 + } portParams;
88076 + uint8_t relativeProfileId; /**< VSP Id - relative to VSP's range
88077 + defined in relevant FM object */
88078 +} t_FmVspParams;
88079 +
88080 +
88081 +/**************************************************************************//**
88082 + @Function FM_VSP_Config
88083 +
88084 + @Description Creates descriptor for the FM VSP module.
88085 +
88086 + The routine returns a handle (descriptor) to the FM VSP object.
88087 + This descriptor must be passed as first parameter to all other
88088 + FM VSP function calls.
88089 +
88090 + No actual initialization or configuration of FM hardware is
88091 + done by this routine.
88092 +
88093 +@Param[in] p_FmVspParams Pointer to data structure of parameters
88094 +
88095 + @Retval Handle to FM VSP object, or NULL for Failure.
88096 +*//***************************************************************************/
88097 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams);
88098 +
88099 +/**************************************************************************//**
88100 + @Function FM_VSP_Init
88101 +
88102 + @Description Initializes the FM VSP module
88103 +
88104 + @Param[in] h_FmVsp - FM VSP module descriptor
88105 +
88106 + @Return E_OK on success; Error code otherwise.
88107 +*//***************************************************************************/
88108 +t_Error FM_VSP_Init(t_Handle h_FmVsp);
88109 +
88110 +/**************************************************************************//**
88111 + @Function FM_VSP_Free
88112 +
88113 + @Description Frees all resources that were assigned to FM VSP module.
88114 +
88115 + Calling this routine invalidates the descriptor.
88116 +
88117 + @Param[in] h_FmVsp - FM VSP module descriptor
88118 +
88119 + @Return E_OK on success; Error code otherwise.
88120 +*//***************************************************************************/
88121 +t_Error FM_VSP_Free(t_Handle h_FmVsp);
88122 +
88123 +
88124 +/**************************************************************************//**
88125 + @Group FM_VSP_adv_config_grp FM VSP Advanced Configuration Unit
88126 +
88127 + @Description FM VSP advanced configuration functions.
88128 +
88129 + @{
88130 +*//***************************************************************************/
88131 +
88132 +/**************************************************************************//**
88133 + @Function FM_VSP_ConfigBufferPrefixContent
88134 +
88135 + @Description Defines the structure, size and content of the application buffer.
88136 +
88137 + The prefix will
88138 + In VSPs defined for Tx ports, if 'passPrsResult', the application
88139 + should set a value to their offsets in the prefix of
88140 + the FM will save the first 'privDataSize', than,
88141 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
88142 + and timeStamp, and the packet itself (in this order), to the
88143 + application buffer, and to offset.
88144 +
88145 + Calling this routine changes the buffer margins definitions
88146 + in the internal driver data base from its default
88147 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
88148 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
88149 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
88150 +
88151 + @Param[in] h_FmVsp A handle to a FM VSP module.
88152 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
88153 + structure of the buffer.
88154 + Out parameter: Start margin - offset
88155 + of data from start of external buffer.
88156 +
88157 + @Return E_OK on success; Error code otherwise.
88158 +
88159 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88160 +*//***************************************************************************/
88161 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp,
88162 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
88163 +
88164 +/**************************************************************************//**
88165 + @Function FM_VSP_ConfigDmaSwapData
88166 +
88167 + @Description Calling this routine changes the DMA swap data parameter
88168 + in the internal driver data base from its default
88169 + configuration [DEFAULT_FM_SP_dmaSwapData]
88170 +
88171 + @Param[in] h_FmVsp A handle to a FM VSP module.
88172 + @Param[in] swapData New selection
88173 +
88174 + @Return E_OK on success; Error code otherwise.
88175 +
88176 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88177 +*//***************************************************************************/
88178 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData);
88179 +
88180 +/**************************************************************************//**
88181 + @Function FM_VSP_ConfigDmaIcCacheAttr
88182 +
88183 + @Description Calling this routine changes the internal context cache
88184 + attribute parameter in the internal driver data base
88185 + from its default configuration [DEFAULT_FM_SP_dmaIntContextCacheAttr]
88186 +
88187 + @Param[in] h_FmVsp A handle to a FM VSP module.
88188 + @Param[in] intContextCacheAttr New selection
88189 +
88190 + @Return E_OK on success; Error code otherwise.
88191 +
88192 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88193 +*//***************************************************************************/
88194 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp,
88195 + e_FmDmaCacheOption intContextCacheAttr);
88196 +
88197 +/**************************************************************************//**
88198 + @Function FM_VSP_ConfigDmaHdrAttr
88199 +
88200 + @Description Calling this routine changes the header cache
88201 + attribute parameter in the internal driver data base
88202 + from its default configuration [DEFAULT_FM_SP_dmaHeaderCacheAttr]
88203 +
88204 + @Param[in] h_FmVsp A handle to a FM VSP module.
88205 + @Param[in] headerCacheAttr New selection
88206 +
88207 + @Return E_OK on success; Error code otherwise.
88208 +
88209 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88210 +*//***************************************************************************/
88211 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr);
88212 +
88213 +/**************************************************************************//**
88214 + @Function FM_VSP_ConfigDmaScatterGatherAttr
88215 +
88216 + @Description Calling this routine changes the scatter gather cache
88217 + attribute parameter in the internal driver data base
88218 + from its default configuration [DEFAULT_FM_SP_dmaScatterGatherCacheAttr]
88219 +
88220 + @Param[in] h_FmVsp A handle to a FM VSP module.
88221 + @Param[in] scatterGatherCacheAttr New selection
88222 +
88223 + @Return E_OK on success; Error code otherwise.
88224 +
88225 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88226 +*//***************************************************************************/
88227 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp,
88228 + e_FmDmaCacheOption scatterGatherCacheAttr);
88229 +
88230 +/**************************************************************************//**
88231 + @Function FM_VSP_ConfigDmaWriteOptimize
88232 +
88233 + @Description Calling this routine changes the write optimization
88234 + parameter in the internal driver data base
88235 + from its default configuration: optimize = [DEFAULT_FM_SP_dmaWriteOptimize]
88236 +
88237 + @Param[in] h_FmVsp A handle to a FM VSP module.
88238 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
88239 +
88240 + @Return E_OK on success; Error code otherwise.
88241 +
88242 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88243 +*//***************************************************************************/
88244 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize);
88245 +
88246 +/**************************************************************************//**
88247 + @Function FM_VSP_ConfigNoScatherGather
88248 +
88249 + @Description Calling this routine changes the possibility to receive S/G frame
88250 + in the internal driver data base
88251 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
88252 +
88253 + @Param[in] h_FmVsp A handle to a FM VSP module.
88254 + @Param[in] noScatherGather TRUE to operate without scatter/gather capability.
88255 +
88256 + @Return E_OK on success; Error code otherwise.
88257 +
88258 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88259 +*//***************************************************************************/
88260 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather);
88261 +
88262 +/**************************************************************************//**
88263 + @Function FM_VSP_ConfigPoolDepletion
88264 +
88265 + @Description Calling this routine enables pause frame generation depending on the
88266 + depletion status of BM pools. It also defines the conditions to activate
88267 + this functionality. By default, this functionality is disabled.
88268 +
88269 + @Param[in] h_FmVsp A handle to a FM VSP module.
88270 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
88271 +
88272 + @Return E_OK on success; Error code otherwise.
88273 +
88274 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88275 +*//***************************************************************************/
88276 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion);
88277 +
88278 +/**************************************************************************//**
88279 + @Function FM_VSP_ConfigBackupPools
88280 +
88281 + @Description Calling this routine allows the configuration of some of the BM pools
88282 + defined for this port as backup pools.
88283 + A pool configured to be a backup pool will be used only if all other
88284 + enabled non-backup pools are depleted.
88285 +
88286 + @Param[in] h_FmVsp A handle to a FM VSP module.
88287 + @Param[in] p_BackupBmPools An array of pool id's. All pools specified here will
88288 + be defined as backup pools.
88289 +
88290 + @Return E_OK on success; Error code otherwise.
88291 +
88292 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88293 +*//***************************************************************************/
88294 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools);
88295 +
88296 +/** @} */ /* end of FM_VSP_adv_config_grp group */
88297 +/** @} */ /* end of FM_VSP_init_grp group */
88298 +
88299 +
88300 +/**************************************************************************//**
88301 + @Group FM_VSP_control_grp FM VSP Control Unit
88302 +
88303 + @Description FM VSP runtime control API.
88304 +
88305 + @{
88306 +*//***************************************************************************/
88307 +
88308 +/**************************************************************************//**
88309 + @Function FM_VSP_GetBufferDataOffset
88310 +
88311 + @Description Relevant for Rx ports.
88312 + Returns the data offset from the beginning of the data buffer
88313 +
88314 + @Param[in] h_FmVsp - FM PORT module descriptor
88315 +
88316 + @Return data offset.
88317 +
88318 + @Cautions Allowed only following FM_VSP_Init().
88319 +*//***************************************************************************/
88320 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp);
88321 +
88322 +/**************************************************************************//**
88323 + @Function FM_VSP_GetBufferICInfo
88324 +
88325 + @Description Returns the Internal Context offset from the beginning of the data buffer
88326 +
88327 + @Param[in] h_FmVsp - FM PORT module descriptor
88328 + @Param[in] p_Data - A pointer to the data buffer.
88329 +
88330 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
88331 + configured for this port.
88332 +
88333 + @Cautions Allowed only following FM_VSP_Init().
88334 +*//***************************************************************************/
88335 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data);
88336 +
88337 +/**************************************************************************//**
88338 + @Function FM_VSP_GetBufferPrsResult
88339 +
88340 + @Description Returns the pointer to the parse result in the data buffer.
88341 + In Rx ports this is relevant after reception, if parse
88342 + result is configured to be part of the data passed to the
88343 + application. For non Rx ports it may be used to get the pointer
88344 + of the area in the buffer where parse result should be
88345 + initialized - if so configured.
88346 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
88347 + configuration.
88348 +
88349 + @Param[in] h_FmVsp - FM PORT module descriptor
88350 + @Param[in] p_Data - A pointer to the data buffer.
88351 +
88352 + @Return Parse result pointer on success, NULL if parse result was not
88353 + configured for this port.
88354 +
88355 + @Cautions Allowed only following FM_VSP_Init().
88356 +*//***************************************************************************/
88357 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data);
88358 +
88359 +/**************************************************************************//**
88360 + @Function FM_VSP_GetBufferTimeStamp
88361 +
88362 + @Description Returns the time stamp in the data buffer.
88363 + Relevant for Rx ports for getting the buffer time stamp.
88364 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
88365 + configuration.
88366 +
88367 + @Param[in] h_FmVsp - FM PORT module descriptor
88368 + @Param[in] p_Data - A pointer to the data buffer.
88369 +
88370 + @Return A pointer to the hash result on success, NULL otherwise.
88371 +
88372 + @Cautions Allowed only following FM_VSP_Init().
88373 +*//***************************************************************************/
88374 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data);
88375 +
88376 +/**************************************************************************//**
88377 + @Function FM_VSP_GetBufferHashResult
88378 +
88379 + @Description Given a data buffer, on the condition that hash result was defined
88380 + as a part of the buffer content (see FM_VSP_ConfigBufferPrefixContent)
88381 + this routine will return the pointer to the hash result location in the
88382 + buffer prefix.
88383 +
88384 + @Param[in] h_FmVsp - FM PORT module descriptor
88385 + @Param[in] p_Data - A pointer to the data buffer.
88386 +
88387 + @Return A pointer to the hash result on success, NULL otherwise.
88388 +
88389 + @Cautions Allowed only following FM_VSP_Init().
88390 +*//***************************************************************************/
88391 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data);
88392 +
88393 +
88394 +/** @} */ /* end of FM_VSP_control_grp group */
88395 +/** @} */ /* end of FM_VSP_grp group */
88396 +/** @} */ /* end of FM_grp group */
88397 +
88398 +
88399 +#endif /* __FM_VSP_EXT_H */
88400 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
88401 new file mode 100644
88402 index 00000000..f635d3c2
88403 --- /dev/null
88404 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
88405 @@ -0,0 +1,76 @@
88406 +/*
88407 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88408 + *
88409 + * Redistribution and use in source and binary forms, with or without
88410 + * modification, are permitted provided that the following conditions are met:
88411 + * * Redistributions of source code must retain the above copyright
88412 + * notice, this list of conditions and the following disclaimer.
88413 + * * Redistributions in binary form must reproduce the above copyright
88414 + * notice, this list of conditions and the following disclaimer in the
88415 + * documentation and/or other materials provided with the distribution.
88416 + * * Neither the name of Freescale Semiconductor nor the
88417 + * names of its contributors may be used to endorse or promote products
88418 + * derived from this software without specific prior written permission.
88419 + *
88420 + *
88421 + * ALTERNATIVELY, this software may be distributed under the terms of the
88422 + * GNU General Public License ("GPL") as published by the Free Software
88423 + * Foundation, either version 2 of that License or (at your option) any
88424 + * later version.
88425 + *
88426 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88427 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88428 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88429 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88430 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88431 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88432 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88433 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88434 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88435 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88436 + */
88437 +
88438 +
88439 +
88440 +#ifndef __MII_ACC_EXT_H
88441 +#define __MII_ACC_EXT_H
88442 +
88443 +
88444 +/**************************************************************************//**
88445 + @Function MII_ReadPhyReg
88446 +
88447 + @Description This routine is called to read a specified PHY
88448 + register value.
88449 +
88450 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
88451 + @Param[in] phyAddr - PHY address (0-31).
88452 + @Param[in] reg - PHY register to read
88453 + @Param[out] p_Data - Gets the register value.
88454 +
88455 + @Return Always zero (success).
88456 +*//***************************************************************************/
88457 +int MII_ReadPhyReg(t_Handle h_MiiAccess,
88458 + uint8_t phyAddr,
88459 + uint8_t reg,
88460 + uint16_t *p_Data);
88461 +
88462 +/**************************************************************************//**
88463 + @Function MII_WritePhyReg
88464 +
88465 + @Description This routine is called to write data to a specified PHY
88466 + register.
88467 +
88468 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
88469 + @Param[in] phyAddr - PHY address (0-31).
88470 + @Param[in] reg - PHY register to write
88471 + @Param[in] data - Data to write in register.
88472 +
88473 + @Return Always zero (success).
88474 +*//***************************************************************************/
88475 +int MII_WritePhyReg(t_Handle h_MiiAccess,
88476 + uint8_t phyAddr,
88477 + uint8_t reg,
88478 + uint16_t data);
88479 +
88480 +
88481 +#endif /* __MII_ACC_EXT_H */
88482 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
88483 new file mode 100644
88484 index 00000000..ec89a6dd
88485 --- /dev/null
88486 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
88487 @@ -0,0 +1,90 @@
88488 +/*
88489 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88490 + *
88491 + * Redistribution and use in source and binary forms, with or without
88492 + * modification, are permitted provided that the following conditions are met:
88493 + * * Redistributions of source code must retain the above copyright
88494 + * notice, this list of conditions and the following disclaimer.
88495 + * * Redistributions in binary form must reproduce the above copyright
88496 + * notice, this list of conditions and the following disclaimer in the
88497 + * documentation and/or other materials provided with the distribution.
88498 + * * Neither the name of Freescale Semiconductor nor the
88499 + * names of its contributors may be used to endorse or promote products
88500 + * derived from this software without specific prior written permission.
88501 + *
88502 + *
88503 + * ALTERNATIVELY, this software may be distributed under the terms of the
88504 + * GNU General Public License ("GPL") as published by the Free Software
88505 + * Foundation, either version 2 of that License or (at your option) any
88506 + * later version.
88507 + *
88508 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88509 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88510 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88511 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88512 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88513 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88514 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88515 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88516 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88517 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88518 + */
88519 +
88520 +
88521 +/**************************************************************************//**
88522 + @File core_ext.h
88523 +
88524 + @Description Generic interface to basic core operations.
88525 +
88526 + The system integrator must ensure that this interface is
88527 + mapped to a specific core implementation, by including the
88528 + appropriate header file.
88529 +*//***************************************************************************/
88530 +#ifndef __CORE_EXT_H
88531 +#define __CORE_EXT_H
88532 +
88533 +#ifdef CONFIG_FMAN_ARM
88534 +#include "arm_ext.h"
88535 +#include <linux/smp.h>
88536 +#else
88537 +#ifdef NCSW_PPC_CORE
88538 +#include "ppc_ext.h"
88539 +#elif defined(NCSW_VXWORKS)
88540 +#include "core_vxw_ext.h"
88541 +#else
88542 +#error "Core is not defined!"
88543 +#endif /* NCSW_CORE */
88544 +
88545 +#if (!defined(CORE_IS_LITTLE_ENDIAN) && !defined(CORE_IS_BIG_ENDIAN))
88546 +#error "Must define core as little-endian or big-endian!"
88547 +#endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */
88548 +
88549 +#ifndef CORE_CACHELINE_SIZE
88550 +#error "Must define the core cache-line size!"
88551 +#endif /* !CORE_CACHELINE_SIZE */
88552 +
88553 +#endif /* CONFIG_FMAN_ARM */
88554 +
88555 +
88556 +/**************************************************************************//**
88557 + @Function CORE_GetId
88558 +
88559 + @Description Returns the core ID in the system.
88560 +
88561 + @Return Core ID.
88562 +*//***************************************************************************/
88563 +uint32_t CORE_GetId(void);
88564 +
88565 +/**************************************************************************//**
88566 + @Function CORE_MemoryBarrier
88567 +
88568 + @Description This routine will cause the core to stop executing any commands
88569 + until all previous memory read/write commands are completely out
88570 + of the core's pipeline.
88571 +
88572 + @Return None.
88573 +*//***************************************************************************/
88574 +void CORE_MemoryBarrier(void);
88575 +#define fsl_mem_core_barrier() CORE_MemoryBarrier()
88576 +
88577 +#endif /* __CORE_EXT_H */
88578 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
88579 new file mode 100644
88580 index 00000000..e63444a7
88581 --- /dev/null
88582 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
88583 @@ -0,0 +1,55 @@
88584 +/*
88585 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88586 + *
88587 + * Redistribution and use in source and binary forms, with or without
88588 + * modification, are permitted provided that the following conditions are met:
88589 + * * Redistributions of source code must retain the above copyright
88590 + * notice, this list of conditions and the following disclaimer.
88591 + * * Redistributions in binary form must reproduce the above copyright
88592 + * notice, this list of conditions and the following disclaimer in the
88593 + * documentation and/or other materials provided with the distribution.
88594 + * * Neither the name of Freescale Semiconductor nor the
88595 + * names of its contributors may be used to endorse or promote products
88596 + * derived from this software without specific prior written permission.
88597 + *
88598 + *
88599 + * ALTERNATIVELY, this software may be distributed under the terms of the
88600 + * GNU General Public License ("GPL") as published by the Free Software
88601 + * Foundation, either version 2 of that License or (at your option) any
88602 + * later version.
88603 + *
88604 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88605 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88606 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88607 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88608 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88609 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88610 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88611 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88612 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88613 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88614 + */
88615 +
88616 +
88617 +/**************************************************************************//**
88618 + @File arm_ext.h
88619 +
88620 + @Description Core API for ARM cores
88621 +
88622 + These routines must be implemented by each specific PowerPC
88623 + core driver.
88624 +*//***************************************************************************/
88625 +#ifndef __ARM_EXT_H
88626 +#define __ARM_EXT_H
88627 +
88628 +#include "part_ext.h"
88629 +
88630 +
88631 +#define CORE_IS_LITTLE_ENDIAN
88632 +
88633 +static __inline__ void CORE_MemoryBarrier(void)
88634 +{
88635 + mb();
88636 +}
88637 +
88638 +#endif /* __PPC_EXT_H */
88639 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
88640 new file mode 100644
88641 index 00000000..e79b1ddf
88642 --- /dev/null
88643 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
88644 @@ -0,0 +1,476 @@
88645 +/*
88646 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88647 + *
88648 + * Redistribution and use in source and binary forms, with or without
88649 + * modification, are permitted provided that the following conditions are met:
88650 + * * Redistributions of source code must retain the above copyright
88651 + * notice, this list of conditions and the following disclaimer.
88652 + * * Redistributions in binary form must reproduce the above copyright
88653 + * notice, this list of conditions and the following disclaimer in the
88654 + * documentation and/or other materials provided with the distribution.
88655 + * * Neither the name of Freescale Semiconductor nor the
88656 + * names of its contributors may be used to endorse or promote products
88657 + * derived from this software without specific prior written permission.
88658 + *
88659 + *
88660 + * ALTERNATIVELY, this software may be distributed under the terms of the
88661 + * GNU General Public License ("GPL") as published by the Free Software
88662 + * Foundation, either version 2 of that License or (at your option) any
88663 + * later version.
88664 + *
88665 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88666 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88667 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88668 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88669 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88670 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88671 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88672 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88673 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88674 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88675 + */
88676 +
88677 +
88678 +/**************************************************************************//**
88679 + @File e500v2_ext.h
88680 +
88681 + @Description E500 external definitions prototypes
88682 + This file is not included by the E500
88683 + source file as it is an assembly file. It is used
88684 + only for prototypes exposure, for inclusion
88685 + by user and other modules.
88686 +*//***************************************************************************/
88687 +
88688 +#ifndef __E500V2_EXT_H
88689 +#define __E500V2_EXT_H
88690 +
88691 +#include "std_ext.h"
88692 +
88693 +
88694 +/* Layer 1 Cache Manipulations
88695 + *==============================
88696 + * Should not be called directly by the user.
88697 + */
88698 +void L1DCache_Invalidate (void);
88699 +void L1ICache_Invalidate(void);
88700 +void L1DCache_Enable(void);
88701 +void L1ICache_Enable(void);
88702 +void L1DCache_Disable(void);
88703 +void L1ICache_Disable(void);
88704 +void L1DCache_Flush(void);
88705 +void L1ICache_Flush(void);
88706 +uint32_t L1ICache_IsEnabled(void);
88707 +uint32_t L1DCache_IsEnabled(void);
88708 +/*
88709 + *
88710 + */
88711 +uint32_t L1DCache_LineLock(uint32_t addr);
88712 +uint32_t L1ICache_LineLock(uint32_t addr);
88713 +void L1Cache_BroadCastEnable(void);
88714 +void L1Cache_BroadCastDisable(void);
88715 +
88716 +
88717 +#define CORE_DCacheEnable E500_DCacheEnable
88718 +#define CORE_ICacheEnable E500_ICacheEnable
88719 +#define CORE_DCacheDisable E500_DCacheDisable
88720 +#define CORE_ICacheDisable E500_ICacheDisable
88721 +#define CORE_GetId E500_GetId
88722 +#define CORE_TestAndSet E500_TestAndSet
88723 +#define CORE_MemoryBarrier E500_MemoryBarrier
88724 +#define CORE_InstructionSync E500_InstructionSync
88725 +
88726 +#define CORE_SetDozeMode E500_SetDozeMode
88727 +#define CORE_SetNapMode E500_SetNapMode
88728 +#define CORE_SetSleepMode E500_SetSleepMode
88729 +#define CORE_SetJogMode E500_SetJogMode
88730 +#define CORE_SetDeepSleepMode E500_SetDeepSleepMode
88731 +
88732 +#define CORE_RecoverDozeMode E500_RecoverDozeMode
88733 +#define CORE_RecoverNapMode E500_RecoverNapMode
88734 +#define CORE_RecoverSleepMode E500_RecoverSleepMode
88735 +#define CORE_RecoverJogMode E500_RecoverJogMode
88736 +
88737 +void E500_SetDozeMode(void);
88738 +void E500_SetNapMode(void);
88739 +void E500_SetSleepMode(void);
88740 +void E500_SetJogMode(void);
88741 +t_Error E500_SetDeepSleepMode(uint32_t bptrAddress);
88742 +
88743 +void E500_RecoverDozeMode(void);
88744 +void E500_RecoverNapMode(void);
88745 +void E500_RecoverSleepMode(void);
88746 +void E500_RecoverJogMode(void);
88747 +
88748 +
88749 +/**************************************************************************//**
88750 + @Group E500_id E500 Application Programming Interface
88751 +
88752 + @Description E500 API functions, definitions and enums
88753 +
88754 + @{
88755 +*//***************************************************************************/
88756 +
88757 +/**************************************************************************//**
88758 + @Group E500_init_grp E500 Initialization Unit
88759 +
88760 + @Description E500 initialization unit API functions, definitions and enums
88761 +
88762 + @{
88763 +*//***************************************************************************/
88764 +
88765 +
88766 +/**************************************************************************//**
88767 + @Function E500_DCacheEnable
88768 +
88769 + @Description Enables the data cache for memory pages that are
88770 + not cache inhibited.
88771 +
88772 + @Return None.
88773 +*//***************************************************************************/
88774 +void E500_DCacheEnable(void);
88775 +
88776 +/**************************************************************************//**
88777 + @Function E500_ICacheEnable
88778 +
88779 + @Description Enables the instruction cache for memory pages that are
88780 + not cache inhibited.
88781 +
88782 + @Return None.
88783 +*//***************************************************************************/
88784 +void E500_ICacheEnable(void);
88785 +
88786 +/**************************************************************************//**
88787 + @Function E500_DCacheDisable
88788 +
88789 + @Description Disables the data cache.
88790 +
88791 + @Return None.
88792 +*//***************************************************************************/
88793 +void E500_DCacheDisable(void);
88794 +
88795 +/**************************************************************************//**
88796 + @Function E500_ICacheDisable
88797 +
88798 + @Description Disables the instruction cache.
88799 +
88800 + @Return None.
88801 +*//***************************************************************************/
88802 +void E500_ICacheDisable(void);
88803 +
88804 +/**************************************************************************//**
88805 + @Function E500_DCacheFlush
88806 +
88807 + @Description Flushes the data cache
88808 +
88809 + @Return None.
88810 +*//***************************************************************************/
88811 +void E500_DCacheFlush(void);
88812 +
88813 +/**************************************************************************//**
88814 + @Function E500_ICacheFlush
88815 +
88816 + @Description Flushes the instruction cache.
88817 +
88818 + @Return None.
88819 +*//***************************************************************************/
88820 +void E500_ICacheFlush(void);
88821 +
88822 +/**************************************************************************//**
88823 + @Function E500_DCacheSetStashId
88824 +
88825 + @Description Set Stash Id for data cache
88826 +
88827 + @Param[in] stashId the stash id to be set.
88828 +
88829 + @Return None.
88830 +*//***************************************************************************/
88831 +void E500_DCacheSetStashId(uint8_t stashId);
88832 +
88833 +/**************************************************************************//**
88834 + @Description E500mc L2 Cache Operation Mode
88835 +*//***************************************************************************/
88836 +typedef enum e_E500mcL2CacheMode
88837 +{
88838 + e_L2_CACHE_MODE_DATA_ONLY = 0x00000001, /**< Cache data only */
88839 + e_L2_CACHE_MODE_INST_ONLY = 0x00000002, /**< Cache instructions only */
88840 + e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */
88841 +} e_E500mcL2CacheMode;
88842 +
88843 +#if defined(CORE_E500MC) || defined(CORE_E5500)
88844 +/**************************************************************************//**
88845 + @Function E500_L2CacheEnable
88846 +
88847 + @Description Enables the cache for memory pages that are not cache inhibited.
88848 +
88849 + @param[in] mode - L2 cache mode: data only, instruction only or instruction and data.
88850 +
88851 + @Return None.
88852 +
88853 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88854 + not possible to call this routine for i-cache and than to call
88855 + again for d-cache; The second call will override the first one.
88856 +*//***************************************************************************/
88857 +void E500_L2CacheEnable(e_E500mcL2CacheMode mode);
88858 +
88859 +/**************************************************************************//**
88860 + @Function E500_L2CacheDisable
88861 +
88862 + @Description Disables the cache (data instruction or both).
88863 +
88864 + @Return None.
88865 +
88866 +*//***************************************************************************/
88867 +void E500_L2CacheDisable(void);
88868 +
88869 +/**************************************************************************//**
88870 + @Function E500_L2CacheFlush
88871 +
88872 + @Description Flushes the cache.
88873 +
88874 + @Return None.
88875 +*//***************************************************************************/
88876 +void E500_L2CacheFlush(void);
88877 +
88878 +/**************************************************************************//**
88879 + @Function E500_L2SetStashId
88880 +
88881 + @Description Set Stash Id
88882 +
88883 + @Param[in] stashId the stash id to be set.
88884 +
88885 + @Return None.
88886 +*//***************************************************************************/
88887 +void E500_L2SetStashId(uint8_t stashId);
88888 +#endif /* defined(CORE_E500MC) || defined(CORE_E5500) */
88889 +
88890 +#ifdef CORE_E6500
88891 +/**************************************************************************//**
88892 + @Function E6500_L2CacheEnable
88893 +
88894 + @Description Enables the cache for memory pages that are not cache inhibited.
88895 +
88896 + @param[in] mode - L2 cache mode: support data & instruction only.
88897 +
88898 + @Return None.
88899 +
88900 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88901 + not possible to call this routine for i-cache and than to call
88902 + again for d-cache; The second call will override the first one.
88903 +*//***************************************************************************/
88904 +void E6500_L2CacheEnable(uintptr_t clusterBase);
88905 +
88906 +/**************************************************************************//**
88907 + @Function E6500_L2CacheDisable
88908 +
88909 + @Description Disables the cache (data instruction or both).
88910 +
88911 + @Return None.
88912 +
88913 +*//***************************************************************************/
88914 +void E6500_L2CacheDisable(uintptr_t clusterBase);
88915 +
88916 +/**************************************************************************//**
88917 + @Function E6500_L2CacheFlush
88918 +
88919 + @Description Flushes the cache.
88920 +
88921 + @Return None.
88922 +*//***************************************************************************/
88923 +void E6500_L2CacheFlush(uintptr_t clusterBase);
88924 +
88925 +/**************************************************************************//**
88926 + @Function E6500_L2SetStashId
88927 +
88928 + @Description Set Stash Id
88929 +
88930 + @Param[in] stashId the stash id to be set.
88931 +
88932 + @Return None.
88933 +*//***************************************************************************/
88934 +void E6500_L2SetStashId(uintptr_t clusterBase, uint8_t stashId);
88935 +
88936 +/**************************************************************************//**
88937 + @Function E6500_GetCcsrBase
88938 +
88939 + @Description Obtain SoC CCSR base address
88940 +
88941 + @Param[in] None.
88942 +
88943 + @Return Physical CCSR base address.
88944 +*//***************************************************************************/
88945 +physAddress_t E6500_GetCcsrBase(void);
88946 +#endif /* CORE_E6500 */
88947 +
88948 +/**************************************************************************//**
88949 + @Function E500_AddressBusStreamingEnable
88950 +
88951 + @Description Enables address bus streaming on the CCB.
88952 +
88953 + This setting, along with the ECM streaming configuration
88954 + parameters, enables address bus streaming on the CCB.
88955 +
88956 + @Return None.
88957 +*//***************************************************************************/
88958 +void E500_AddressBusStreamingEnable(void);
88959 +
88960 +/**************************************************************************//**
88961 + @Function E500_AddressBusStreamingDisable
88962 +
88963 + @Description Disables address bus streaming on the CCB.
88964 +
88965 + @Return None.
88966 +*//***************************************************************************/
88967 +void E500_AddressBusStreamingDisable(void);
88968 +
88969 +/**************************************************************************//**
88970 + @Function E500_AddressBroadcastEnable
88971 +
88972 + @Description Enables address broadcast.
88973 +
88974 + The e500 broadcasts cache management instructions (dcbst, dcblc
88975 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88976 + based on ABE. ABE must be set to allow management of external
88977 + L2 caches.
88978 +
88979 + @Return None.
88980 +*//***************************************************************************/
88981 +void E500_AddressBroadcastEnable(void);
88982 +
88983 +/**************************************************************************//**
88984 + @Function E500_AddressBroadcastDisable
88985 +
88986 + @Description Disables address broadcast.
88987 +
88988 + The e500 broadcasts cache management instructions (dcbst, dcblc
88989 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88990 + based on ABE. ABE must be set to allow management of external
88991 + L2 caches.
88992 +
88993 + @Return None.
88994 +*//***************************************************************************/
88995 +void E500_AddressBroadcastDisable(void);
88996 +
88997 +/**************************************************************************//**
88998 + @Function E500_IsTaskletSupported
88999 +
89000 + @Description Checks if tasklets are supported by the e500 interrupt handler.
89001 +
89002 + @Retval TRUE - Tasklets are supported.
89003 + @Retval FALSE - Tasklets are not supported.
89004 +*//***************************************************************************/
89005 +bool E500_IsTaskletSupported(void);
89006 +
89007 +void E500_EnableTimeBase(void);
89008 +void E500_DisableTimeBase(void);
89009 +
89010 +uint64_t E500_GetTimeBaseTime(void);
89011 +
89012 +void E500_GenericIntrInit(void);
89013 +
89014 +t_Error E500_SetIntr(int ppcIntrSrc,
89015 + void (* Isr)(t_Handle handle),
89016 + t_Handle handle);
89017 +
89018 +t_Error E500_ClearIntr(int ppcIntrSrc);
89019 +
89020 +/**************************************************************************//**
89021 + @Function E500_GenericIntrHandler
89022 +
89023 + @Description This is the general e500 interrupt handler.
89024 +
89025 + It is called by the main assembly interrupt handler
89026 + when an exception occurs and no other function has been
89027 + assigned to this exception.
89028 +
89029 + @Param intrEntry - (In) The exception interrupt vector entry.
89030 +*//***************************************************************************/
89031 +void E500_GenericIntrHandler(uint32_t intrEntry);
89032 +
89033 +/**************************************************************************//**
89034 + @Function CriticalIntr
89035 +
89036 + @Description This is the specific critical e500 interrupt handler.
89037 +
89038 + It is called by the main assembly interrupt handler
89039 + when an critical interrupt.
89040 +
89041 + @Param intrEntry - (In) The exception interrupt vector entry.
89042 +*//***************************************************************************/
89043 +void CriticalIntr(uint32_t intrEntry);
89044 +
89045 +
89046 +/**************************************************************************//**
89047 + @Function E500_GetId
89048 +
89049 + @Description Returns the core ID in the system.
89050 +
89051 + @Return Core ID.
89052 +*//***************************************************************************/
89053 +uint32_t E500_GetId(void);
89054 +
89055 +/**************************************************************************//**
89056 + @Function E500_TestAndSet
89057 +
89058 + @Description This routine tries to atomically test-and-set an integer
89059 + in memory to a non-zero value.
89060 +
89061 + The memory will be set only if it is tested as zero, in which
89062 + case the routine returns the new non-zero value; otherwise the
89063 + routine returns zero.
89064 +
89065 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
89066 + operation should be made.
89067 +
89068 + @Retval Zero - Operation failed - memory was already set.
89069 + @Retval Non-zero - Operation succeeded - memory has been set.
89070 +*//***************************************************************************/
89071 +int E500_TestAndSet(volatile int *p);
89072 +
89073 +/**************************************************************************//**
89074 + @Function E500_MemoryBarrier
89075 +
89076 + @Description This routine will cause the core to stop executing any commands
89077 + until all previous memory read/write commands are completely out
89078 + of the core's pipeline.
89079 +
89080 + @Return None.
89081 +*//***************************************************************************/
89082 +static __inline__ void E500_MemoryBarrier(void)
89083 +{
89084 +#ifndef CORE_E500V2
89085 + __asm__ ("mbar 1");
89086 +#else /* CORE_E500V2 */
89087 + /**** ERRATA WORK AROUND START ****/
89088 + /* ERRATA num: CPU1 */
89089 + /* Description: "mbar MO = 1" instruction fails to order caching-inhibited
89090 + guarded loads and stores. */
89091 +
89092 + /* "msync" instruction is used instead */
89093 +
89094 + __asm__ ("msync");
89095 +
89096 + /**** ERRATA WORK AROUND END ****/
89097 +#endif /* CORE_E500V2 */
89098 +}
89099 +
89100 +/**************************************************************************//**
89101 + @Function E500_InstructionSync
89102 +
89103 + @Description This routine will cause the core to wait for previous instructions
89104 + (including any interrupts they generate) to complete before the
89105 + synchronization command executes, which purges all instructions
89106 + from the processor's pipeline and refetches the next instruction.
89107 +
89108 + @Return None.
89109 +*//***************************************************************************/
89110 +static __inline__ void E500_InstructionSync(void)
89111 +{
89112 + __asm__ ("isync");
89113 +}
89114 +
89115 +
89116 +/** @} */ /* end of E500_init_grp group */
89117 +/** @} */ /* end of E500_grp group */
89118 +
89119 +
89120 +#endif /* __E500V2_EXT_H */
89121 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
89122 new file mode 100644
89123 index 00000000..9344b3a1
89124 --- /dev/null
89125 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
89126 @@ -0,0 +1,141 @@
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 +
89160 +/**************************************************************************//**
89161 + @File ppc_ext.h
89162 +
89163 + @Description Core API for PowerPC cores
89164 +
89165 + These routines must be implemented by each specific PowerPC
89166 + core driver.
89167 +*//***************************************************************************/
89168 +#ifndef __PPC_EXT_H
89169 +#define __PPC_EXT_H
89170 +
89171 +#include "part_ext.h"
89172 +
89173 +
89174 +#define CORE_IS_BIG_ENDIAN
89175 +
89176 +#if defined(CORE_E300) || defined(CORE_E500V2)
89177 +#define CORE_CACHELINE_SIZE 32
89178 +#elif defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
89179 +#define CORE_CACHELINE_SIZE 64
89180 +#else
89181 +#error "Core not defined!"
89182 +#endif /* defined(CORE_E300) || ... */
89183 +
89184 +
89185 +/**************************************************************************//**
89186 + @Function CORE_TestAndSet
89187 +
89188 + @Description This routine tries to atomically test-and-set an integer
89189 + in memory to a non-zero value.
89190 +
89191 + The memory will be set only if it is tested as zero, in which
89192 + case the routine returns the new non-zero value; otherwise the
89193 + routine returns zero.
89194 +
89195 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
89196 + operation should be made.
89197 +
89198 + @Retval Zero - Operation failed - memory was already set.
89199 + @Retval Non-zero - Operation succeeded - memory has been set.
89200 +*//***************************************************************************/
89201 +int CORE_TestAndSet(volatile int *p);
89202 +
89203 +/**************************************************************************//**
89204 + @Function CORE_InstructionSync
89205 +
89206 + @Description This routine will cause the core to wait for previous instructions
89207 + (including any interrupts they generate) to complete before the
89208 + synchronization command executes, which purges all instructions
89209 + from the processor's pipeline and refetches the next instruction.
89210 +
89211 + @Return None.
89212 +*//***************************************************************************/
89213 +void CORE_InstructionSync(void);
89214 +
89215 +/**************************************************************************//**
89216 + @Function CORE_DCacheEnable
89217 +
89218 + @Description Enables the data cache for memory pages that are
89219 + not cache inhibited.
89220 +
89221 + @Return None.
89222 +*//***************************************************************************/
89223 +void CORE_DCacheEnable(void);
89224 +
89225 +/**************************************************************************//**
89226 + @Function CORE_ICacheEnable
89227 +
89228 + @Description Enables the instruction cache for memory pages that are
89229 + not cache inhibited.
89230 +
89231 + @Return None.
89232 +*//***************************************************************************/
89233 +void CORE_ICacheEnable(void);
89234 +
89235 +/**************************************************************************//**
89236 + @Function CORE_DCacheDisable
89237 +
89238 + @Description Disables the data cache.
89239 +
89240 + @Return None.
89241 +*//***************************************************************************/
89242 +void CORE_DCacheDisable(void);
89243 +
89244 +/**************************************************************************//**
89245 + @Function CORE_ICacheDisable
89246 +
89247 + @Description Disables the instruction cache.
89248 +
89249 + @Return None.
89250 +*//***************************************************************************/
89251 +void CORE_ICacheDisable(void);
89252 +
89253 +
89254 +
89255 +#if defined(CORE_E300)
89256 +#include "e300_ext.h"
89257 +#elif defined(CORE_E500V2) || defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
89258 +#include "e500v2_ext.h"
89259 +#if !defined(NCSW_LINUX)
89260 +#include "e500v2_asm_ext.h"
89261 +#endif
89262 +#else
89263 +#error "Core not defined!"
89264 +#endif
89265 +
89266 +
89267 +#endif /* __PPC_EXT_H */
89268 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
89269 new file mode 100644
89270 index 00000000..8bb343fc
89271 --- /dev/null
89272 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
89273 @@ -0,0 +1,77 @@
89274 +/*
89275 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89276 + *
89277 + * Redistribution and use in source and binary forms, with or without
89278 + * modification, are permitted provided that the following conditions are met:
89279 + * * Redistributions of source code must retain the above copyright
89280 + * notice, this list of conditions and the following disclaimer.
89281 + * * Redistributions in binary form must reproduce the above copyright
89282 + * notice, this list of conditions and the following disclaimer in the
89283 + * documentation and/or other materials provided with the distribution.
89284 + * * Neither the name of Freescale Semiconductor nor the
89285 + * names of its contributors may be used to endorse or promote products
89286 + * derived from this software without specific prior written permission.
89287 + *
89288 + *
89289 + * ALTERNATIVELY, this software may be distributed under the terms of the
89290 + * GNU General Public License ("GPL") as published by the Free Software
89291 + * Foundation, either version 2 of that License or (at your option) any
89292 + * later version.
89293 + *
89294 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89295 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89296 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89297 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89298 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89299 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89300 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89301 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89302 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89303 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89304 + */
89305 +
89306 +#ifndef __DDR_SDT_EXT_H
89307 +#define __DDR_SDT_EXT_H
89308 +
89309 +
89310 +/**************************************************************************//**
89311 + @Group ddr_Generic_Resources
89312 +
89313 + @Description ddr generic functions, definitions and enums.
89314 +
89315 + @{
89316 +*//***************************************************************************/
89317 +
89318 +
89319 +/**************************************************************************//**
89320 + @Description SPD maximum size
89321 +*//***************************************************************************/
89322 +#define SPD_MAX_SIZE 256
89323 +
89324 +/**************************************************************************//**
89325 + @Description DDR types select
89326 +*//***************************************************************************/
89327 +typedef enum e_DdrType
89328 +{
89329 + e_DDR_DDR1,
89330 + e_DDR_DDR2,
89331 + e_DDR_DDR3,
89332 + e_DDR_DDR3L,
89333 + e_DDR_DDR4
89334 +} e_DdrType;
89335 +
89336 +/**************************************************************************//**
89337 + @Description DDR Mode.
89338 +*//***************************************************************************/
89339 +typedef enum e_DdrMode
89340 +{
89341 + e_DDR_BUS_WIDTH_32BIT,
89342 + e_DDR_BUS_WIDTH_64BIT
89343 +} e_DdrMode;
89344 +
89345 +/** @} */ /* end of ddr_Generic_Resources group */
89346 +
89347 +
89348 +
89349 +#endif /* __DDR_SDT_EXT_H */
89350 +
89351 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
89352 new file mode 100644
89353 index 00000000..57db0a14
89354 --- /dev/null
89355 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
89356 @@ -0,0 +1,233 @@
89357 +/*
89358 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89359 + *
89360 + * Redistribution and use in source and binary forms, with or without
89361 + * modification, are permitted provided that the following conditions are met:
89362 + * * Redistributions of source code must retain the above copyright
89363 + * notice, this list of conditions and the following disclaimer.
89364 + * * Redistributions in binary form must reproduce the above copyright
89365 + * notice, this list of conditions and the following disclaimer in the
89366 + * documentation and/or other materials provided with the distribution.
89367 + * * Neither the name of Freescale Semiconductor nor the
89368 + * names of its contributors may be used to endorse or promote products
89369 + * derived from this software without specific prior written permission.
89370 + *
89371 + *
89372 + * ALTERNATIVELY, this software may be distributed under the terms of the
89373 + * GNU General Public License ("GPL") as published by the Free Software
89374 + * Foundation, either version 2 of that License or (at your option) any
89375 + * later version.
89376 + *
89377 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89378 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89379 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89380 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89381 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89382 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89383 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89384 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89385 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89386 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89387 + */
89388 +
89389 +
89390 +/**************************************************************************//**
89391 + @File debug_ext.h
89392 +
89393 + @Description Debug mode definitions.
89394 +*//***************************************************************************/
89395 +
89396 +#ifndef __DEBUG_EXT_H
89397 +#define __DEBUG_EXT_H
89398 +
89399 +#include "std_ext.h"
89400 +#include "xx_ext.h"
89401 +#include "memcpy_ext.h"
89402 +#if (DEBUG_ERRORS > 0)
89403 +#include "sprint_ext.h"
89404 +#include "string_ext.h"
89405 +#endif /* DEBUG_ERRORS > 0 */
89406 +
89407 +
89408 +#if (DEBUG_ERRORS > 0)
89409 +
89410 +/* Internally used macros */
89411 +
89412 +#define DUMP_Print XX_Print
89413 +#define DUMP_MAX_LEVELS 6
89414 +#define DUMP_IDX_LEN 6
89415 +#define DUMP_MAX_STR 64
89416 +
89417 +
89418 +#define _CREATE_DUMP_SUBSTR(phrase) \
89419 + dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \
89420 + snprintf(dumpTmpStr, DUMP_MAX_STR, "%s", #phrase); \
89421 + p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \
89422 + while ((p_DumpToken != NULL) && (dumpTmpLevel < DUMP_MAX_LEVELS)) \
89423 + { \
89424 + strlcat(dumpSubStr, p_DumpToken, DUMP_MAX_STR); \
89425 + if (dumpIsArr[dumpTmpLevel]) \
89426 + { \
89427 + strlcat(dumpSubStr, dumpIdxStr[dumpTmpLevel], DUMP_MAX_STR); \
89428 + p_DumpToken = strtok(NULL, "."); \
89429 + } \
89430 + if ((p_DumpToken != NULL) && \
89431 + ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != NULL)) \
89432 + strlcat(dumpSubStr, ".", DUMP_MAX_STR); \
89433 + }
89434 +
89435 +
89436 +/**************************************************************************//**
89437 + @Group gen_id General Drivers Utilities
89438 +
89439 + @Description External routines.
89440 +
89441 + @{
89442 +*//***************************************************************************/
89443 +
89444 +/**************************************************************************//**
89445 + @Group dump_id Memory and Registers Dump Mechanism
89446 +
89447 + @Description Macros for dumping memory mapped structures.
89448 +
89449 + @{
89450 +*//***************************************************************************/
89451 +
89452 +/**************************************************************************//**
89453 + @Description Declaration of dump mechanism variables.
89454 +
89455 + This macro must be declared at the beginning of each routine
89456 + which uses the dump mechanism macros, before the routine's code
89457 + starts.
89458 +*//***************************************************************************/
89459 +#define DECLARE_DUMP \
89460 + char dumpIdxStr[DUMP_MAX_LEVELS + 1][DUMP_IDX_LEN] = { "", }; \
89461 + char dumpSubStr[DUMP_MAX_STR] = ""; \
89462 + char dumpTmpStr[DUMP_MAX_STR] = ""; \
89463 + char *p_DumpToken = NULL; \
89464 + int dumpArrIdx = 0, dumpArrSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \
89465 + uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \
89466 + /* Prevent warnings if not all used */ \
89467 + UNUSED(dumpIdxStr[0][0]); \
89468 + UNUSED(dumpSubStr[0]); \
89469 + UNUSED(dumpTmpStr[0]); \
89470 + UNUSED(p_DumpToken); \
89471 + UNUSED(dumpArrIdx); \
89472 + UNUSED(dumpArrSize); \
89473 + UNUSED(dumpLevel); \
89474 + UNUSED(dumpTmpLevel); \
89475 + UNUSED(dumpIsArr[0]);
89476 +
89477 +
89478 +/**************************************************************************//**
89479 + @Description Prints a title for a subsequent dumped structure or memory.
89480 +
89481 + The inputs for this macro are the structure/memory title and
89482 + its base addresses.
89483 +*//***************************************************************************/
89484 +#define DUMP_TITLE(addr, msg) \
89485 + DUMP_Print("\r\n"); DUMP_Print msg; \
89486 + if (addr) \
89487 + DUMP_Print(" (%p)", (addr)); \
89488 + DUMP_Print("\r\n---------------------------------------------------------\r\n");
89489 +
89490 +/**************************************************************************//**
89491 + @Description Prints a subtitle for a subsequent dumped sub-structure (optional).
89492 +
89493 + The inputs for this macro are the sub-structure subtitle.
89494 + A separating line with this subtitle will be printed.
89495 +*//***************************************************************************/
89496 +#define DUMP_SUBTITLE(subtitle) \
89497 + DUMP_Print("----------- "); DUMP_Print subtitle; DUMP_Print("\r\n")
89498 +
89499 +
89500 +/**************************************************************************//**
89501 + @Description Dumps a memory region in 4-bytes aligned format.
89502 +
89503 + The inputs for this macro are the base addresses and size
89504 + (in bytes) of the memory region.
89505 +*//***************************************************************************/
89506 +#define DUMP_MEMORY(addr, size) \
89507 + MemDisp((uint8_t *)(addr), (int)(size))
89508 +
89509 +
89510 +/**************************************************************************//**
89511 + @Description Declares a dump loop, for dumping a sub-structure array.
89512 +
89513 + The inputs for this macro are:
89514 + - idx: an index variable, for indexing the sub-structure items
89515 + inside the loop. This variable must be declared separately
89516 + in the beginning of the routine.
89517 + - cnt: the number of times to repeat the loop. This number should
89518 + equal the number of items in the sub-structures array.
89519 +
89520 + Note, that the body of the loop must be written inside brackets.
89521 +*//***************************************************************************/
89522 +#define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \
89523 + for (idx=0, dumpIsArr[dumpLevel++] = 1; \
89524 + (idx < cnt) && (dumpLevel > 0) && snprintf(dumpIdxStr[dumpLevel-1], DUMP_IDX_LEN, "[%d]", idx); \
89525 + idx++, ((idx < cnt) || (dumpIsArr[--dumpLevel] = 0)))
89526 +
89527 +
89528 +/**************************************************************************//**
89529 + @Description Dumps a structure's member variable.
89530 +
89531 + The input for this macro is the full reference for the member
89532 + variable, where the structure is referenced using a pointer.
89533 +
89534 + Note, that a members array must be dumped using DUMP_ARR macro,
89535 + rather than using this macro.
89536 +
89537 + If the member variable is part of a sub-structure hierarchy,
89538 + the full hierarchy (including array indexing) must be specified.
89539 +
89540 + Examples: p_Struct->member
89541 + p_Struct->sub.member
89542 + p_Struct->sub[i].member
89543 +*//***************************************************************************/
89544 +#define DUMP_VAR(st, phrase) \
89545 + do { \
89546 + void *addr = (void *)&((st)->phrase); \
89547 + physAddress_t physAddr = XX_VirtToPhys(addr); \
89548 + _CREATE_DUMP_SUBSTR(phrase); \
89549 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \
89550 + physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); \
89551 + } while (0)
89552 +
89553 +
89554 +/**************************************************************************//**
89555 + @Description Dumps a structure's members array.
89556 +
89557 + The input for this macro is the full reference for the members
89558 + array, where the structure is referenced using a pointer.
89559 +
89560 + If the members array is part of a sub-structure hierarchy,
89561 + the full hierarchy (including array indexing) must be specified.
89562 +
89563 + Examples: p_Struct->array
89564 + p_Struct->sub.array
89565 + p_Struct->sub[i].array
89566 +*//***************************************************************************/
89567 +#define DUMP_ARR(st, phrase) \
89568 + do { \
89569 + physAddress_t physAddr; \
89570 + _CREATE_DUMP_SUBSTR(phrase); \
89571 + dumpArrSize = ARRAY_SIZE((st)->phrase); \
89572 + for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
89573 + physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \
89574 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s[%d]\r\n", \
89575 + physAddr, GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
89576 + } \
89577 + } while (0)
89578 +
89579 +
89580 +
89581 +#endif /* DEBUG_ERRORS > 0 */
89582 +
89583 +
89584 +/** @} */ /* end of dump_id group */
89585 +/** @} */ /* end of gen_id group */
89586 +
89587 +
89588 +#endif /* __DEBUG_EXT_H */
89589 +
89590 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
89591 new file mode 100644
89592 index 00000000..5cdec668
89593 --- /dev/null
89594 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
89595 @@ -0,0 +1,447 @@
89596 +/*
89597 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89598 + *
89599 + * Redistribution and use in source and binary forms, with or without
89600 + * modification, are permitted provided that the following conditions are met:
89601 + * * Redistributions of source code must retain the above copyright
89602 + * notice, this list of conditions and the following disclaimer.
89603 + * * Redistributions in binary form must reproduce the above copyright
89604 + * notice, this list of conditions and the following disclaimer in the
89605 + * documentation and/or other materials provided with the distribution.
89606 + * * Neither the name of Freescale Semiconductor nor the
89607 + * names of its contributors may be used to endorse or promote products
89608 + * derived from this software without specific prior written permission.
89609 + *
89610 + *
89611 + * ALTERNATIVELY, this software may be distributed under the terms of the
89612 + * GNU General Public License ("GPL") as published by the Free Software
89613 + * Foundation, either version 2 of that License or (at your option) any
89614 + * later version.
89615 + *
89616 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89617 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89618 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89619 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89620 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89621 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89622 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89623 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89624 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89625 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89626 + */
89627 +
89628 +
89629 +/**************************************************************************//**
89630 +
89631 + @File endian_ext.h
89632 +
89633 + @Description Big/little endian swapping routines.
89634 +*//***************************************************************************/
89635 +
89636 +#ifndef __ENDIAN_EXT_H
89637 +#define __ENDIAN_EXT_H
89638 +
89639 +#include "std_ext.h"
89640 +
89641 +
89642 +/**************************************************************************//**
89643 + @Group gen_id General Drivers Utilities
89644 +
89645 + @Description General usage API. This API is intended for usage by both the
89646 + internal modules and the user's application.
89647 +
89648 + @{
89649 +*//***************************************************************************/
89650 +
89651 +/**************************************************************************//**
89652 + @Group endian_id Big/Little-Endian Conversion
89653 +
89654 + @Description Routines and macros for Big/Little-Endian conversion and
89655 + general byte swapping.
89656 +
89657 + All routines and macros are expecting unsigned values as
89658 + parameters, but will generate the correct result also for
89659 + signed values. Therefore, signed/unsigned casting is allowed.
89660 + @{
89661 +*//***************************************************************************/
89662 +
89663 +/**************************************************************************//**
89664 + @Collection Byte-Swap Macros
89665 +
89666 + Macros for swapping byte order.
89667 +
89668 + @Cautions The parameters of these macros are evaluated multiple times.
89669 + For calculated expressions or expressions that contain function
89670 + calls it is recommended to use the byte-swap routines.
89671 +
89672 + @{
89673 +*//***************************************************************************/
89674 +
89675 +/**************************************************************************//**
89676 + @Description Swaps the byte order of a given 16-bit value.
89677 +
89678 + @Param[in] val - The 16-bit value to swap.
89679 +
89680 + @Return The byte-swapped value..
89681 +
89682 + @Cautions The given value is evaluated multiple times by this macro.
89683 + For calculated expressions or expressions that contain function
89684 + calls it is recommended to use the SwapUint16() routine.
89685 +
89686 + @hideinitializer
89687 +*//***************************************************************************/
89688 +#define SWAP_UINT16(val) \
89689 + ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8)))
89690 +
89691 +/**************************************************************************//**
89692 + @Description Swaps the byte order of a given 32-bit value.
89693 +
89694 + @Param[in] val - The 32-bit value to swap.
89695 +
89696 + @Return The byte-swapped value..
89697 +
89698 + @Cautions The given value is evaluated multiple times by this macro.
89699 + For calculated expressions or expressions that contain function
89700 + calls it is recommended to use the SwapUint32() routine.
89701 +
89702 + @hideinitializer
89703 +*//***************************************************************************/
89704 +#define SWAP_UINT32(val) \
89705 + ((uint32_t)((((val) & 0x000000FF) << 24) | \
89706 + (((val) & 0x0000FF00) << 8) | \
89707 + (((val) & 0x00FF0000) >> 8) | \
89708 + (((val) & 0xFF000000) >> 24)))
89709 +
89710 +/**************************************************************************//**
89711 + @Description Swaps the byte order of a given 64-bit value.
89712 +
89713 + @Param[in] val - The 64-bit value to swap.
89714 +
89715 + @Return The byte-swapped value..
89716 +
89717 + @Cautions The given value is evaluated multiple times by this macro.
89718 + For calculated expressions or expressions that contain function
89719 + calls it is recommended to use the SwapUint64() routine.
89720 +
89721 + @hideinitializer
89722 +*//***************************************************************************/
89723 +#define SWAP_UINT64(val) \
89724 + ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \
89725 + (((val) & 0x000000000000FF00ULL) << 40) | \
89726 + (((val) & 0x0000000000FF0000ULL) << 24) | \
89727 + (((val) & 0x00000000FF000000ULL) << 8) | \
89728 + (((val) & 0x000000FF00000000ULL) >> 8) | \
89729 + (((val) & 0x0000FF0000000000ULL) >> 24) | \
89730 + (((val) & 0x00FF000000000000ULL) >> 40) | \
89731 + (((val) & 0xFF00000000000000ULL) >> 56)))
89732 +
89733 +/* @} */
89734 +
89735 +/**************************************************************************//**
89736 + @Collection Byte-Swap Routines
89737 +
89738 + Routines for swapping the byte order of a given parameter and
89739 + returning the swapped value.
89740 +
89741 + These inline routines are safer than the byte-swap macros,
89742 + because they evaluate the parameter expression only once.
89743 + @{
89744 +*//***************************************************************************/
89745 +
89746 +/**************************************************************************//**
89747 + @Function SwapUint16
89748 +
89749 + @Description Returns the byte-swapped value of a given 16-bit value.
89750 +
89751 + @Param[in] val - The 16-bit value.
89752 +
89753 + @Return The byte-swapped value of the parameter.
89754 +*//***************************************************************************/
89755 +static __inline__ uint16_t SwapUint16(uint16_t val)
89756 +{
89757 + return (uint16_t)(((val & 0x00FF) << 8) |
89758 + ((val & 0xFF00) >> 8));
89759 +}
89760 +
89761 +/**************************************************************************//**
89762 + @Function SwapUint32
89763 +
89764 + @Description Returns the byte-swapped value of a given 32-bit value.
89765 +
89766 + @Param[in] val - The 32-bit value.
89767 +
89768 + @Return The byte-swapped value of the parameter.
89769 +*//***************************************************************************/
89770 +static __inline__ uint32_t SwapUint32(uint32_t val)
89771 +{
89772 + return (uint32_t)(((val & 0x000000FF) << 24) |
89773 + ((val & 0x0000FF00) << 8) |
89774 + ((val & 0x00FF0000) >> 8) |
89775 + ((val & 0xFF000000) >> 24));
89776 +}
89777 +
89778 +/**************************************************************************//**
89779 + @Function SwapUint64
89780 +
89781 + @Description Returns the byte-swapped value of a given 64-bit value.
89782 +
89783 + @Param[in] val - The 64-bit value.
89784 +
89785 + @Return The byte-swapped value of the parameter.
89786 +*//***************************************************************************/
89787 +static __inline__ uint64_t SwapUint64(uint64_t val)
89788 +{
89789 + return (uint64_t)(((val & 0x00000000000000FFULL) << 56) |
89790 + ((val & 0x000000000000FF00ULL) << 40) |
89791 + ((val & 0x0000000000FF0000ULL) << 24) |
89792 + ((val & 0x00000000FF000000ULL) << 8) |
89793 + ((val & 0x000000FF00000000ULL) >> 8) |
89794 + ((val & 0x0000FF0000000000ULL) >> 24) |
89795 + ((val & 0x00FF000000000000ULL) >> 40) |
89796 + ((val & 0xFF00000000000000ULL) >> 56));
89797 +}
89798 +
89799 +/* @} */
89800 +
89801 +/**************************************************************************//**
89802 + @Collection In-place Byte-Swap-And-Set Routines
89803 +
89804 + Routines for swapping the byte order of a given variable and
89805 + setting the swapped value back to the same variable.
89806 + @{
89807 +*//***************************************************************************/
89808 +
89809 +/**************************************************************************//**
89810 + @Function SwapUint16P
89811 +
89812 + @Description Swaps the byte order of a given 16-bit variable.
89813 +
89814 + @Param[in] p_Val - Pointer to the 16-bit variable.
89815 +
89816 + @Return None.
89817 +*//***************************************************************************/
89818 +static __inline__ void SwapUint16P(uint16_t *p_Val)
89819 +{
89820 + *p_Val = SwapUint16(*p_Val);
89821 +}
89822 +
89823 +/**************************************************************************//**
89824 + @Function SwapUint32P
89825 +
89826 + @Description Swaps the byte order of a given 32-bit variable.
89827 +
89828 + @Param[in] p_Val - Pointer to the 32-bit variable.
89829 +
89830 + @Return None.
89831 +*//***************************************************************************/
89832 +static __inline__ void SwapUint32P(uint32_t *p_Val)
89833 +{
89834 + *p_Val = SwapUint32(*p_Val);
89835 +}
89836 +
89837 +/**************************************************************************//**
89838 + @Function SwapUint64P
89839 +
89840 + @Description Swaps the byte order of a given 64-bit variable.
89841 +
89842 + @Param[in] p_Val - Pointer to the 64-bit variable.
89843 +
89844 + @Return None.
89845 +*//***************************************************************************/
89846 +static __inline__ void SwapUint64P(uint64_t *p_Val)
89847 +{
89848 + *p_Val = SwapUint64(*p_Val);
89849 +}
89850 +
89851 +/* @} */
89852 +
89853 +
89854 +/**************************************************************************//**
89855 + @Collection Little-Endian Conversion Macros
89856 +
89857 + These macros convert given parameters to or from Little-Endian
89858 + format. Use these macros when you want to read or write a specific
89859 + Little-Endian value in memory, without a-priori knowing the CPU
89860 + byte order.
89861 +
89862 + These macros use the byte-swap routines. For conversion of
89863 + constants in initialization structures, you may use the CONST
89864 + versions of these macros (see below), which are using the
89865 + byte-swap macros instead.
89866 + @{
89867 +*//***************************************************************************/
89868 +
89869 +/**************************************************************************//**
89870 + @Description Converts a given 16-bit value from CPU byte order to
89871 + Little-Endian byte order.
89872 +
89873 + @Param[in] val - The 16-bit value to convert.
89874 +
89875 + @Return The converted value.
89876 +
89877 + @hideinitializer
89878 +*//***************************************************************************/
89879 +#define CPU_TO_LE16(val) SwapUint16(val)
89880 +
89881 +/**************************************************************************//**
89882 + @Description Converts a given 32-bit value from CPU byte order to
89883 + Little-Endian byte order.
89884 +
89885 + @Param[in] val - The 32-bit value to convert.
89886 +
89887 + @Return The converted value.
89888 +
89889 + @hideinitializer
89890 +*//***************************************************************************/
89891 +#define CPU_TO_LE32(val) SwapUint32(val)
89892 +
89893 +/**************************************************************************//**
89894 + @Description Converts a given 64-bit value from CPU byte order to
89895 + Little-Endian byte order.
89896 +
89897 + @Param[in] val - The 64-bit value to convert.
89898 +
89899 + @Return The converted value.
89900 +
89901 + @hideinitializer
89902 +*//***************************************************************************/
89903 +#define CPU_TO_LE64(val) SwapUint64(val)
89904 +
89905 +
89906 +/**************************************************************************//**
89907 + @Description Converts a given 16-bit value from Little-Endian byte order to
89908 + CPU byte order.
89909 +
89910 + @Param[in] val - The 16-bit value to convert.
89911 +
89912 + @Return The converted value.
89913 +
89914 + @hideinitializer
89915 +*//***************************************************************************/
89916 +#define LE16_TO_CPU(val) CPU_TO_LE16(val)
89917 +
89918 +/**************************************************************************//**
89919 + @Description Converts a given 32-bit value from Little-Endian byte order to
89920 + CPU byte order.
89921 +
89922 + @Param[in] val - The 32-bit value to convert.
89923 +
89924 + @Return The converted value.
89925 +
89926 + @hideinitializer
89927 +*//***************************************************************************/
89928 +#define LE32_TO_CPU(val) CPU_TO_LE32(val)
89929 +
89930 +/**************************************************************************//**
89931 + @Description Converts a given 64-bit value from Little-Endian byte order to
89932 + CPU byte order.
89933 +
89934 + @Param[in] val - The 64-bit value to convert.
89935 +
89936 + @Return The converted value.
89937 +
89938 + @hideinitializer
89939 +*//***************************************************************************/
89940 +#define LE64_TO_CPU(val) CPU_TO_LE64(val)
89941 +
89942 +/* @} */
89943 +
89944 +/**************************************************************************//**
89945 + @Collection Little-Endian Constant Conversion Macros
89946 +
89947 + These macros convert given constants to or from Little-Endian
89948 + format. Use these macros when you want to read or write a specific
89949 + Little-Endian constant in memory, without a-priori knowing the
89950 + CPU byte order.
89951 +
89952 + These macros use the byte-swap macros, therefore can be used for
89953 + conversion of constants in initialization structures.
89954 +
89955 + @Cautions The parameters of these macros are evaluated multiple times.
89956 + For non-constant expressions, use the non-CONST macro versions.
89957 +
89958 + @{
89959 +*//***************************************************************************/
89960 +
89961 +/**************************************************************************//**
89962 + @Description Converts a given 16-bit constant from CPU byte order to
89963 + Little-Endian byte order.
89964 +
89965 + @Param[in] val - The 16-bit value to convert.
89966 +
89967 + @Return The converted value.
89968 +
89969 + @hideinitializer
89970 +*//***************************************************************************/
89971 +#define CONST_CPU_TO_LE16(val) SWAP_UINT16(val)
89972 +
89973 +/**************************************************************************//**
89974 + @Description Converts a given 32-bit constant from CPU byte order to
89975 + Little-Endian byte order.
89976 +
89977 + @Param[in] val - The 32-bit value to convert.
89978 +
89979 + @Return The converted value.
89980 +
89981 + @hideinitializer
89982 +*//***************************************************************************/
89983 +#define CONST_CPU_TO_LE32(val) SWAP_UINT32(val)
89984 +
89985 +/**************************************************************************//**
89986 + @Description Converts a given 64-bit constant from CPU byte order to
89987 + Little-Endian byte order.
89988 +
89989 + @Param[in] val - The 64-bit value to convert.
89990 +
89991 + @Return The converted value.
89992 +
89993 + @hideinitializer
89994 +*//***************************************************************************/
89995 +#define CONST_CPU_TO_LE64(val) SWAP_UINT64(val)
89996 +
89997 +
89998 +/**************************************************************************//**
89999 + @Description Converts a given 16-bit constant from Little-Endian byte order
90000 + to CPU byte order.
90001 +
90002 + @Param[in] val - The 16-bit value to convert.
90003 +
90004 + @Return The converted value.
90005 +
90006 + @hideinitializer
90007 +*//***************************************************************************/
90008 +#define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val)
90009 +
90010 +/**************************************************************************//**
90011 + @Description Converts a given 32-bit constant from Little-Endian byte order
90012 + to CPU byte order.
90013 +
90014 + @Param[in] val - The 32-bit value to convert.
90015 +
90016 + @Return The converted value.
90017 +
90018 + @hideinitializer
90019 +*//***************************************************************************/
90020 +#define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val)
90021 +
90022 +/**************************************************************************//**
90023 + @Description Converts a given 64-bit constant from Little-Endian byte order
90024 + to CPU byte order.
90025 +
90026 + @Param[in] val - The 64-bit value to convert.
90027 +
90028 + @Return The converted value.
90029 +
90030 + @hideinitializer
90031 +*//***************************************************************************/
90032 +#define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val)
90033 +
90034 +/* @} */
90035 +
90036 +
90037 +/** @} */ /* end of endian_id group */
90038 +/** @} */ /* end of gen_id group */
90039 +
90040 +
90041 +#endif /* __ENDIAN_EXT_H */
90042 +
90043 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
90044 new file mode 100644
90045 index 00000000..ef3bee55
90046 --- /dev/null
90047 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
90048 @@ -0,0 +1,205 @@
90049 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90050 + * All rights reserved.
90051 + *
90052 + * Redistribution and use in source and binary forms, with or without
90053 + * modification, are permitted provided that the following conditions are met:
90054 + * * Redistributions of source code must retain the above copyright
90055 + * notice, this list of conditions and the following disclaimer.
90056 + * * Redistributions in binary form must reproduce the above copyright
90057 + * notice, this list of conditions and the following disclaimer in the
90058 + * documentation and/or other materials provided with the distribution.
90059 + * * Neither the name of Freescale Semiconductor nor the
90060 + * names of its contributors may be used to endorse or promote products
90061 + * derived from this software without specific prior written permission.
90062 + *
90063 + *
90064 + * ALTERNATIVELY, this software may be distributed under the terms of the
90065 + * GNU General Public License ("GPL") as published by the Free Software
90066 + * Foundation, either version 2 of that License or (at your option) any
90067 + * later version.
90068 + *
90069 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90070 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90071 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90072 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90073 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90074 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90075 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90076 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90077 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90078 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90079 + */
90080 +
90081 +
90082 +/**************************************************************************//**
90083 + @File enet_ext.h
90084 +
90085 + @Description Ethernet generic definitions and enums.
90086 +*//***************************************************************************/
90087 +
90088 +#ifndef __ENET_EXT_H
90089 +#define __ENET_EXT_H
90090 +
90091 +#include "fsl_enet.h"
90092 +
90093 +#define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */
90094 +#define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */
90095 +
90096 +
90097 +/**************************************************************************//**
90098 + @Description Ethernet Address
90099 +*//***************************************************************************/
90100 +typedef uint8_t t_EnetAddr[ENET_NUM_OCTETS_PER_ADDRESS];
90101 +
90102 +/**************************************************************************//**
90103 + @Description Ethernet Address Type.
90104 +*//***************************************************************************/
90105 +typedef enum e_EnetAddrType
90106 +{
90107 + e_ENET_ADDR_TYPE_INDIVIDUAL, /**< Individual (unicast) address */
90108 + e_ENET_ADDR_TYPE_GROUP, /**< Group (multicast) address */
90109 + e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */
90110 +} e_EnetAddrType;
90111 +
90112 +/**************************************************************************//**
90113 + @Description Ethernet MAC-PHY Interface
90114 +*//***************************************************************************/
90115 +typedef enum e_EnetInterface
90116 +{
90117 + e_ENET_IF_MII = E_ENET_IF_MII, /**< MII interface */
90118 + e_ENET_IF_RMII = E_ENET_IF_RMII, /**< RMII interface */
90119 + e_ENET_IF_SMII = E_ENET_IF_SMII, /**< SMII interface */
90120 + e_ENET_IF_GMII = E_ENET_IF_GMII, /**< GMII interface */
90121 + e_ENET_IF_RGMII = E_ENET_IF_RGMII, /**< RGMII interface */
90122 + e_ENET_IF_TBI = E_ENET_IF_TBI, /**< TBI interface */
90123 + e_ENET_IF_RTBI = E_ENET_IF_RTBI, /**< RTBI interface */
90124 + e_ENET_IF_SGMII = E_ENET_IF_SGMII, /**< SGMII interface */
90125 + e_ENET_IF_XGMII = E_ENET_IF_XGMII, /**< XGMII interface */
90126 + e_ENET_IF_QSGMII= E_ENET_IF_QSGMII, /**< QSGMII interface */
90127 + e_ENET_IF_XFI = E_ENET_IF_XFI /**< XFI interface */
90128 +} e_EnetInterface;
90129 +
90130 +#define ENET_IF_SGMII_BASEX 0x80000000 /**< SGMII/QSGII interface with 1000BaseX
90131 + auto-negotiation between MAC and phy
90132 + or backplane;
90133 + Note: 1000BaseX auto-negotiation relates
90134 + only to interface between MAC and phy/backplane,
90135 + SGMII phy can still synchronize with far-end phy
90136 + at 10Mbps, 100Mbps or 1000Mbps */
90137 +
90138 +/**************************************************************************//**
90139 + @Description Ethernet Duplex Mode
90140 +*//***************************************************************************/
90141 +typedef enum e_EnetDuplexMode
90142 +{
90143 + e_ENET_HALF_DUPLEX, /**< Half-Duplex mode */
90144 + e_ENET_FULL_DUPLEX /**< Full-Duplex mode */
90145 +} e_EnetDuplexMode;
90146 +
90147 +/**************************************************************************//**
90148 + @Description Ethernet Speed (nominal data rate)
90149 +*//***************************************************************************/
90150 +typedef enum e_EnetSpeed
90151 +{
90152 + e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */
90153 + e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */
90154 + e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */
90155 + e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */
90156 + e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */
90157 +} e_EnetSpeed;
90158 +
90159 +/**************************************************************************//**
90160 + @Description Ethernet mode (combination of MAC-PHY interface and speed)
90161 +*//***************************************************************************/
90162 +typedef enum e_EnetMode
90163 +{
90164 + e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */
90165 + e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */
90166 + e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */
90167 + e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */
90168 + e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */
90169 + e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */
90170 + e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */
90171 + e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */
90172 + e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */
90173 + e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */
90174 + e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */
90175 + e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */
90176 + e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */
90177 + e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10),
90178 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
90179 + SGMII phy according to Cisco SGMII specification */
90180 + e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100),
90181 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
90182 + SGMII phy according to Cisco SGMII specification */
90183 + e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000),
90184 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
90185 + SGMII phy according to Cisco SGMII specification */
90186 + e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500),
90187 + e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10),
90188 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
90189 + MAC and SGMII phy or backplane */
90190 + e_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_100),
90191 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
90192 + MAC and SGMII phy or backplane */
90193 + e_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_1000),
90194 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
90195 + MAC and SGMII phy or backplane */
90196 + e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
90197 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
90198 + QSGMII phy according to Cisco QSGMII specification */
90199 + e_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
90200 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
90201 + MAC and QSGMII phy or backplane */
90202 + e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */
90203 + e_ENET_MODE_XFI_10000 = (e_ENET_IF_XFI | e_ENET_SPEED_10000) /**< 10000 Mbps XFI */
90204 +} e_EnetMode;
90205 +
90206 +
90207 +#define IS_ENET_MODE_VALID(mode) \
90208 + (((mode) == e_ENET_MODE_MII_10 ) || \
90209 + ((mode) == e_ENET_MODE_MII_100 ) || \
90210 + ((mode) == e_ENET_MODE_RMII_10 ) || \
90211 + ((mode) == e_ENET_MODE_RMII_100 ) || \
90212 + ((mode) == e_ENET_MODE_SMII_10 ) || \
90213 + ((mode) == e_ENET_MODE_SMII_100 ) || \
90214 + ((mode) == e_ENET_MODE_GMII_1000 ) || \
90215 + ((mode) == e_ENET_MODE_RGMII_10 ) || \
90216 + ((mode) == e_ENET_MODE_RGMII_100 ) || \
90217 + ((mode) == e_ENET_MODE_RGMII_1000 ) || \
90218 + ((mode) == e_ENET_MODE_TBI_1000 ) || \
90219 + ((mode) == e_ENET_MODE_RTBI_1000 ) || \
90220 + ((mode) == e_ENET_MODE_SGMII_10 ) || \
90221 + ((mode) == e_ENET_MODE_SGMII_100 ) || \
90222 + ((mode) == e_ENET_MODE_SGMII_1000 ) || \
90223 + ((mode) == e_ENET_MODE_SGMII_BASEX_10 ) || \
90224 + ((mode) == e_ENET_MODE_SGMII_BASEX_100 ) || \
90225 + ((mode) == e_ENET_MODE_SGMII_BASEX_1000 ) || \
90226 + ((mode) == e_ENET_MODE_XGMII_10000) || \
90227 + ((mode) == e_ENET_MODE_QSGMII_1000) || \
90228 + ((mode) == e_ENET_MODE_QSGMII_BASEX_1000) || \
90229 + ((mode) == e_ENET_MODE_XFI_10000))
90230 +
90231 +
90232 +#define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed))
90233 +
90234 +#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0x0FFF0000)
90235 +#define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF)
90236 +
90237 +#define ENET_ADDR_TO_UINT64(_enetAddr) \
90238 + (uint64_t)(((uint64_t)(_enetAddr)[0] << 40) | \
90239 + ((uint64_t)(_enetAddr)[1] << 32) | \
90240 + ((uint64_t)(_enetAddr)[2] << 24) | \
90241 + ((uint64_t)(_enetAddr)[3] << 16) | \
90242 + ((uint64_t)(_enetAddr)[4] << 8) | \
90243 + ((uint64_t)(_enetAddr)[5]))
90244 +
90245 +#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enetAddr) \
90246 + do { \
90247 + int i; \
90248 + for (i=0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
90249 + (_enetAddr)[i] = (uint8_t)((_addr64) >> ((5-i)*8)); \
90250 + } while (0)
90251 +
90252 +
90253 +#endif /* __ENET_EXT_H */
90254 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
90255 new file mode 100644
90256 index 00000000..2a5ad67b
90257 --- /dev/null
90258 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
90259 @@ -0,0 +1,529 @@
90260 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90261 + * All rights reserved.
90262 + *
90263 + * Redistribution and use in source and binary forms, with or without
90264 + * modification, are permitted provided that the following conditions are met:
90265 + * * Redistributions of source code must retain the above copyright
90266 + * notice, this list of conditions and the following disclaimer.
90267 + * * Redistributions in binary form must reproduce the above copyright
90268 + * notice, this list of conditions and the following disclaimer in the
90269 + * documentation and/or other materials provided with the distribution.
90270 + * * Neither the name of Freescale Semiconductor nor the
90271 + * names of its contributors may be used to endorse or promote products
90272 + * derived from this software without specific prior written permission.
90273 + *
90274 + *
90275 + * ALTERNATIVELY, this software may be distributed under the terms of the
90276 + * GNU General Public License ("GPL") as published by the Free Software
90277 + * Foundation, either version 2 of that License or (at your option) any
90278 + * later version.
90279 + *
90280 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90281 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90282 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90283 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90284 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90285 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90286 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90287 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90288 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90289 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90290 + */
90291 +
90292 +
90293 +/**************************************************************************//**
90294 + @File error_ext.h
90295 +
90296 + @Description Error definitions.
90297 +*//***************************************************************************/
90298 +
90299 +#ifndef __ERROR_EXT_H
90300 +#define __ERROR_EXT_H
90301 +
90302 +#if !defined(NCSW_LINUX)
90303 +#include <errno.h>
90304 +#endif
90305 +
90306 +#include "std_ext.h"
90307 +#include "xx_ext.h"
90308 +#include "core_ext.h"
90309 +
90310 +
90311 +
90312 +
90313 +/**************************************************************************//**
90314 + @Group gen_id General Drivers Utilities
90315 +
90316 + @Description External routines.
90317 +
90318 + @{
90319 +*//***************************************************************************/
90320 +
90321 +/**************************************************************************//**
90322 + @Group gen_error_id Errors, Events and Debug
90323 +
90324 + @Description External routines.
90325 +
90326 + @{
90327 +*//***************************************************************************/
90328 +
90329 +/******************************************************************************
90330 +The scheme below provides the bits description for error codes:
90331 +
90332 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
90333 +| Reserved (should be zero) | Module ID |
90334 +
90335 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
90336 +| Error Type |
90337 +******************************************************************************/
90338 +
90339 +#define ERROR_CODE(_err) ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__)
90340 +
90341 +#define GET_ERROR_TYPE(_errcode) ((_errcode) & 0x0000FFFF)
90342 + /**< Extract module code from error code (#t_Error) */
90343 +
90344 +#define GET_ERROR_MODULE(_errcode) ((_errcode) & 0x00FF0000)
90345 + /**< Extract error type (#e_ErrorType) from
90346 + error code (#t_Error) */
90347 +
90348 +
90349 +/**************************************************************************//**
90350 + @Description Error Type Enumeration
90351 +*//***************************************************************************/
90352 +typedef enum e_ErrorType /* Comments / Associated Message Strings */
90353 +{ /* ------------------------------------------------------------ */
90354 + E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */
90355 + ,E_WRITE_FAILED = EIO /**< Write access failed on memory/device. */
90356 + /* String: none, or device name. */
90357 + ,E_NO_DEVICE = ENXIO /**< The associated device is not initialized. */
90358 + /* String: none. */
90359 + ,E_NOT_AVAILABLE = EAGAIN
90360 + /**< Resource is unavailable. */
90361 + /* String: none, unless the operation is not the main goal
90362 + of the function (in this case add resource description). */
90363 + ,E_NO_MEMORY = ENOMEM /**< External memory allocation failed. */
90364 + /* String: description of item for which allocation failed. */
90365 + ,E_INVALID_ADDRESS = EFAULT
90366 + /**< Invalid address. */
90367 + /* String: description of the specific violation. */
90368 + ,E_BUSY = EBUSY /**< Resource or module is busy. */
90369 + /* String: none, unless the operation is not the main goal
90370 + of the function (in this case add resource description). */
90371 + ,E_ALREADY_EXISTS = EEXIST
90372 + /**< Requested resource or item already exists. */
90373 + /* Use when resource duplication or sharing are not allowed.
90374 + String: none, unless the operation is not the main goal
90375 + of the function (in this case add item description). */
90376 + ,E_INVALID_OPERATION = ENODEV
90377 + /**< The operation/command is invalid (unrecognized). */
90378 + /* String: none. */
90379 + ,E_INVALID_VALUE = EDOM /**< Invalid value. */
90380 + /* Use for non-enumeration parameters, and
90381 + only when other error types are not suitable.
90382 + String: parameter description + "(should be <attribute>)",
90383 + e.g: "Maximum Rx buffer length (should be divisible by 8)",
90384 + "Channel number (should be even)". */
90385 + ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range. */
90386 + /* Don't use this error for enumeration parameters.
90387 + String: parameter description + "(should be %d-%d)",
90388 + e.g: "Number of pad characters (should be 0-15)". */
90389 + ,E_NOT_SUPPORTED = ENOSYS
90390 + /**< The function is not supported or not implemented. */
90391 + /* String: none. */
90392 + ,E_INVALID_STATE /**< The operation is not allowed in current module state. */
90393 + /* String: none. */
90394 + ,E_INVALID_HANDLE /**< Invalid handle of module or object. */
90395 + /* String: none, unless the function takes in more than one
90396 + handle (in this case add the handle description) */
90397 + ,E_INVALID_ID /**< Invalid module ID (usually enumeration or index). */
90398 + /* String: none, unless the function takes in more than one
90399 + ID (in this case add the ID description) */
90400 + ,E_NULL_POINTER /**< Unexpected NULL pointer. */
90401 + /* String: pointer description. */
90402 + ,E_INVALID_SELECTION /**< Invalid selection or mode. */
90403 + /* Use for enumeration values, only when other error types
90404 + are not suitable.
90405 + String: parameter description. */
90406 + ,E_INVALID_COMM_MODE /**< Invalid communication mode. */
90407 + /* String: none, unless the function takes in more than one
90408 + communication mode indications (in this case add
90409 + parameter description). */
90410 + ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */
90411 + /* String: none, unless the function takes in more than one
90412 + memory types (in this case add memory description,
90413 + e.g: "Data memory", "Buffer descriptors memory"). */
90414 + ,E_INVALID_CLOCK /**< Invalid clock. */
90415 + /* String: none, unless the function takes in more than one
90416 + clocks (in this case add clock description,
90417 + e.g: "Rx clock", "Tx clock"). */
90418 + ,E_CONFLICT /**< Some setting conflicts with another setting. */
90419 + /* String: description of the conflicting settings. */
90420 + ,E_NOT_ALIGNED /**< Non-aligned address. */
90421 + /* String: parameter description + "(should be %d-bytes aligned)",
90422 + e.g: "Rx data buffer (should be 32-bytes aligned)". */
90423 + ,E_NOT_FOUND /**< Requested resource or item was not found. */
90424 + /* Use only when the resource/item is uniquely identified.
90425 + String: none, unless the operation is not the main goal
90426 + of the function (in this case add item description). */
90427 + ,E_FULL /**< Resource is full. */
90428 + /* String: none, unless the operation is not the main goal
90429 + of the function (in this case add resource description). */
90430 + ,E_EMPTY /**< Resource is empty. */
90431 + /* String: none, unless the operation is not the main goal
90432 + of the function (in this case add resource description). */
90433 + ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */
90434 + /* String: none, unless the operation is not the main goal
90435 + of the function (in this case add item description). */
90436 + ,E_READ_FAILED /**< Read access failed on memory/device. */
90437 + /* String: none, or device name. */
90438 + ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */
90439 + /* String: none. */
90440 + ,E_SEND_FAILED /**< Send operation failed on device. */
90441 + /* String: none, or device name. */
90442 + ,E_RECEIVE_FAILED /**< Receive operation failed on device. */
90443 + /* String: none, or device name. */
90444 + ,E_TIMEOUT/* = ETIMEDOUT*/ /**< The operation timed out. */
90445 + /* String: none. */
90446 +
90447 + ,E_DUMMY_LAST /* NEVER USED */
90448 +
90449 +} e_ErrorType;
90450 +
90451 +/**************************************************************************//**
90452 + @Description Event Type Enumeration
90453 +*//***************************************************************************/
90454 +typedef enum e_Event /* Comments / Associated Flags and Message Strings */
90455 +{ /* ------------------------------------------------------------ */
90456 + EV_NO_EVENT = 0 /**< No event; Never used. */
90457 +
90458 + ,EV_RX_DISCARD /**< Received packet discarded (by the driver, and only for
90459 + complete packets);
90460 + Flags: error flags in case of error, zero otherwise. */
90461 + /* String: reason for discard, e.g: "Error in frame",
90462 + "Disordered frame", "Incomplete frame", "No frame object". */
90463 + ,EV_RX_ERROR /**< Receive error (by hardware/firmware);
90464 + Flags: usually status flags from the buffer descriptor. */
90465 + /* String: none. */
90466 + ,EV_TX_ERROR /**< Transmit error (by hardware/firmware);
90467 + Flags: usually status flags from the buffer descriptor. */
90468 + /* String: none. */
90469 + ,EV_NO_BUFFERS /**< System ran out of buffer objects;
90470 + Flags: zero. */
90471 + /* String: none. */
90472 + ,EV_NO_MB_FRAMES /**< System ran out of multi-buffer frame objects;
90473 + Flags: zero. */
90474 + /* String: none. */
90475 + ,EV_NO_SB_FRAMES /**< System ran out of single-buffer frame objects;
90476 + Flags: zero. */
90477 + /* String: none. */
90478 + ,EV_TX_QUEUE_FULL /**< Transmit queue is full;
90479 + Flags: zero. */
90480 + /* String: none. */
90481 + ,EV_RX_QUEUE_FULL /**< Receive queue is full;
90482 + Flags: zero. */
90483 + /* String: none. */
90484 + ,EV_INTR_QUEUE_FULL /**< Interrupt queue overflow;
90485 + Flags: zero. */
90486 + /* String: none. */
90487 + ,EV_NO_DATA_BUFFER /**< Data buffer allocation (from higher layer) failed;
90488 + Flags: zero. */
90489 + /* String: none. */
90490 + ,EV_OBJ_POOL_EMPTY /**< Objects pool is empty;
90491 + Flags: zero. */
90492 + /* String: object description (name). */
90493 + ,EV_BUS_ERROR /**< Illegal access on bus;
90494 + Flags: the address (if available) or bus identifier */
90495 + /* String: bus/address/module description. */
90496 + ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full;
90497 + Flags: zero. */
90498 + /* String: none. */
90499 + ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full;
90500 + Flags: zero. */
90501 + /* String: none. */
90502 + ,EV_DUMMY_LAST
90503 +
90504 +} e_Event;
90505 +
90506 +
90507 +/**************************************************************************//**
90508 + @Collection Debug Levels for Errors and Events
90509 +
90510 + The level description refers to errors only.
90511 + For events, classification is done by the user.
90512 +
90513 + The TRACE, INFO and WARNING levels are allowed only when using
90514 + the DBG macro, and are not allowed when using the error macros
90515 + (RETURN_ERROR or REPORT_ERROR).
90516 + @{
90517 +*//***************************************************************************/
90518 +#define REPORT_LEVEL_CRITICAL 1 /**< Crasher: Incorrect flow, NULL pointers/handles. */
90519 +#define REPORT_LEVEL_MAJOR 2 /**< Cannot proceed: Invalid operation, parameters or
90520 + configuration. */
90521 +#define REPORT_LEVEL_MINOR 3 /**< Recoverable problem: a repeating call with the same
90522 + parameters may be successful. */
90523 +#define REPORT_LEVEL_WARNING 4 /**< Something is not exactly right, yet it is not an error. */
90524 +#define REPORT_LEVEL_INFO 5 /**< Messages which may be of interest to user/programmer. */
90525 +#define REPORT_LEVEL_TRACE 6 /**< Program flow messages. */
90526 +
90527 +#define EVENT_DISABLED 0xFF /**< Disabled event (not reported at all) */
90528 +
90529 +/* @} */
90530 +
90531 +
90532 +
90533 +#define NO_MSG ("")
90534 +
90535 +#ifndef DEBUG_GLOBAL_LEVEL
90536 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
90537 +#endif /* DEBUG_GLOBAL_LEVEL */
90538 +
90539 +#ifndef ERROR_GLOBAL_LEVEL
90540 +#define ERROR_GLOBAL_LEVEL DEBUG_GLOBAL_LEVEL
90541 +#endif /* ERROR_GLOBAL_LEVEL */
90542 +
90543 +#ifndef EVENT_GLOBAL_LEVEL
90544 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
90545 +#endif /* EVENT_GLOBAL_LEVEL */
90546 +
90547 +#ifdef EVENT_LOCAL_LEVEL
90548 +#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL
90549 +#else
90550 +#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL
90551 +#endif /* EVENT_LOCAL_LEVEL */
90552 +
90553 +
90554 +#ifndef DEBUG_DYNAMIC_LEVEL
90555 +#define DEBUG_USING_STATIC_LEVEL
90556 +
90557 +#ifdef DEBUG_STATIC_LEVEL
90558 +#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL
90559 +#else
90560 +#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL
90561 +#endif /* DEBUG_STATIC_LEVEL */
90562 +
90563 +#else /* DEBUG_DYNAMIC_LEVEL */
90564 +#ifdef DEBUG_STATIC_LEVEL
90565 +#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)"
90566 +#else
90567 +int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL;
90568 +#endif /* DEBUG_STATIC_LEVEL */
90569 +#endif /* !DEBUG_DYNAMIC_LEVEL */
90570 +
90571 +
90572 +#ifndef ERROR_DYNAMIC_LEVEL
90573 +
90574 +#ifdef ERROR_STATIC_LEVEL
90575 +#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL
90576 +#else
90577 +#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL
90578 +#endif /* ERROR_STATIC_LEVEL */
90579 +
90580 +#else /* ERROR_DYNAMIC_LEVEL */
90581 +#ifdef ERROR_STATIC_LEVEL
90582 +#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)"
90583 +#else
90584 +int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL;
90585 +#endif /* ERROR_STATIC_LEVEL */
90586 +#endif /* !ERROR_DYNAMIC_LEVEL */
90587 +
90588 +#define PRINT_FORMAT "[CPU%02d, %s:%d %s]"
90589 +#define PRINT_FMT_PARAMS raw_smp_processor_id(), __FILE__, __LINE__, __FUNCTION__
90590 +
90591 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
90592 +/* No debug/error/event messages at all */
90593 +#define DBG(_level, _vmsg)
90594 +
90595 +#define REPORT_ERROR(_level, _err, _vmsg)
90596 +
90597 +#define RETURN_ERROR(_level, _err, _vmsg) \
90598 + return ERROR_CODE(_err)
90599 +
90600 +#if (REPORT_EVENTS > 0)
90601 +
90602 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90603 + do { \
90604 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90605 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90606 + } \
90607 + } while (0)
90608 +
90609 +#else
90610 +
90611 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90612 +
90613 +#endif /* (REPORT_EVENTS > 0) */
90614 +
90615 +
90616 +#else /* DEBUG_ERRORS > 0 */
90617 +
90618 +extern const char *dbgLevelStrings[];
90619 +extern const char *moduleStrings[];
90620 +#if (REPORT_EVENTS > 0)
90621 +extern const char *eventStrings[];
90622 +#endif /* (REPORT_EVENTS > 0) */
90623 +
90624 +char * ErrTypeStrings (e_ErrorType err);
90625 +
90626 +
90627 +#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING))
90628 +/* No need for DBG macro - debug level is higher anyway */
90629 +#define DBG(_level, _vmsg)
90630 +#else
90631 +#define DBG(_level, _vmsg) \
90632 + do { \
90633 + if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \
90634 + XX_Print("> %s (%s) " PRINT_FORMAT ": ", \
90635 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90636 + moduleStrings[__ERR_MODULE__ >> 16], \
90637 + PRINT_FMT_PARAMS); \
90638 + XX_Print _vmsg; \
90639 + XX_Print("\r\n"); \
90640 + } \
90641 + } while (0)
90642 +#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */
90643 +
90644 +
90645 +#define REPORT_ERROR(_level, _err, _vmsg) \
90646 + do { \
90647 + if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \
90648 + XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \
90649 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90650 + moduleStrings[__ERR_MODULE__ >> 16], \
90651 + PRINT_FMT_PARAMS, \
90652 + ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \
90653 + XX_Print _vmsg; \
90654 + XX_Print("\r\n"); \
90655 + } \
90656 + } while (0)
90657 +
90658 +
90659 +#define RETURN_ERROR(_level, _err, _vmsg) \
90660 + do { \
90661 + REPORT_ERROR(_level, (_err), _vmsg); \
90662 + return ERROR_CODE(_err); \
90663 + } while (0)
90664 +
90665 +
90666 +#if (REPORT_EVENTS > 0)
90667 +
90668 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90669 + do { \
90670 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90671 + XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \
90672 + dbgLevelStrings[_ev##_LEVEL - 1], \
90673 + moduleStrings[__ERR_MODULE__ >> 16], \
90674 + PRINT_FMT_PARAMS, \
90675 + eventStrings[((_ev) - EV_NO_EVENT - 1)], \
90676 + (uint16_t)(_flg)); \
90677 + XX_Print _vmsg; \
90678 + XX_Print("\r\n"); \
90679 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90680 + } \
90681 + } while (0)
90682 +
90683 +#else /* not REPORT_EVENTS */
90684 +
90685 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90686 +
90687 +#endif /* (REPORT_EVENTS > 0) */
90688 +
90689 +#endif /* (DEBUG_ERRORS > 0) */
90690 +
90691 +
90692 +/**************************************************************************//**
90693 + @Function ASSERT_COND
90694 +
90695 + @Description Assertion macro.
90696 +
90697 + @Param[in] _cond - The condition being checked, in positive form;
90698 + Failure of the condition triggers the assert.
90699 +*//***************************************************************************/
90700 +#ifdef DISABLE_ASSERTIONS
90701 +#define ASSERT_COND(_cond)
90702 +#else
90703 +#define ASSERT_COND(_cond) \
90704 + do { \
90705 + if (!(_cond)) { \
90706 + XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \
90707 + PRINT_FMT_PARAMS); \
90708 + XX_Exit(1); \
90709 + } \
90710 + } while (0)
90711 +#endif /* DISABLE_ASSERTIONS */
90712 +
90713 +
90714 +#ifdef DISABLE_INIT_PARAMETERS_CHECK
90715 +
90716 +#define CHECK_INIT_PARAMETERS(handle, f_check)
90717 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval)
90718 +
90719 +#else
90720 +
90721 +#define CHECK_INIT_PARAMETERS(handle, f_check) \
90722 + do { \
90723 + t_Error err = f_check(handle); \
90724 + if (err != E_OK) { \
90725 + RETURN_ERROR(MAJOR, err, NO_MSG); \
90726 + } \
90727 + } while (0)
90728 +
90729 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \
90730 + do { \
90731 + t_Error err = f_check(handle); \
90732 + if (err != E_OK) { \
90733 + REPORT_ERROR(MAJOR, err, NO_MSG); \
90734 + return (retval); \
90735 + } \
90736 + } while (0)
90737 +
90738 +#endif /* DISABLE_INIT_PARAMETERS_CHECK */
90739 +
90740 +#ifdef DISABLE_SANITY_CHECKS
90741 +
90742 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err)
90743 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval)
90744 +#define SANITY_CHECK_RETURN(_cond, _err)
90745 +#define SANITY_CHECK_EXIT(_cond, _err)
90746 +
90747 +#else /* DISABLE_SANITY_CHECKS */
90748 +
90749 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \
90750 + do { \
90751 + if (!(_cond)) { \
90752 + RETURN_ERROR(CRITICAL, (_err), NO_MSG); \
90753 + } \
90754 + } while (0)
90755 +
90756 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \
90757 + do { \
90758 + if (!(_cond)) { \
90759 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90760 + return (retval); \
90761 + } \
90762 + } while (0)
90763 +
90764 +#define SANITY_CHECK_RETURN(_cond, _err) \
90765 + do { \
90766 + if (!(_cond)) { \
90767 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90768 + return; \
90769 + } \
90770 + } while (0)
90771 +
90772 +#define SANITY_CHECK_EXIT(_cond, _err) \
90773 + do { \
90774 + if (!(_cond)) { \
90775 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90776 + XX_Exit(1); \
90777 + } \
90778 + } while (0)
90779 +
90780 +#endif /* DISABLE_SANITY_CHECKS */
90781 +
90782 +/** @} */ /* end of Debug/error Utils group */
90783 +
90784 +/** @} */ /* end of General Utils group */
90785 +
90786 +#endif /* __ERROR_EXT_H */
90787 +
90788 +
90789 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
90790 new file mode 100644
90791 index 00000000..ee6b9f29
90792 --- /dev/null
90793 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
90794 @@ -0,0 +1,358 @@
90795 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90796 + * All rights reserved.
90797 + *
90798 + * Redistribution and use in source and binary forms, with or without
90799 + * modification, are permitted provided that the following conditions are met:
90800 + * * Redistributions of source code must retain the above copyright
90801 + * notice, this list of conditions and the following disclaimer.
90802 + * * Redistributions in binary form must reproduce the above copyright
90803 + * notice, this list of conditions and the following disclaimer in the
90804 + * documentation and/or other materials provided with the distribution.
90805 + * * Neither the name of Freescale Semiconductor nor the
90806 + * names of its contributors may be used to endorse or promote products
90807 + * derived from this software without specific prior written permission.
90808 + *
90809 + *
90810 + * ALTERNATIVELY, this software may be distributed under the terms of the
90811 + * GNU General Public License ("GPL") as published by the Free Software
90812 + * Foundation, either version 2 of that License or (at your option) any
90813 + * later version.
90814 + *
90815 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90816 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90817 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90818 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90819 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90820 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90821 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90822 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90823 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90824 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90825 + */
90826 +
90827 +
90828 +/**************************************************************************//**
90829 +
90830 + @File list_ext.h
90831 +
90832 + @Description External prototypes for list.c
90833 +*//***************************************************************************/
90834 +
90835 +#ifndef __LIST_EXT_H
90836 +#define __LIST_EXT_H
90837 +
90838 +
90839 +#include "std_ext.h"
90840 +
90841 +
90842 +/**************************************************************************//**
90843 + @Group etc_id Utility Library Application Programming Interface
90844 +
90845 + @Description External routines.
90846 +
90847 + @{
90848 +*//***************************************************************************/
90849 +
90850 +/**************************************************************************//**
90851 + @Group list_id List
90852 +
90853 + @Description List module functions,definitions and enums.
90854 +
90855 + @{
90856 +*//***************************************************************************/
90857 +
90858 +/**************************************************************************//**
90859 + @Description List structure.
90860 +*//***************************************************************************/
90861 +typedef struct List
90862 +{
90863 + struct List *p_Next; /**< A pointer to the next list object */
90864 + struct List *p_Prev; /**< A pointer to the previous list object */
90865 +} t_List;
90866 +
90867 +
90868 +/**************************************************************************//**
90869 + @Function LIST_FIRST/LIST_LAST/LIST_NEXT/LIST_PREV
90870 +
90871 + @Description Macro to get first/last/next/previous entry in a list.
90872 +
90873 + @Param[in] p_List - A pointer to a list.
90874 +*//***************************************************************************/
90875 +#define LIST_FIRST(p_List) (p_List)->p_Next
90876 +#define LIST_LAST(p_List) (p_List)->p_Prev
90877 +#define LIST_NEXT LIST_FIRST
90878 +#define LIST_PREV LIST_LAST
90879 +
90880 +
90881 +/**************************************************************************//**
90882 + @Function LIST_INIT
90883 +
90884 + @Description Macro for initialization of a list struct.
90885 +
90886 + @Param[in] lst - The t_List object to initialize.
90887 +*//***************************************************************************/
90888 +#define LIST_INIT(lst) {&(lst), &(lst)}
90889 +
90890 +
90891 +/**************************************************************************//**
90892 + @Function LIST
90893 +
90894 + @Description Macro to declare of a list.
90895 +
90896 + @Param[in] listName - The list object name.
90897 +*//***************************************************************************/
90898 +#define LIST(listName) t_List listName = LIST_INIT(listName)
90899 +
90900 +
90901 +/**************************************************************************//**
90902 + @Function INIT_LIST
90903 +
90904 + @Description Macro to initialize a list pointer.
90905 +
90906 + @Param[in] p_List - The list pointer.
90907 +*//***************************************************************************/
90908 +#define INIT_LIST(p_List) LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List)
90909 +
90910 +
90911 +/**************************************************************************//**
90912 + @Function LIST_OBJECT
90913 +
90914 + @Description Macro to get the struct (object) for this entry.
90915 +
90916 + @Param[in] type - The type of the struct (object) this list is embedded in.
90917 + @Param[in] member - The name of the t_List object within the struct.
90918 +
90919 + @Return The structure pointer for this entry.
90920 +*//***************************************************************************/
90921 +#define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member))
90922 +#define LIST_OBJECT(p_List, type, member) \
90923 + ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member)))
90924 +
90925 +
90926 +/**************************************************************************//**
90927 + @Function LIST_FOR_EACH
90928 +
90929 + @Description Macro to iterate over a list.
90930 +
90931 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90932 + @Param[in] p_Head - A pointer to the head for your list pointer.
90933 +
90934 + @Cautions You can't delete items with this routine.
90935 + For deletion use LIST_FOR_EACH_SAFE().
90936 +*//***************************************************************************/
90937 +#define LIST_FOR_EACH(p_Pos, p_Head) \
90938 + for (p_Pos = LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = LIST_NEXT(p_Pos))
90939 +
90940 +
90941 +/**************************************************************************//**
90942 + @Function LIST_FOR_EACH_SAFE
90943 +
90944 + @Description Macro to iterate over a list safe against removal of list entry.
90945 +
90946 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90947 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90948 + @Param[in] p_Head - A pointer to the head for your list pointer.
90949 +*//***************************************************************************/
90950 +#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \
90951 + for (p_Pos = LIST_FIRST(p_Head), p_Tmp = LIST_FIRST(p_Pos); \
90952 + p_Pos != (p_Head); \
90953 + p_Pos = p_Tmp, p_Tmp = LIST_NEXT(p_Pos))
90954 +
90955 +
90956 +/**************************************************************************//**
90957 + @Function LIST_FOR_EACH_OBJECT_SAFE
90958 +
90959 + @Description Macro to iterate over list of given type safely.
90960 +
90961 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90962 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90963 + @Param[in] type - The type of the struct this is embedded in.
90964 + @Param[in] p_Head - A pointer to the head for your list pointer.
90965 + @Param[in] member - The name of the list_struct within the struct.
90966 +
90967 + @Cautions You can't delete items with this routine.
90968 + For deletion use LIST_FOR_EACH_SAFE().
90969 +*//***************************************************************************/
90970 +#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \
90971 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member), \
90972 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member); \
90973 + &p_Pos->member != (p_Head); \
90974 + p_Pos = p_Tmp, \
90975 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member))
90976 +
90977 +/**************************************************************************//**
90978 + @Function LIST_FOR_EACH_OBJECT
90979 +
90980 + @Description Macro to iterate over list of given type.
90981 +
90982 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90983 + @Param[in] type - The type of the struct this is embedded in.
90984 + @Param[in] p_Head - A pointer to the head for your list pointer.
90985 + @Param[in] member - The name of the list_struct within the struct.
90986 +
90987 + @Cautions You can't delete items with this routine.
90988 + For deletion use LIST_FOR_EACH_SAFE().
90989 +*//***************************************************************************/
90990 +#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \
90991 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member); \
90992 + &p_Pos->member != (p_Head); \
90993 + p_Pos = LIST_OBJECT(LIST_FIRST(&(p_Pos->member)), type, member))
90994 +
90995 +
90996 +/**************************************************************************//**
90997 + @Function LIST_Add
90998 +
90999 + @Description Add a new entry to a list.
91000 +
91001 + Insert a new entry after the specified head.
91002 + This is good for implementing stacks.
91003 +
91004 + @Param[in] p_New - A pointer to a new list entry to be added.
91005 + @Param[in] p_Head - A pointer to a list head to add it after.
91006 +
91007 + @Return none.
91008 +*//***************************************************************************/
91009 +static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head)
91010 +{
91011 + LIST_PREV(LIST_NEXT(p_Head)) = p_New;
91012 + LIST_NEXT(p_New) = LIST_NEXT(p_Head);
91013 + LIST_PREV(p_New) = p_Head;
91014 + LIST_NEXT(p_Head) = p_New;
91015 +}
91016 +
91017 +
91018 +/**************************************************************************//**
91019 + @Function LIST_AddToTail
91020 +
91021 + @Description Add a new entry to a list.
91022 +
91023 + Insert a new entry before the specified head.
91024 + This is useful for implementing queues.
91025 +
91026 + @Param[in] p_New - A pointer to a new list entry to be added.
91027 + @Param[in] p_Head - A pointer to a list head to add it before.
91028 +
91029 + @Return none.
91030 +*//***************************************************************************/
91031 +static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head)
91032 +{
91033 + LIST_NEXT(LIST_PREV(p_Head)) = p_New;
91034 + LIST_PREV(p_New) = LIST_PREV(p_Head);
91035 + LIST_NEXT(p_New) = p_Head;
91036 + LIST_PREV(p_Head) = p_New;
91037 +}
91038 +
91039 +
91040 +/**************************************************************************//**
91041 + @Function LIST_Del
91042 +
91043 + @Description Deletes entry from a list.
91044 +
91045 + @Param[in] p_Entry - A pointer to the element to delete from the list.
91046 +
91047 + @Return none.
91048 +
91049 + @Cautions LIST_IsEmpty() on entry does not return true after this,
91050 + the entry is in an undefined state.
91051 +*//***************************************************************************/
91052 +static __inline__ void LIST_Del(t_List *p_Entry)
91053 +{
91054 + LIST_PREV(LIST_NEXT(p_Entry)) = LIST_PREV(p_Entry);
91055 + LIST_NEXT(LIST_PREV(p_Entry)) = LIST_NEXT(p_Entry);
91056 +}
91057 +
91058 +
91059 +/**************************************************************************//**
91060 + @Function LIST_DelAndInit
91061 +
91062 + @Description Deletes entry from list and reinitialize it.
91063 +
91064 + @Param[in] p_Entry - A pointer to the element to delete from the list.
91065 +
91066 + @Return none.
91067 +*//***************************************************************************/
91068 +static __inline__ void LIST_DelAndInit(t_List *p_Entry)
91069 +{
91070 + LIST_Del(p_Entry);
91071 + INIT_LIST(p_Entry);
91072 +}
91073 +
91074 +
91075 +/**************************************************************************//**
91076 + @Function LIST_Move
91077 +
91078 + @Description Delete from one list and add as another's head.
91079 +
91080 + @Param[in] p_Entry - A pointer to the list entry to move.
91081 + @Param[in] p_Head - A pointer to the list head that will precede our entry.
91082 +
91083 + @Return none.
91084 +*//***************************************************************************/
91085 +static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head)
91086 +{
91087 + LIST_Del(p_Entry);
91088 + LIST_Add(p_Entry, p_Head);
91089 +}
91090 +
91091 +
91092 +/**************************************************************************//**
91093 + @Function LIST_MoveToTail
91094 +
91095 + @Description Delete from one list and add as another's tail.
91096 +
91097 + @Param[in] p_Entry - A pointer to the entry to move.
91098 + @Param[in] p_Head - A pointer to the list head that will follow our entry.
91099 +
91100 + @Return none.
91101 +*//***************************************************************************/
91102 +static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head)
91103 +{
91104 + LIST_Del(p_Entry);
91105 + LIST_AddToTail(p_Entry, p_Head);
91106 +}
91107 +
91108 +
91109 +/**************************************************************************//**
91110 + @Function LIST_IsEmpty
91111 +
91112 + @Description Tests whether a list is empty.
91113 +
91114 + @Param[in] p_List - A pointer to the list to test.
91115 +
91116 + @Return 1 if the list is empty, 0 otherwise.
91117 +*//***************************************************************************/
91118 +static __inline__ int LIST_IsEmpty(t_List *p_List)
91119 +{
91120 + return (LIST_FIRST(p_List) == p_List);
91121 +}
91122 +
91123 +
91124 +/**************************************************************************//**
91125 + @Function LIST_Append
91126 +
91127 + @Description Join two lists.
91128 +
91129 + @Param[in] p_NewList - A pointer to the new list to add.
91130 + @Param[in] p_Head - A pointer to the place to add it in the first list.
91131 +
91132 + @Return none.
91133 +*//***************************************************************************/
91134 +void LIST_Append(t_List *p_NewList, t_List *p_Head);
91135 +
91136 +
91137 +/**************************************************************************//**
91138 + @Function LIST_NumOfObjs
91139 +
91140 + @Description Counts number of objects in the list
91141 +
91142 + @Param[in] p_List - A pointer to the list which objects are to be counted.
91143 +
91144 + @Return Number of objects in the list.
91145 +*//***************************************************************************/
91146 +int LIST_NumOfObjs(t_List *p_List);
91147 +
91148 +/** @} */ /* end of list_id group */
91149 +/** @} */ /* end of etc_id group */
91150 +
91151 +
91152 +#endif /* __LIST_EXT_H */
91153 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
91154 new file mode 100644
91155 index 00000000..d0565d41
91156 --- /dev/null
91157 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
91158 @@ -0,0 +1,318 @@
91159 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91160 + * All rights reserved.
91161 + *
91162 + * Redistribution and use in source and binary forms, with or without
91163 + * modification, are permitted provided that the following conditions are met:
91164 + * * Redistributions of source code must retain the above copyright
91165 + * notice, this list of conditions and the following disclaimer.
91166 + * * Redistributions in binary form must reproduce the above copyright
91167 + * notice, this list of conditions and the following disclaimer in the
91168 + * documentation and/or other materials provided with the distribution.
91169 + * * Neither the name of Freescale Semiconductor nor the
91170 + * names of its contributors may be used to endorse or promote products
91171 + * derived from this software without specific prior written permission.
91172 + *
91173 + *
91174 + * ALTERNATIVELY, this software may be distributed under the terms of the
91175 + * GNU General Public License ("GPL") as published by the Free Software
91176 + * Foundation, either version 2 of that License or (at your option) any
91177 + * later version.
91178 + *
91179 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91180 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91181 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91182 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91183 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91184 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91185 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91186 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91187 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91188 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91189 + */
91190 +
91191 +
91192 +/**************************************************************************//**
91193 +
91194 + @File mem_ext.h
91195 +
91196 + @Description External prototypes for the memory manager object
91197 +*//***************************************************************************/
91198 +
91199 +#ifndef __MEM_EXT_H
91200 +#define __MEM_EXT_H
91201 +
91202 +#include "std_ext.h"
91203 +#include "part_ext.h"
91204 +
91205 +
91206 +/**************************************************************************//**
91207 + @Group etc_id Utility Library Application Programming Interface
91208 +
91209 + @Description External routines.
91210 +
91211 + @{
91212 +*//***************************************************************************/
91213 +
91214 +/**************************************************************************//**
91215 + @Group mem_id Slab Memory Manager
91216 +
91217 + @Description Slab Memory Manager module functions, definitions and enums.
91218 +
91219 + @{
91220 +*//***************************************************************************/
91221 +
91222 +/* Each block is of the following structure:
91223 + *
91224 + *
91225 + * +-----------+----------+---------------------------+-----------+-----------+
91226 + * | Alignment | Prefix | Data | Postfix | Alignment |
91227 + * | field | field | field | field | Padding |
91228 + * | | | | | |
91229 + * +-----------+----------+---------------------------+-----------+-----------+
91230 + * and at the beginning of all bytes, an additional optional padding might reside
91231 + * to ensure that the first blocks data field is aligned as requested.
91232 + */
91233 +
91234 +
91235 +#define MEM_MAX_NAME_LENGTH 8
91236 +
91237 +/**************************************************************************//*
91238 + @Description Memory Segment structure
91239 +*//***************************************************************************/
91240 +
91241 +typedef struct
91242 +{
91243 + char name[MEM_MAX_NAME_LENGTH];
91244 + /* The segment's name */
91245 + uint8_t **p_Bases; /* Base addresses of the segments */
91246 + uint8_t **p_BlocksStack; /* Array of pointers to blocks */
91247 + t_Handle h_Spinlock;
91248 + uint16_t dataSize; /* Size of each data block */
91249 + uint16_t prefixSize; /* How many bytes to reserve before the data */
91250 + uint16_t postfixSize; /* How many bytes to reserve after the data */
91251 + uint16_t alignment; /* Requested alignment for the data field */
91252 + int allocOwner; /* Memory allocation owner */
91253 + uint32_t getFailures; /* Number of times get failed */
91254 + uint32_t num; /* Number of blocks in segment */
91255 + uint32_t current; /* Current block */
91256 + bool consecutiveMem; /* Allocate consecutive data blocks memory */
91257 +#ifdef DEBUG_MEM_LEAKS
91258 + void *p_MemDbg; /* MEM debug database (MEM leaks detection) */
91259 + uint32_t blockOffset;
91260 + uint32_t blockSize;
91261 +#endif /* DEBUG_MEM_LEAKS */
91262 +} t_MemorySegment;
91263 +
91264 +
91265 +
91266 +/**************************************************************************//**
91267 + @Function MEM_Init
91268 +
91269 + @Description Create a new memory segment.
91270 +
91271 + @Param[in] name - Name of memory partition.
91272 + @Param[in] p_Handle - Handle to new segment is returned through here.
91273 + @Param[in] num - Number of blocks in new segment.
91274 + @Param[in] dataSize - Size of blocks in segment.
91275 + @Param[in] prefixSize - How many bytes to allocate before the data.
91276 + @Param[in] postfixSize - How many bytes to allocate after the data.
91277 + @Param[in] alignment - Requested alignment for data field (in bytes).
91278 +
91279 + @Return E_OK - success, E_NO_MEMORY - out of memory.
91280 +*//***************************************************************************/
91281 +t_Error MEM_Init(char name[],
91282 + t_Handle *p_Handle,
91283 + uint32_t num,
91284 + uint16_t dataSize,
91285 + uint16_t prefixSize,
91286 + uint16_t postfixSize,
91287 + uint16_t alignment);
91288 +
91289 +/**************************************************************************//**
91290 + @Function MEM_InitSmart
91291 +
91292 + @Description Create a new memory segment.
91293 +
91294 + @Param[in] name - Name of memory partition.
91295 + @Param[in] p_Handle - Handle to new segment is returned through here.
91296 + @Param[in] num - Number of blocks in new segment.
91297 + @Param[in] dataSize - Size of blocks in segment.
91298 + @Param[in] prefixSize - How many bytes to allocate before the data.
91299 + @Param[in] postfixSize - How many bytes to allocate after the data.
91300 + @Param[in] alignment - Requested alignment for data field (in bytes).
91301 + @Param[in] memPartitionId - Memory partition ID for allocation.
91302 + @Param[in] consecutiveMem - Whether to allocate the memory blocks
91303 + continuously or not.
91304 +
91305 + @Return E_OK - success, E_NO_MEMORY - out of memory.
91306 +*//***************************************************************************/
91307 +t_Error MEM_InitSmart(char name[],
91308 + t_Handle *p_Handle,
91309 + uint32_t num,
91310 + uint16_t dataSize,
91311 + uint16_t prefixSize,
91312 + uint16_t postfixSize,
91313 + uint16_t alignment,
91314 + uint8_t memPartitionId,
91315 + bool consecutiveMem);
91316 +
91317 +/**************************************************************************//**
91318 + @Function MEM_InitByAddress
91319 +
91320 + @Description Create a new memory segment with a specified base address.
91321 +
91322 + @Param[in] name - Name of memory partition.
91323 + @Param[in] p_Handle - Handle to new segment is returned through here.
91324 + @Param[in] num - Number of blocks in new segment.
91325 + @Param[in] dataSize - Size of blocks in segment.
91326 + @Param[in] prefixSize - How many bytes to allocate before the data.
91327 + @Param[in] postfixSize - How many bytes to allocate after the data.
91328 + @Param[in] alignment - Requested alignment for data field (in bytes).
91329 + @Param[in] address - The required base address.
91330 +
91331 + @Return E_OK - success, E_NO_MEMORY - out of memory.
91332 + *//***************************************************************************/
91333 +t_Error MEM_InitByAddress(char name[],
91334 + t_Handle *p_Handle,
91335 + uint32_t num,
91336 + uint16_t dataSize,
91337 + uint16_t prefixSize,
91338 + uint16_t postfixSize,
91339 + uint16_t alignment,
91340 + uint8_t *address);
91341 +
91342 +/**************************************************************************//**
91343 + @Function MEM_Free
91344 +
91345 + @Description Free a specific memory segment.
91346 +
91347 + @Param[in] h_Mem - Handle to memory segment.
91348 +
91349 + @Return None.
91350 +*//***************************************************************************/
91351 +void MEM_Free(t_Handle h_Mem);
91352 +
91353 +/**************************************************************************//**
91354 + @Function MEM_Get
91355 +
91356 + @Description Get a block of memory from a segment.
91357 +
91358 + @Param[in] h_Mem - Handle to memory segment.
91359 +
91360 + @Return Pointer to new memory block on success,0 otherwise.
91361 +*//***************************************************************************/
91362 +void * MEM_Get(t_Handle h_Mem);
91363 +
91364 +/**************************************************************************//**
91365 + @Function MEM_GetN
91366 +
91367 + @Description Get up to N blocks of memory from a segment.
91368 +
91369 + The blocks are assumed to be of a fixed size (one size per segment).
91370 +
91371 + @Param[in] h_Mem - Handle to memory segment.
91372 + @Param[in] num - Number of blocks to allocate.
91373 + @Param[out] array - Array of at least num pointers to which the addresses
91374 + of the allocated blocks are written.
91375 +
91376 + @Return The number of blocks actually allocated.
91377 +
91378 + @Cautions Interrupts are disabled for all of the allocation loop.
91379 + Although this loop is very short for each block (several machine
91380 + instructions), you should not allocate a very large number
91381 + of blocks via this routine.
91382 +*//***************************************************************************/
91383 +uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
91384 +
91385 +/**************************************************************************//**
91386 + @Function MEM_Put
91387 +
91388 + @Description Put a block of memory back to a segment.
91389 +
91390 + @Param[in] h_Mem - Handle to memory segment.
91391 + @Param[in] p_Block - The block to return.
91392 +
91393 + @Return Pointer to new memory block on success,0 otherwise.
91394 +*//***************************************************************************/
91395 +t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
91396 +
91397 +/**************************************************************************//**
91398 + @Function MEM_ComputePartitionSize
91399 +
91400 + @Description calculate a tight upper boundary of the size of a partition with
91401 + given attributes.
91402 +
91403 + The returned value is suitable if one wants to use MEM_InitByAddress().
91404 +
91405 + @Param[in] num - The number of blocks in the segment.
91406 + @Param[in] dataSize - Size of block to get.
91407 + @Param[in] prefixSize - The prefix size
91408 + @Param postfixSize - The postfix size
91409 + @Param[in] alignment - The requested alignment value (in bytes)
91410 +
91411 + @Return The memory block size a segment with the given attributes needs.
91412 +*//***************************************************************************/
91413 +uint32_t MEM_ComputePartitionSize(uint32_t num,
91414 + uint16_t dataSize,
91415 + uint16_t prefixSize,
91416 + uint16_t postfixSize,
91417 + uint16_t alignment);
91418 +
91419 +#ifdef DEBUG_MEM_LEAKS
91420 +#if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi))
91421 +#error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
91422 +#endif /* !(defined(__MWERKS__) && ... */
91423 +
91424 +/**************************************************************************//**
91425 + @Function MEM_CheckLeaks
91426 +
91427 + @Description Report MEM object leaks.
91428 +
91429 + This routine is automatically called by the MEM_Free() routine,
91430 + but it can also be invoked while the MEM object is alive.
91431 +
91432 + @Param[in] h_Mem - Handle to memory segment.
91433 +
91434 + @Return None.
91435 +*//***************************************************************************/
91436 +void MEM_CheckLeaks(t_Handle h_Mem);
91437 +
91438 +#else /* not DEBUG_MEM_LEAKS */
91439 +#define MEM_CheckLeaks(h_Mem)
91440 +#endif /* not DEBUG_MEM_LEAKS */
91441 +
91442 +/**************************************************************************//**
91443 + @Description Get base of MEM
91444 +*//***************************************************************************/
91445 +#define MEM_GetBase(h_Mem) ((t_MemorySegment *)(h_Mem))->p_Bases[0]
91446 +
91447 +/**************************************************************************//**
91448 + @Description Get size of MEM block
91449 +*//***************************************************************************/
91450 +#define MEM_GetSize(h_Mem) ((t_MemorySegment *)(h_Mem))->dataSize
91451 +
91452 +/**************************************************************************//**
91453 + @Description Get prefix size of MEM block
91454 +*//***************************************************************************/
91455 +#define MEM_GetPrefixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->prefixSize
91456 +
91457 +/**************************************************************************//**
91458 + @Description Get postfix size of MEM block
91459 +*//***************************************************************************/
91460 +#define MEM_GetPostfixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->postfixSize
91461 +
91462 +/**************************************************************************//**
91463 + @Description Get alignment of MEM block (in bytes)
91464 +*//***************************************************************************/
91465 +#define MEM_GetAlignment(h_Mem) ((t_MemorySegment *)(h_Mem))->alignment
91466 +
91467 +/**************************************************************************//**
91468 + @Description Get the number of blocks in the segment
91469 +*//***************************************************************************/
91470 +#define MEM_GetNumOfBlocks(h_Mem) ((t_MemorySegment *)(h_Mem))->num
91471 +
91472 +/** @} */ /* end of MEM group */
91473 +/** @} */ /* end of etc_id group */
91474 +
91475 +
91476 +#endif /* __MEM_EXT_H */
91477 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
91478 new file mode 100644
91479 index 00000000..1b3a2fac
91480 --- /dev/null
91481 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
91482 @@ -0,0 +1,208 @@
91483 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91484 + * All rights reserved.
91485 + *
91486 + * Redistribution and use in source and binary forms, with or without
91487 + * modification, are permitted provided that the following conditions are met:
91488 + * * Redistributions of source code must retain the above copyright
91489 + * notice, this list of conditions and the following disclaimer.
91490 + * * Redistributions in binary form must reproduce the above copyright
91491 + * notice, this list of conditions and the following disclaimer in the
91492 + * documentation and/or other materials provided with the distribution.
91493 + * * Neither the name of Freescale Semiconductor nor the
91494 + * names of its contributors may be used to endorse or promote products
91495 + * derived from this software without specific prior written permission.
91496 + *
91497 + *
91498 + * ALTERNATIVELY, this software may be distributed under the terms of the
91499 + * GNU General Public License ("GPL") as published by the Free Software
91500 + * Foundation, either version 2 of that License or (at your option) any
91501 + * later version.
91502 + *
91503 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91504 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91505 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91506 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91507 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91508 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91509 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91510 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91511 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91512 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91513 + */
91514 +
91515 +
91516 +/**************************************************************************//**
91517 +
91518 + @File memcpy_ext.h
91519 +
91520 + @Description Efficient functions for copying and setting blocks of memory.
91521 +*//***************************************************************************/
91522 +
91523 +#ifndef __MEMCPY_EXT_H
91524 +#define __MEMCPY_EXT_H
91525 +
91526 +#include "std_ext.h"
91527 +
91528 +
91529 +/**************************************************************************//**
91530 + @Group etc_id Utility Library Application Programming Interface
91531 +
91532 + @Description External routines.
91533 +
91534 + @{
91535 +*//***************************************************************************/
91536 +
91537 +/**************************************************************************//**
91538 + @Group mem_cpy Memory Copy
91539 +
91540 + @Description Memory Copy module functions,definitions and enums.
91541 +
91542 + @{
91543 +*//***************************************************************************/
91544 +
91545 +/**************************************************************************//**
91546 + @Function MemCpy32
91547 +
91548 + @Description Copies one memory buffer into another one in 4-byte chunks!
91549 + Which should be more efficient than byte by byte.
91550 +
91551 + For large buffers (over 60 bytes) this function is about 4 times
91552 + more efficient than the trivial memory copy. For short buffers
91553 + it is reduced to the trivial copy and may be a bit worse.
91554 +
91555 + @Param[in] pDst - The address of the destination buffer.
91556 + @Param[in] pSrc - The address of the source buffer.
91557 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91558 +
91559 + @Return pDst (the address of the destination buffer).
91560 +
91561 + @Cautions There is no parameter or boundary checking! It is up to the user
91562 + to supply non-null parameters as source & destination and size
91563 + that actually fits into the destination buffer.
91564 +*//***************************************************************************/
91565 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size);
91566 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91567 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size);
91568 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91569 +
91570 +/**************************************************************************//**
91571 + @Function MemCpy64
91572 +
91573 + @Description Copies one memory buffer into another one in 8-byte chunks!
91574 + Which should be more efficient than byte by byte.
91575 +
91576 + For large buffers (over 60 bytes) this function is about 8 times
91577 + more efficient than the trivial memory copy. For short buffers
91578 + it is reduced to the trivial copy and may be a bit worse.
91579 +
91580 + Some testing suggests that MemCpy32() preforms better than
91581 + MemCpy64() over small buffers. On average they break even at
91582 + 100 byte buffers. For buffers larger than that MemCpy64 is
91583 + superior.
91584 +
91585 + @Param[in] pDst - The address of the destination buffer.
91586 + @Param[in] pSrc - The address of the source buffer.
91587 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91588 +
91589 + @Return pDst (the address of the destination buffer).
91590 +
91591 + @Cautions There is no parameter or boundary checking! It is up to the user
91592 + to supply non null parameters as source & destination and size
91593 + that actually fits into their buffer.
91594 +
91595 + Do not use under Linux.
91596 +*//***************************************************************************/
91597 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size);
91598 +
91599 +/**************************************************************************//**
91600 + @Function MemSet32
91601 +
91602 + @Description Sets all bytes of a memory buffer to a specific value, in
91603 + 4-byte chunks.
91604 +
91605 + @Param[in] pDst - The address of the destination buffer.
91606 + @Param[in] val - Value to set destination bytes to.
91607 + @Param[in] size - The number of bytes that will be set to val.
91608 +
91609 + @Return pDst (the address of the destination buffer).
91610 +
91611 + @Cautions There is no parameter or boundary checking! It is up to the user
91612 + to supply non null parameter as destination and size
91613 + that actually fits into the destination buffer.
91614 +*//***************************************************************************/
91615 +void * MemSet32(void* pDst, uint8_t val, uint32_t size);
91616 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size);
91617 +
91618 +/**************************************************************************//**
91619 + @Function MemSet64
91620 +
91621 + @Description Sets all bytes of a memory buffer to a specific value, in
91622 + 8-byte chunks.
91623 +
91624 + @Param[in] pDst - The address of the destination buffer.
91625 + @Param[in] val - Value to set destination bytes to.
91626 + @Param[in] size - The number of bytes that will be set to val.
91627 +
91628 + @Return pDst (the address of the destination buffer).
91629 +
91630 + @Cautions There is no parameter or boundary checking! It is up to the user
91631 + to supply non null parameter as destination and size
91632 + that actually fits into the destination buffer.
91633 +*//***************************************************************************/
91634 +void * MemSet64(void* pDst, uint8_t val, uint32_t size);
91635 +
91636 +/**************************************************************************//**
91637 + @Function MemDisp
91638 +
91639 + @Description Displays a block of memory in chunks of 32 bits.
91640 +
91641 + @Param[in] addr - The address of the memory to display.
91642 + @Param[in] size - The number of bytes that will be displayed.
91643 +
91644 + @Return None.
91645 +
91646 + @Cautions There is no parameter or boundary checking! It is up to the user
91647 + to supply non null parameter as destination and size
91648 + that actually fits into the destination buffer.
91649 +*//***************************************************************************/
91650 +void MemDisp(uint8_t *addr, int size);
91651 +
91652 +/**************************************************************************//**
91653 + @Function MemCpy8
91654 +
91655 + @Description Trivial copy one memory buffer into another byte by byte
91656 +
91657 + @Param[in] pDst - The address of the destination buffer.
91658 + @Param[in] pSrc - The address of the source buffer.
91659 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91660 +
91661 + @Return pDst (the address of the destination buffer).
91662 +
91663 + @Cautions There is no parameter or boundary checking! It is up to the user
91664 + to supply non-null parameters as source & destination and size
91665 + that actually fits into the destination buffer.
91666 +*//***************************************************************************/
91667 +void * MemCpy8(void* pDst,void* pSrc, uint32_t size);
91668 +
91669 +/**************************************************************************//**
91670 + @Function MemSet8
91671 +
91672 + @Description Sets all bytes of a memory buffer to a specific value byte by byte.
91673 +
91674 + @Param[in] pDst - The address of the destination buffer.
91675 + @Param[in] c - Value to set destination bytes to.
91676 + @Param[in] size - The number of bytes that will be set to val.
91677 +
91678 + @Return pDst (the address of the destination buffer).
91679 +
91680 + @Cautions There is no parameter or boundary checking! It is up to the user
91681 + to supply non null parameter as destination and size
91682 + that actually fits into the destination buffer.
91683 +*//***************************************************************************/
91684 +void * MemSet8(void* pDst, int c, uint32_t size);
91685 +
91686 +/** @} */ /* end of mem_cpy group */
91687 +/** @} */ /* end of etc_id group */
91688 +
91689 +
91690 +#endif /* __MEMCPY_EXT_H */
91691 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
91692 new file mode 100644
91693 index 00000000..fa7c85e3
91694 --- /dev/null
91695 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
91696 @@ -0,0 +1,310 @@
91697 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91698 + * All rights reserved.
91699 + *
91700 + * Redistribution and use in source and binary forms, with or without
91701 + * modification, are permitted provided that the following conditions are met:
91702 + * * Redistributions of source code must retain the above copyright
91703 + * notice, this list of conditions and the following disclaimer.
91704 + * * Redistributions in binary form must reproduce the above copyright
91705 + * notice, this list of conditions and the following disclaimer in the
91706 + * documentation and/or other materials provided with the distribution.
91707 + * * Neither the name of Freescale Semiconductor nor the
91708 + * names of its contributors may be used to endorse or promote products
91709 + * derived from this software without specific prior written permission.
91710 + *
91711 + *
91712 + * ALTERNATIVELY, this software may be distributed under the terms of the
91713 + * GNU General Public License ("GPL") as published by the Free Software
91714 + * Foundation, either version 2 of that License or (at your option) any
91715 + * later version.
91716 + *
91717 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91718 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91719 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91720 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91721 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91722 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91723 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91724 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91725 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91726 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91727 + */
91728 +
91729 +
91730 +/**************************************************************************//**
91731 + @File mm_ext.h
91732 +
91733 + @Description Memory Manager Application Programming Interface
91734 +*//***************************************************************************/
91735 +#ifndef __MM_EXT
91736 +#define __MM_EXT
91737 +
91738 +#include "std_ext.h"
91739 +
91740 +#define MM_MAX_ALIGNMENT 20 /* Alignments from 2 to 128 are available
91741 + where maximum alignment defined as
91742 + MM_MAX_ALIGNMENT power of 2 */
91743 +
91744 +#define MM_MAX_NAME_LEN 32
91745 +
91746 +/**************************************************************************//**
91747 + @Group etc_id Utility Library Application Programming Interface
91748 +
91749 + @Description External routines.
91750 +
91751 + @{
91752 +*//***************************************************************************/
91753 +
91754 +/**************************************************************************//**
91755 + @Group mm_grp Flexible Memory Manager
91756 +
91757 + @Description Flexible Memory Manager module functions,definitions and enums.
91758 + (All of the following functions,definitions and enums can be found in mm_ext.h)
91759 +
91760 + @{
91761 +*//***************************************************************************/
91762 +
91763 +
91764 +/**************************************************************************//**
91765 + @Function MM_Init
91766 +
91767 + @Description Initializes a new MM object.
91768 +
91769 + It initializes a new memory block consisting of base address
91770 + and size of the available memory by calling to MemBlock_Init
91771 + routine. It is also initializes a new free block for each
91772 + by calling FreeBlock_Init routine, which is pointed to
91773 + the almost all memory started from the required alignment
91774 + from the base address and to the end of the memory.
91775 + The handle to the new MM object is returned via "MM"
91776 + argument (passed by reference).
91777 +
91778 + @Param[in] h_MM - Handle to the MM object.
91779 + @Param[in] base - Base address of the MM.
91780 + @Param[in] size - Size of the MM.
91781 +
91782 + @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.
91783 +*//***************************************************************************/
91784 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size);
91785 +
91786 +/**************************************************************************//**
91787 + @Function MM_Get
91788 +
91789 + @Description Allocates a block of memory according to the given size and the alignment.
91790 +
91791 + The Alignment argument tells from which
91792 + free list allocate a block of memory. 2^alignment indicates
91793 + the alignment that the base address of the allocated block
91794 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91795 + are available for the alignment argument.
91796 + The routine passes through the specific free list of free
91797 + blocks and seeks for a first block that have anough memory
91798 + that is required (best fit).
91799 + After the block is found and data is allocated, it calls
91800 + the internal MM_CutFree routine to update all free lists
91801 + do not include a just allocated block. Of course, each
91802 + free list contains a free blocks with the same alignment.
91803 + It is also creates a busy block that holds
91804 + information about an allocated block.
91805 +
91806 + @Param[in] h_MM - Handle to the MM object.
91807 + @Param[in] size - Size of the MM.
91808 + @Param[in] alignment - Index as a power of two defines a required
91809 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91810 + @Param[in] name - The name that specifies an allocated block.
91811 +
91812 + @Return base address of an allocated block ILLEGAL_BASE if can't allocate a block
91813 +*//***************************************************************************/
91814 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char *name);
91815 +
91816 +/**************************************************************************//**
91817 + @Function MM_GetBase
91818 +
91819 + @Description Gets the base address of the required MM objects.
91820 +
91821 + @Param[in] h_MM - Handle to the MM object.
91822 +
91823 + @Return base address of the block.
91824 +*//***************************************************************************/
91825 +uint64_t MM_GetBase(t_Handle h_MM);
91826 +
91827 +/**************************************************************************//**
91828 + @Function MM_GetForce
91829 +
91830 + @Description Force memory allocation.
91831 +
91832 + It means to allocate a block of memory of the given
91833 + size from the given base address.
91834 + The routine checks if the required block can be allocated
91835 + (that is it is free) and then, calls the internal MM_CutFree
91836 + routine to update all free lists do not include that block.
91837 +
91838 + @Param[in] h_MM - Handle to the MM object.
91839 + @Param[in] base - Base address of the MM.
91840 + @Param[in] size - Size of the MM.
91841 + @Param[in] name - Name that specifies an allocated block.
91842 +
91843 + @Return base address of an allocated block, ILLEGAL_BASE if can't allocate a block.
91844 +*//***************************************************************************/
91845 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char *name);
91846 +
91847 +/**************************************************************************//**
91848 + @Function MM_GetForceMin
91849 +
91850 + @Description Allocates a block of memory according to the given size, the alignment and minimum base address.
91851 +
91852 + The Alignment argument tells from which
91853 + free list allocate a block of memory. 2^alignment indicates
91854 + the alignment that the base address of the allocated block
91855 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91856 + are available for the alignment argument.
91857 + The minimum baser address forces the location of the block
91858 + to be from a given address onward.
91859 + The routine passes through the specific free list of free
91860 + blocks and seeks for the first base address equal or smaller
91861 + than the required minimum address and end address larger than
91862 + than the required base + its size - i.e. that may contain
91863 + the required block.
91864 + After the block is found and data is allocated, it calls
91865 + the internal MM_CutFree routine to update all free lists
91866 + do not include a just allocated block. Of course, each
91867 + free list contains a free blocks with the same alignment.
91868 + It is also creates a busy block that holds
91869 + information about an allocated block.
91870 +
91871 + @Param[in] h_MM - Handle to the MM object.
91872 + @Param[in] size - Size of the MM.
91873 + @Param[in] alignment - Index as a power of two defines a required
91874 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91875 + @Param[in] min - The minimum base address of the block.
91876 + @Param[in] name - Name that specifies an allocated block.
91877 +
91878 + @Return base address of an allocated block,ILLEGAL_BASE if can't allocate a block.
91879 +*//***************************************************************************/
91880 +uint64_t MM_GetForceMin(t_Handle h_MM,
91881 + uint64_t size,
91882 + uint64_t alignment,
91883 + uint64_t min,
91884 + char *name);
91885 +
91886 +/**************************************************************************//**
91887 + @Function MM_Put
91888 +
91889 + @Description Puts a block of memory of the given base address back to the memory.
91890 +
91891 + It checks if there is a busy block with the
91892 + given base address. If not, it returns 0, that
91893 + means can't free a block. Otherwise, it gets parameters of
91894 + the busy block and after it updates lists of free blocks,
91895 + removes that busy block from the list by calling to MM_CutBusy
91896 + routine.
91897 + After that it calls to MM_AddFree routine to add a new free
91898 + block to the free lists.
91899 +
91900 + @Param[in] h_MM - Handle to the MM object.
91901 + @Param[in] base - Base address of the MM.
91902 +
91903 + @Return The size of bytes released, 0 if failed.
91904 +*//***************************************************************************/
91905 +uint64_t MM_Put(t_Handle h_MM, uint64_t base);
91906 +
91907 +/**************************************************************************//**
91908 + @Function MM_PutForce
91909 +
91910 + @Description Releases a block of memory of the required size from the required base address.
91911 +
91912 + First, it calls to MM_CutBusy routine
91913 + to cut a free block from the busy list. And then, calls to
91914 + MM_AddFree routine to add the free block to the free lists.
91915 +
91916 + @Param[in] h_MM - Handle to the MM object.
91917 + @Param[in] base - Base address of of a block to free.
91918 + @Param[in] size - Size of a block to free.
91919 +
91920 + @Return The number of bytes released, 0 on failure.
91921 +*//***************************************************************************/
91922 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size);
91923 +
91924 +/**************************************************************************//**
91925 + @Function MM_Add
91926 +
91927 + @Description Adds a new memory block for memory allocation.
91928 +
91929 + When a new memory block is initialized and added to the
91930 + memory list, it calls to MM_AddFree routine to add the
91931 + new free block to the free lists.
91932 +
91933 + @Param[in] h_MM - Handle to the MM object.
91934 + @Param[in] base - Base address of the memory block.
91935 + @Param[in] size - Size of the memory block.
91936 +
91937 + @Return E_OK on success, otherwise returns an error code.
91938 +*//***************************************************************************/
91939 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size);
91940 +
91941 +/**************************************************************************//**
91942 + @Function MM_Dump
91943 +
91944 + @Description Prints results of free and busy lists.
91945 +
91946 + @Param[in] h_MM - Handle to the MM object.
91947 +*//***************************************************************************/
91948 +void MM_Dump(t_Handle h_MM);
91949 +
91950 +/**************************************************************************//**
91951 + @Function MM_Free
91952 +
91953 + @Description Releases memory allocated for MM object.
91954 +
91955 + @Param[in] h_MM - Handle of the MM object.
91956 +*//***************************************************************************/
91957 +void MM_Free(t_Handle h_MM);
91958 +
91959 +/**************************************************************************//**
91960 + @Function MM_GetMemBlock
91961 +
91962 + @Description Returns base address of the memory block specified by the index.
91963 +
91964 + If index is 0, returns base address
91965 + of the first memory block, 1 - returns base address
91966 + of the second memory block, etc.
91967 + Note, those memory blocks are allocated by the
91968 + application before MM_Init or MM_Add and have to
91969 + be released by the application before or after invoking
91970 + the MM_Free routine.
91971 +
91972 + @Param[in] h_MM - Handle to the MM object.
91973 + @Param[in] index - Index of the memory block.
91974 +
91975 + @Return valid base address or ILLEGAL_BASE if no memory block specified by the index.
91976 +*//***************************************************************************/
91977 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index);
91978 +
91979 +/**************************************************************************//**
91980 + @Function MM_InRange
91981 +
91982 + @Description Checks if a specific address is in the memory range of the passed MM object.
91983 +
91984 + @Param[in] h_MM - Handle to the MM object.
91985 + @Param[in] addr - The address to be checked.
91986 +
91987 + @Return TRUE if the address is in the address range of the block, FALSE otherwise.
91988 +*//***************************************************************************/
91989 +bool MM_InRange(t_Handle h_MM, uint64_t addr);
91990 +
91991 +/**************************************************************************//**
91992 + @Function MM_GetFreeMemSize
91993 +
91994 + @Description Returns the size (in bytes) of free memory.
91995 +
91996 + @Param[in] h_MM - Handle to the MM object.
91997 +
91998 + @Return Free memory size in bytes.
91999 +*//***************************************************************************/
92000 +uint64_t MM_GetFreeMemSize(t_Handle h_MM);
92001 +
92002 +
92003 +/** @} */ /* end of mm_grp group */
92004 +/** @} */ /* end of etc_id group */
92005 +
92006 +#endif /* __MM_EXT_H */
92007 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
92008 new file mode 100644
92009 index 00000000..52f7a9dc
92010 --- /dev/null
92011 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
92012 @@ -0,0 +1,118 @@
92013 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
92014 + * All rights reserved.
92015 + *
92016 + * Redistribution and use in source and binary forms, with or without
92017 + * modification, are permitted provided that the following conditions are met:
92018 + * * Redistributions of source code must retain the above copyright
92019 + * notice, this list of conditions and the following disclaimer.
92020 + * * Redistributions in binary form must reproduce the above copyright
92021 + * notice, this list of conditions and the following disclaimer in the
92022 + * documentation and/or other materials provided with the distribution.
92023 + * * Neither the name of Freescale Semiconductor nor the
92024 + * names of its contributors may be used to endorse or promote products
92025 + * derived from this software without specific prior written permission.
92026 + *
92027 + *
92028 + * ALTERNATIVELY, this software may be distributed under the terms of the
92029 + * GNU General Public License ("GPL") as published by the Free Software
92030 + * Foundation, either version 2 of that License or (at your option) any
92031 + * later version.
92032 + *
92033 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92034 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92035 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92036 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92037 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92038 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92039 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92040 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92041 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92042 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92043 + */
92044 +
92045 +
92046 +/**************************************************************************//**
92047 + @File sprint_ext.h
92048 +
92049 + @Description Debug routines (externals).
92050 +
92051 +*//***************************************************************************/
92052 +
92053 +#ifndef __SPRINT_EXT_H
92054 +#define __SPRINT_EXT_H
92055 +
92056 +
92057 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
92058 +#include <linux/kernel.h>
92059 +
92060 +#elif defined(NCSW_VXWORKS)
92061 +#include "private/stdioP.h"
92062 +
92063 +#else
92064 +#include <stdio.h>
92065 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
92066 +
92067 +#include "std_ext.h"
92068 +
92069 +
92070 +/**************************************************************************//**
92071 + @Group etc_id Utility Library Application Programming Interface
92072 +
92073 + @Description External routines.
92074 +
92075 + @{
92076 +*//***************************************************************************/
92077 +
92078 +/**************************************************************************//**
92079 + @Group sprint_id Sprint
92080 +
92081 + @Description Sprint & Sscan module functions,definitions and enums.
92082 +
92083 + @{
92084 +*//***************************************************************************/
92085 +
92086 +/**************************************************************************//**
92087 + @Function Sprint
92088 +
92089 + @Description Format a string and place it in a buffer.
92090 +
92091 + @Param[in] buff - The buffer to place the result into.
92092 + @Param[in] str - The format string to use.
92093 + @Param[in] ... - Arguments for the format string.
92094 +
92095 + @Return Number of bytes formatted.
92096 +*//***************************************************************************/
92097 +int Sprint(char *buff, const char *str, ...);
92098 +
92099 +/**************************************************************************//**
92100 + @Function Snprint
92101 +
92102 + @Description Format a string and place it in a buffer.
92103 +
92104 + @Param[in] buf - The buffer to place the result into.
92105 + @Param[in] size - The size of the buffer, including the trailing null space.
92106 + @Param[in] fmt - The format string to use.
92107 + @Param[in] ... - Arguments for the format string.
92108 +
92109 + @Return Number of bytes formatted.
92110 +*//***************************************************************************/
92111 +int Snprint(char * buf, uint32_t size, const char *fmt, ...);
92112 +
92113 +/**************************************************************************//**
92114 + @Function Sscan
92115 +
92116 + @Description Unformat a buffer into a list of arguments.
92117 +
92118 + @Param[in] buf - input buffer.
92119 + @Param[in] fmt - formatting of buffer.
92120 + @Param[out] ... - resulting arguments.
92121 +
92122 + @Return Number of bytes unformatted.
92123 +*//***************************************************************************/
92124 +int Sscan(const char * buf, const char * fmt, ...);
92125 +
92126 +/** @} */ /* end of sprint_id group */
92127 +/** @} */ /* end of etc_id group */
92128 +
92129 +
92130 +#endif /* __SPRINT_EXT_H */
92131 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
92132 new file mode 100644
92133 index 00000000..c7b9b46f
92134 --- /dev/null
92135 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
92136 @@ -0,0 +1,37 @@
92137 +/*
92138 + * Copyright 2008-2012 Freescale Semiconductor Inc.
92139 + *
92140 + * Redistribution and use in source and binary forms, with or without
92141 + * modification, are permitted provided that the following conditions are met:
92142 + * * Redistributions of source code must retain the above copyright
92143 + * notice, this list of conditions and the following disclaimer.
92144 + * * Redistributions in binary form must reproduce the above copyright
92145 + * notice, this list of conditions and the following disclaimer in the
92146 + * documentation and/or other materials provided with the distribution.
92147 + * * Neither the name of Freescale Semiconductor nor the
92148 + * names of its contributors may be used to endorse or promote products
92149 + * derived from this software without specific prior written permission.
92150 + *
92151 + *
92152 + * ALTERNATIVELY, this software may be distributed under the terms of the
92153 + * GNU General Public License ("GPL") as published by the Free Software
92154 + * Foundation, either version 2 of that License or (at your option) any
92155 + * later version.
92156 + *
92157 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92158 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92159 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92160 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92161 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92162 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92163 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92164 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92165 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92166 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92167 + */
92168 +
92169 +#ifndef FL_E500_MACROS_H
92170 +#define FL_E500_MACROS_H
92171 +
92172 +#endif /* FL_E500_MACROS_H */
92173 +
92174 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
92175 new file mode 100644
92176 index 00000000..b3f516fb
92177 --- /dev/null
92178 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
92179 @@ -0,0 +1,52 @@
92180 +/*
92181 + * Copyright 2008-2012 Freescale Semiconductor Inc.
92182 + *
92183 + * Redistribution and use in source and binary forms, with or without
92184 + * modification, are permitted provided that the following conditions are met:
92185 + * * Redistributions of source code must retain the above copyright
92186 + * notice, this list of conditions and the following disclaimer.
92187 + * * Redistributions in binary form must reproduce the above copyright
92188 + * notice, this list of conditions and the following disclaimer in the
92189 + * documentation and/or other materials provided with the distribution.
92190 + * * Neither the name of Freescale Semiconductor nor the
92191 + * names of its contributors may be used to endorse or promote products
92192 + * derived from this software without specific prior written permission.
92193 + *
92194 + *
92195 + * ALTERNATIVELY, this software may be distributed under the terms of the
92196 + * GNU General Public License ("GPL") as published by the Free Software
92197 + * Foundation, either version 2 of that License or (at your option) any
92198 + * later version.
92199 + *
92200 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92201 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92202 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92203 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92204 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92205 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92206 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92207 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92208 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92209 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92210 + */
92211 +
92212 +#ifndef __GENERAL_H
92213 +#define __GENERAL_H
92214 +
92215 +#include "std_ext.h"
92216 +#if !defined(NCSW_LINUX)
92217 +#include "errno.h"
92218 +#endif
92219 +
92220 +
92221 +extern uint32_t get_mac_addr_crc(uint64_t _addr);
92222 +
92223 +#ifndef CONFIG_FMAN_ARM
92224 +#define iowrite32be(val, addr) WRITE_UINT32(*addr, val)
92225 +#define ioread32be(addr) GET_UINT32(*addr)
92226 +#endif
92227 +
92228 +#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16)
92229 +
92230 +
92231 +#endif /* __GENERAL_H */
92232 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
92233 new file mode 100755
92234 index 00000000..8b194e99
92235 --- /dev/null
92236 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
92237 @@ -0,0 +1,78 @@
92238 +/*
92239 + * Copyright 2008-2013 Freescale Semiconductor Inc.
92240 + *
92241 + * Redistribution and use in source and binary forms, with or without
92242 + * modification, are permitted provided that the following conditions are met:
92243 + * * Redistributions of source code must retain the above copyright
92244 + * notice, this list of conditions and the following disclaimer.
92245 + * * Redistributions in binary form must reproduce the above copyright
92246 + * notice, this list of conditions and the following disclaimer in the
92247 + * documentation and/or other materials provided with the distribution.
92248 + * * Neither the name of Freescale Semiconductor nor the
92249 + * names of its contributors may be used to endorse or promote products
92250 + * derived from this software without specific prior written permission.
92251 + *
92252 + *
92253 + * ALTERNATIVELY, this software may be distributed under the terms of the
92254 + * GNU General Public License ("GPL") as published by the Free Software
92255 + * Foundation, either version 2 of that License or (at your option) any
92256 + * later version.
92257 + *
92258 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92259 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92260 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92261 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92262 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92263 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92264 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92265 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92266 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92267 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92268 + */
92269 +
92270 +
92271 +#ifndef __FMAN_COMMON_H
92272 +#define __FMAN_COMMON_H
92273 +
92274 +/**************************************************************************//**
92275 + @Description NIA Description
92276 +*//***************************************************************************/
92277 +#define NIA_ORDER_RESTOR 0x00800000
92278 +#define NIA_ENG_FM_CTL 0x00000000
92279 +#define NIA_ENG_PRS 0x00440000
92280 +#define NIA_ENG_KG 0x00480000
92281 +#define NIA_ENG_PLCR 0x004C0000
92282 +#define NIA_ENG_BMI 0x00500000
92283 +#define NIA_ENG_QMI_ENQ 0x00540000
92284 +#define NIA_ENG_QMI_DEQ 0x00580000
92285 +#define NIA_ENG_MASK 0x007C0000
92286 +
92287 +#define NIA_FM_CTL_AC_CC 0x00000006
92288 +#define NIA_FM_CTL_AC_HC 0x0000000C
92289 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
92290 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
92291 +#define NIA_FM_CTL_AC_FRAG 0x0000000e
92292 +#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010
92293 +#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012
92294 +#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018
92295 +#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012
92296 +#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014
92297 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
92298 +
92299 +
92300 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
92301 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
92302 +#define NIA_BMI_AC_RELEASE 0x000000C0
92303 +#define NIA_BMI_AC_DISCARD 0x000000C1
92304 +#define NIA_BMI_AC_TX 0x00000274
92305 +#define NIA_BMI_AC_FETCH 0x00000208
92306 +#define NIA_BMI_AC_MASK 0x000003FF
92307 +
92308 +#define NIA_KG_DIRECT 0x00000100
92309 +#define NIA_KG_CC_EN 0x00000200
92310 +#define NIA_PLCR_ABSOLUTE 0x00008000
92311 +
92312 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
92313 +#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c
92314 +
92315 +#endif /* __FMAN_COMMON_H */
92316 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
92317 new file mode 100644
92318 index 00000000..caa87fc6
92319 --- /dev/null
92320 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
92321 @@ -0,0 +1,273 @@
92322 +/*
92323 + * Copyright 2008-2012 Freescale Semiconductor Inc.
92324 + *
92325 + * Redistribution and use in source and binary forms, with or without
92326 + * modification, are permitted provided that the following conditions are met:
92327 + * * Redistributions of source code must retain the above copyright
92328 + * notice, this list of conditions and the following disclaimer.
92329 + * * Redistributions in binary form must reproduce the above copyright
92330 + * notice, this list of conditions and the following disclaimer in the
92331 + * documentation and/or other materials provided with the distribution.
92332 + * * Neither the name of Freescale Semiconductor nor the
92333 + * names of its contributors may be used to endorse or promote products
92334 + * derived from this software without specific prior written permission.
92335 + *
92336 + *
92337 + * ALTERNATIVELY, this software may be distributed under the terms of the
92338 + * GNU General Public License ("GPL") as published by the Free Software
92339 + * Foundation, either version 2 of that License or (at your option) any
92340 + * later version.
92341 + *
92342 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92343 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92344 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92345 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92346 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92347 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92348 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92349 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92350 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92351 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92352 + */
92353 +
92354 +#ifndef __FSL_ENET_H
92355 +#define __FSL_ENET_H
92356 +
92357 +/**
92358 + @Description Ethernet MAC-PHY Interface
92359 +*/
92360 +
92361 +enum enet_interface {
92362 + E_ENET_IF_MII = 0x00010000, /**< MII interface */
92363 + E_ENET_IF_RMII = 0x00020000, /**< RMII interface */
92364 + E_ENET_IF_SMII = 0x00030000, /**< SMII interface */
92365 + E_ENET_IF_GMII = 0x00040000, /**< GMII interface */
92366 + E_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */
92367 + E_ENET_IF_TBI = 0x00060000, /**< TBI interface */
92368 + E_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */
92369 + E_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */
92370 + E_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */
92371 + E_ENET_IF_QSGMII = 0x000a0000, /**< QSGMII interface */
92372 + E_ENET_IF_XFI = 0x000b0000 /**< XFI interface */
92373 +};
92374 +
92375 +/**
92376 + @Description Ethernet Speed (nominal data rate)
92377 +*/
92378 +enum enet_speed {
92379 + E_ENET_SPEED_10 = 10, /**< 10 Mbps */
92380 + E_ENET_SPEED_100 = 100, /**< 100 Mbps */
92381 + E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
92382 + E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */
92383 + E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
92384 +};
92385 +
92386 +enum mac_type {
92387 + E_MAC_DTSEC,
92388 + E_MAC_TGEC,
92389 + E_MAC_MEMAC
92390 +};
92391 +
92392 +/**************************************************************************//**
92393 + @Description Enum for inter-module interrupts registration
92394 +*//***************************************************************************/
92395 +enum fman_event_modules {
92396 + E_FMAN_MOD_PRS, /**< Parser event */
92397 + E_FMAN_MOD_KG, /**< Keygen event */
92398 + E_FMAN_MOD_PLCR, /**< Policer event */
92399 + E_FMAN_MOD_10G_MAC, /**< 10G MAC event */
92400 + E_FMAN_MOD_1G_MAC, /**< 1G MAC event */
92401 + E_FMAN_MOD_TMR, /**< Timer event */
92402 + E_FMAN_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
92403 + E_FMAN_MOD_MACSEC,
92404 + E_FMAN_MOD_DUMMY_LAST
92405 +};
92406 +
92407 +/**************************************************************************//**
92408 + @Description Enum for interrupts types
92409 +*//***************************************************************************/
92410 +enum fman_intr_type {
92411 + E_FMAN_INTR_TYPE_ERR,
92412 + E_FMAN_INTR_TYPE_NORMAL
92413 +};
92414 +
92415 +/**************************************************************************//**
92416 + @Description enum for defining MAC types
92417 +*//***************************************************************************/
92418 +enum fman_mac_type {
92419 + E_FMAN_MAC_10G = 0, /**< 10G MAC */
92420 + E_FMAN_MAC_1G /**< 1G MAC */
92421 +};
92422 +
92423 +enum fman_mac_exceptions {
92424 + E_FMAN_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0,
92425 + /**< 10GEC MDIO scan event interrupt */
92426 + E_FMAN_MAC_EX_10G_MDIO_CMD_CMPL,
92427 + /**< 10GEC MDIO command completion interrupt */
92428 + E_FMAN_MAC_EX_10G_REM_FAULT,
92429 + /**< 10GEC, mEMAC Remote fault interrupt */
92430 + E_FMAN_MAC_EX_10G_LOC_FAULT,
92431 + /**< 10GEC, mEMAC Local fault interrupt */
92432 + E_FMAN_MAC_EX_10G_1TX_ECC_ER,
92433 + /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
92434 + E_FMAN_MAC_EX_10G_TX_FIFO_UNFL,
92435 + /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
92436 + E_FMAN_MAC_EX_10G_TX_FIFO_OVFL,
92437 + /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
92438 + E_FMAN_MAC_EX_10G_TX_ER,
92439 + /**< 10GEC Transmit frame error interrupt */
92440 + E_FMAN_MAC_EX_10G_RX_FIFO_OVFL,
92441 + /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
92442 + E_FMAN_MAC_EX_10G_RX_ECC_ER,
92443 + /**< 10GEC, mEMAC Receive frame ECC error interrupt */
92444 + E_FMAN_MAC_EX_10G_RX_JAB_FRM,
92445 + /**< 10GEC Receive jabber frame interrupt */
92446 + E_FMAN_MAC_EX_10G_RX_OVRSZ_FRM,
92447 + /**< 10GEC Receive oversized frame interrupt */
92448 + E_FMAN_MAC_EX_10G_RX_RUNT_FRM,
92449 + /**< 10GEC Receive runt frame interrupt */
92450 + E_FMAN_MAC_EX_10G_RX_FRAG_FRM,
92451 + /**< 10GEC Receive fragment frame interrupt */
92452 + E_FMAN_MAC_EX_10G_RX_LEN_ER,
92453 + /**< 10GEC Receive payload length error interrupt */
92454 + E_FMAN_MAC_EX_10G_RX_CRC_ER,
92455 + /**< 10GEC Receive CRC error interrupt */
92456 + E_FMAN_MAC_EX_10G_RX_ALIGN_ER,
92457 + /**< 10GEC Receive alignment error interrupt */
92458 + E_FMAN_MAC_EX_1G_BAB_RX,
92459 + /**< dTSEC Babbling receive error */
92460 + E_FMAN_MAC_EX_1G_RX_CTL,
92461 + /**< dTSEC Receive control (pause frame) interrupt */
92462 + E_FMAN_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET,
92463 + /**< dTSEC Graceful transmit stop complete */
92464 + E_FMAN_MAC_EX_1G_BAB_TX,
92465 + /**< dTSEC Babbling transmit error */
92466 + E_FMAN_MAC_EX_1G_TX_CTL,
92467 + /**< dTSEC Transmit control (pause frame) interrupt */
92468 + E_FMAN_MAC_EX_1G_TX_ERR,
92469 + /**< dTSEC Transmit error */
92470 + E_FMAN_MAC_EX_1G_LATE_COL,
92471 + /**< dTSEC Late collision */
92472 + E_FMAN_MAC_EX_1G_COL_RET_LMT,
92473 + /**< dTSEC Collision retry limit */
92474 + E_FMAN_MAC_EX_1G_TX_FIFO_UNDRN,
92475 + /**< dTSEC Transmit FIFO underrun */
92476 + E_FMAN_MAC_EX_1G_MAG_PCKT,
92477 + /**< dTSEC Magic Packet detection */
92478 + E_FMAN_MAC_EX_1G_MII_MNG_RD_COMPLET,
92479 + /**< dTSEC MII management read completion */
92480 + E_FMAN_MAC_EX_1G_MII_MNG_WR_COMPLET,
92481 + /**< dTSEC MII management write completion */
92482 + E_FMAN_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET,
92483 + /**< dTSEC Graceful receive stop complete */
92484 + E_FMAN_MAC_EX_1G_TX_DATA_ERR,
92485 + /**< dTSEC Internal data error on transmit */
92486 + E_FMAN_MAC_EX_1G_RX_DATA_ERR,
92487 + /**< dTSEC Internal data error on receive */
92488 + E_FMAN_MAC_EX_1G_1588_TS_RX_ERR,
92489 + /**< dTSEC Time-Stamp Receive Error */
92490 + E_FMAN_MAC_EX_1G_RX_MIB_CNT_OVFL,
92491 + /**< dTSEC MIB counter overflow */
92492 + E_FMAN_MAC_EX_TS_FIFO_ECC_ERR,
92493 + /**< mEMAC Time-stamp FIFO ECC error interrupt;
92494 + not supported on T4240/B4860 rev1 chips */
92495 +};
92496 +
92497 +#define ENET_IF_SGMII_BASEX 0x80000000
92498 + /**< SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
92499 + and phy or backplane;
92500 + Note: 1000BaseX auto-negotiation relates only to interface between MAC
92501 + and phy/backplane, SGMII phy can still synchronize with far-end phy at
92502 + 10Mbps, 100Mbps or 1000Mbps */
92503 +
92504 +enum enet_mode {
92505 + E_ENET_MODE_INVALID = 0,
92506 + /**< Invalid Ethernet mode */
92507 + E_ENET_MODE_MII_10 = (E_ENET_IF_MII | E_ENET_SPEED_10),
92508 + /**< 10 Mbps MII */
92509 + E_ENET_MODE_MII_100 = (E_ENET_IF_MII | E_ENET_SPEED_100),
92510 + /**< 100 Mbps MII */
92511 + E_ENET_MODE_RMII_10 = (E_ENET_IF_RMII | E_ENET_SPEED_10),
92512 + /**< 10 Mbps RMII */
92513 + E_ENET_MODE_RMII_100 = (E_ENET_IF_RMII | E_ENET_SPEED_100),
92514 + /**< 100 Mbps RMII */
92515 + E_ENET_MODE_SMII_10 = (E_ENET_IF_SMII | E_ENET_SPEED_10),
92516 + /**< 10 Mbps SMII */
92517 + E_ENET_MODE_SMII_100 = (E_ENET_IF_SMII | E_ENET_SPEED_100),
92518 + /**< 100 Mbps SMII */
92519 + E_ENET_MODE_GMII_1000 = (E_ENET_IF_GMII | E_ENET_SPEED_1000),
92520 + /**< 1000 Mbps GMII */
92521 + E_ENET_MODE_RGMII_10 = (E_ENET_IF_RGMII | E_ENET_SPEED_10),
92522 + /**< 10 Mbps RGMII */
92523 + E_ENET_MODE_RGMII_100 = (E_ENET_IF_RGMII | E_ENET_SPEED_100),
92524 + /**< 100 Mbps RGMII */
92525 + E_ENET_MODE_RGMII_1000 = (E_ENET_IF_RGMII | E_ENET_SPEED_1000),
92526 + /**< 1000 Mbps RGMII */
92527 + E_ENET_MODE_TBI_1000 = (E_ENET_IF_TBI | E_ENET_SPEED_1000),
92528 + /**< 1000 Mbps TBI */
92529 + E_ENET_MODE_RTBI_1000 = (E_ENET_IF_RTBI | E_ENET_SPEED_1000),
92530 + /**< 1000 Mbps RTBI */
92531 + E_ENET_MODE_SGMII_10 = (E_ENET_IF_SGMII | E_ENET_SPEED_10),
92532 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
92533 + SGMII phy according to Cisco SGMII specification */
92534 + E_ENET_MODE_SGMII_100 = (E_ENET_IF_SGMII | E_ENET_SPEED_100),
92535 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
92536 + SGMII phy according to Cisco SGMII specification */
92537 + E_ENET_MODE_SGMII_1000 = (E_ENET_IF_SGMII | E_ENET_SPEED_1000),
92538 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
92539 + SGMII phy according to Cisco SGMII specification */
92540 + E_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92541 + | E_ENET_SPEED_10),
92542 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
92543 + MAC and SGMII phy or backplane */
92544 + E_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92545 + | E_ENET_SPEED_100),
92546 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
92547 + MAC and SGMII phy or backplane */
92548 + E_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92549 + | E_ENET_SPEED_1000),
92550 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
92551 + MAC and SGMII phy or backplane */
92552 + E_ENET_MODE_QSGMII_1000 = (E_ENET_IF_QSGMII | E_ENET_SPEED_1000),
92553 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
92554 + QSGMII phy according to Cisco QSGMII specification */
92555 + E_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_QSGMII
92556 + | E_ENET_SPEED_1000),
92557 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
92558 + MAC and QSGMII phy or backplane */
92559 + E_ENET_MODE_XGMII_10000 = (E_ENET_IF_XGMII | E_ENET_SPEED_10000),
92560 + /**< 10000 Mbps XGMII */
92561 + E_ENET_MODE_XFI_10000 = (E_ENET_IF_XFI | E_ENET_SPEED_10000)
92562 + /**< 10000 Mbps XFI */
92563 +};
92564 +
92565 +enum fmam_mac_statistics_level {
92566 + E_FMAN_MAC_NONE_STATISTICS, /**< No statistics */
92567 + E_FMAN_MAC_PARTIAL_STATISTICS, /**< Only error counters are available;
92568 + Optimized for performance */
92569 + E_FMAN_MAC_FULL_STATISTICS /**< All counters available; Not
92570 + optimized for performance */
92571 +};
92572 +
92573 +#define _MAKE_ENET_MODE(_interface, _speed) (enum enet_mode)((_interface) \
92574 + | (_speed))
92575 +
92576 +#define _ENET_INTERFACE_FROM_MODE(mode) (enum enet_interface) \
92577 + ((mode) & 0x0FFF0000)
92578 +#define _ENET_SPEED_FROM_MODE(mode) (enum enet_speed)((mode) & 0x0000FFFF)
92579 +#define _ENET_ADDR_TO_UINT64(_enet_addr) \
92580 + (uint64_t)(((uint64_t)(_enet_addr)[0] << 40) | \
92581 + ((uint64_t)(_enet_addr)[1] << 32) | \
92582 + ((uint64_t)(_enet_addr)[2] << 24) | \
92583 + ((uint64_t)(_enet_addr)[3] << 16) | \
92584 + ((uint64_t)(_enet_addr)[4] << 8) | \
92585 + ((uint64_t)(_enet_addr)[5]))
92586 +
92587 +#define _MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \
92588 + do { \
92589 + int i; \
92590 + for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
92591 + (_enet_addr)[i] = (uint8_t)((_addr64) >> ((5-i)*8));\
92592 + } while (0)
92593 +
92594 +#endif /* __FSL_ENET_H */
92595 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
92596 new file mode 100755
92597 index 00000000..96a63fa7
92598 --- /dev/null
92599 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
92600 @@ -0,0 +1,825 @@
92601 +/*
92602 + * Copyright 2013 Freescale Semiconductor Inc.
92603 + *
92604 + * Redistribution and use in source and binary forms, with or without
92605 + * modification, are permitted provided that the following conditions are met:
92606 + * * Redistributions of source code must retain the above copyright
92607 + * notice, this list of conditions and the following disclaimer.
92608 + * * Redistributions in binary form must reproduce the above copyright
92609 + * notice, this list of conditions and the following disclaimer in the
92610 + * documentation and/or other materials provided with the distribution.
92611 + * * Neither the name of Freescale Semiconductor nor the
92612 + * names of its contributors may be used to endorse or promote products
92613 + * derived from this software without specific prior written permission.
92614 + *
92615 + *
92616 + * ALTERNATIVELY, this software may be distributed under the terms of the
92617 + * GNU General Public License ("GPL") as published by the Free Software
92618 + * Foundation, either version 2 of that License or (at your option) any
92619 + * later version.
92620 + *
92621 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92622 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92623 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92624 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92625 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92626 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92627 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92628 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92629 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92630 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92631 + */
92632 +
92633 +#ifndef __FSL_FMAN_H
92634 +#define __FSL_FMAN_H
92635 +
92636 +#include "common/general.h"
92637 +
92638 +struct fman_ext_pool_params {
92639 + uint8_t id; /**< External buffer pool id */
92640 + uint16_t size; /**< External buffer pool buffer size */
92641 +};
92642 +
92643 +struct fman_ext_pools {
92644 + uint8_t num_pools_used; /**< Number of pools use by this port */
92645 + struct fman_ext_pool_params *ext_buf_pool;
92646 + /**< Parameters for each port */
92647 +};
92648 +
92649 +struct fman_backup_bm_pools {
92650 + uint8_t num_backup_pools; /**< Number of BM backup pools -
92651 + must be smaller than the total number
92652 + of pools defined for the specified
92653 + port.*/
92654 + uint8_t *pool_ids; /**< numOfBackupPools pool id's,
92655 + specifying which pools should be used
92656 + only as backup. Pool id's specified
92657 + here must be a subset of the pools
92658 + used by the specified port.*/
92659 +};
92660 +
92661 +/**************************************************************************//**
92662 + @Description A structure for defining BM pool depletion criteria
92663 +*//***************************************************************************/
92664 +struct fman_buf_pool_depletion {
92665 + bool buf_pool_depletion_enabled;
92666 + bool pools_grp_mode_enable; /**< select mode in which pause frames
92667 + will be sent after a number of pools
92668 + (all together!) are depleted */
92669 + uint8_t num_pools; /**< the number of depleted pools that
92670 + will invoke pause frames transmission.
92671 + */
92672 + bool *pools_to_consider; /**< For each pool, TRUE if it should be
92673 + considered for depletion (Note - this
92674 + pool must be used by this port!). */
92675 + bool single_pool_mode_enable; /**< select mode in which pause frames
92676 + will be sent after a single-pool
92677 + is depleted; */
92678 + bool *pools_to_consider_for_single_mode;
92679 + /**< For each pool, TRUE if it should be
92680 + considered for depletion (Note - this
92681 + pool must be used by this port!) */
92682 + bool has_pfc_priorities;
92683 + bool *pfc_priorities_en; /**< This field is used by the MAC as
92684 + the Priority Enable Vector in the PFC
92685 + frame which is transmitted */
92686 +};
92687 +
92688 +/**************************************************************************//**
92689 + @Description Enum for defining port DMA swap mode
92690 +*//***************************************************************************/
92691 +enum fman_dma_swap_option {
92692 + FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
92693 + FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
92694 + in PowerPc Little Endian mode. */
92695 + FMAN_DMA_SWP_BE /**< The transferred data should be swapped
92696 + in Big Endian mode */
92697 +};
92698 +
92699 +/**************************************************************************//**
92700 + @Description Enum for defining port DMA cache attributes
92701 +*//***************************************************************************/
92702 +enum fman_dma_cache_option {
92703 + FMAN_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */
92704 + FMAN_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */
92705 +};
92706 +
92707 +typedef struct t_FmPrsResult fm_prs_result_t;
92708 +typedef enum e_EnetMode enet_mode_t;
92709 +typedef t_Handle handle_t;
92710 +
92711 +struct fman_revision_info {
92712 + uint8_t majorRev; /**< Major revision */
92713 + uint8_t minorRev; /**< Minor revision */
92714 +};
92715 +
92716 +/* sizes */
92717 +#define CAPWAP_FRAG_EXTRA_SPACE 32
92718 +#define OFFSET_UNITS 16
92719 +#define MAX_INT_OFFSET 240
92720 +#define MAX_IC_SIZE 256
92721 +#define MAX_EXT_OFFSET 496
92722 +#define MAX_EXT_BUFFER_OFFSET 511
92723 +
92724 +/**************************************************************************
92725 + @Description Memory Mapped Registers
92726 +***************************************************************************/
92727 +#define FMAN_LIODN_TBL 64 /* size of LIODN table */
92728 +
92729 +struct fman_fpm_regs {
92730 + uint32_t fmfp_tnc; /**< FPM TNUM Control 0x00 */
92731 + uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association 0x04 */
92732 + uint32_t fmfp_brkc; /**< FPM Breakpoint Control 0x08 */
92733 + uint32_t fmfp_mxd; /**< FPM Flush Control 0x0c */
92734 + uint32_t fmfp_dist1; /**< FPM Dispatch Thresholds1 0x10 */
92735 + uint32_t fmfp_dist2; /**< FPM Dispatch Thresholds2 0x14 */
92736 + uint32_t fm_epi; /**< FM Error Pending Interrupts 0x18 */
92737 + uint32_t fm_rie; /**< FM Error Interrupt Enable 0x1c */
92738 + uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 0x20-0x2f */
92739 + uint32_t res0030[4]; /**< res 0x30 - 0x3f */
92740 + uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 0x40-0x4f */
92741 + uint32_t res0050[4]; /**< res 0x50-0x5f */
92742 + uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 0x60 */
92743 + uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 0x64 */
92744 + uint32_t fmfp_tsp; /**< FPM Time Stamp 0x68 */
92745 + uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction 0x6c */
92746 + uint32_t fm_rcr; /**< FM Rams Control 0x70 */
92747 + uint32_t fmfp_extc; /**< FPM External Requests Control 0x74 */
92748 + uint32_t fmfp_ext1; /**< FPM External Requests Config1 0x78 */
92749 + uint32_t fmfp_ext2; /**< FPM External Requests Config2 0x7c */
92750 + uint32_t fmfp_drd[16]; /**< FPM Data_Ram Data 0-15 0x80 - 0xbf */
92751 + uint32_t fmfp_dra; /**< FPM Data Ram Access 0xc0 */
92752 + uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 0xc4 */
92753 + uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 0xc8 */
92754 + uint32_t fm_rstc; /**< FM Reset Command 0xcc */
92755 + uint32_t fm_cld; /**< FM Classifier Debug 0xd0 */
92756 + uint32_t fm_npi; /**< FM Normal Pending Interrupts 0xd4 */
92757 + uint32_t fmfp_exte; /**< FPM External Requests Enable 0xd8 */
92758 + uint32_t fmfp_ee; /**< FPM Event & Mask 0xdc */
92759 + uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 0xe0-0xef */
92760 + uint32_t res00f0[4]; /**< res 0xf0-0xff */
92761 + uint32_t fmfp_ps[64]; /**< FPM Port Status 0x100-0x1ff */
92762 + uint32_t fmfp_clfabc; /**< FPM CLFABC 0x200 */
92763 + uint32_t fmfp_clfcc; /**< FPM CLFCC 0x204 */
92764 + uint32_t fmfp_clfaval; /**< FPM CLFAVAL 0x208 */
92765 + uint32_t fmfp_clfbval; /**< FPM CLFBVAL 0x20c */
92766 + uint32_t fmfp_clfcval; /**< FPM CLFCVAL 0x210 */
92767 + uint32_t fmfp_clfamsk; /**< FPM CLFAMSK 0x214 */
92768 + uint32_t fmfp_clfbmsk; /**< FPM CLFBMSK 0x218 */
92769 + uint32_t fmfp_clfcmsk; /**< FPM CLFCMSK 0x21c */
92770 + uint32_t fmfp_clfamc; /**< FPM CLFAMC 0x220 */
92771 + uint32_t fmfp_clfbmc; /**< FPM CLFBMC 0x224 */
92772 + uint32_t fmfp_clfcmc; /**< FPM CLFCMC 0x228 */
92773 + uint32_t fmfp_decceh; /**< FPM DECCEH 0x22c */
92774 + uint32_t res0230[116]; /**< res 0x230 - 0x3ff */
92775 + uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status 0x400 - 0x5ff */
92776 + uint32_t res0600[0x400 - 384];
92777 +};
92778 +
92779 +struct fman_bmi_regs {
92780 + uint32_t fmbm_init; /**< BMI Initialization 0x00 */
92781 + uint32_t fmbm_cfg1; /**< BMI Configuration 1 0x04 */
92782 + uint32_t fmbm_cfg2; /**< BMI Configuration 2 0x08 */
92783 + uint32_t res000c[5]; /**< 0x0c - 0x1f */
92784 + uint32_t fmbm_ievr; /**< Interrupt Event Register 0x20 */
92785 + uint32_t fmbm_ier; /**< Interrupt Enable Register 0x24 */
92786 + uint32_t fmbm_ifr; /**< Interrupt Force Register 0x28 */
92787 + uint32_t res002c[5]; /**< 0x2c - 0x3f */
92788 + uint32_t fmbm_arb[8]; /**< BMI Arbitration 0x40 - 0x5f */
92789 + uint32_t res0060[12]; /**<0x60 - 0x8f */
92790 + uint32_t fmbm_dtc[3]; /**< Debug Trap Counter 0x90 - 0x9b */
92791 + uint32_t res009c; /**< 0x9c */
92792 + uint32_t fmbm_dcv[3][4]; /**< Debug Compare val 0xa0-0xcf */
92793 + uint32_t fmbm_dcm[3][4]; /**< Debug Compare Mask 0xd0-0xff */
92794 + uint32_t fmbm_gde; /**< BMI Global Debug Enable 0x100 */
92795 + uint32_t fmbm_pp[63]; /**< BMI Port Parameters 0x104 - 0x1ff */
92796 + uint32_t res0200; /**< 0x200 */
92797 + uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size 0x204 - 0x2ff */
92798 + uint32_t res0300; /**< 0x300 */
92799 + uint32_t fmbm_spliodn[63]; /**< Port Partition ID 0x304 - 0x3ff */
92800 +};
92801 +
92802 +struct fman_qmi_regs {
92803 + uint32_t fmqm_gc; /**< General Configuration Register 0x00 */
92804 + uint32_t res0004; /**< 0x04 */
92805 + uint32_t fmqm_eie; /**< Error Interrupt Event Register 0x08 */
92806 + uint32_t fmqm_eien; /**< Error Interrupt Enable Register 0x0c */
92807 + uint32_t fmqm_eif; /**< Error Interrupt Force Register 0x10 */
92808 + uint32_t fmqm_ie; /**< Interrupt Event Register 0x14 */
92809 + uint32_t fmqm_ien; /**< Interrupt Enable Register 0x18 */
92810 + uint32_t fmqm_if; /**< Interrupt Force Register 0x1c */
92811 + uint32_t fmqm_gs; /**< Global Status Register 0x20 */
92812 + uint32_t fmqm_ts; /**< Task Status Register 0x24 */
92813 + uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter 0x28 */
92814 + uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter 0x2c */
92815 + uint32_t fmqm_dc0; /**< Dequeue Counter 0 0x30 */
92816 + uint32_t fmqm_dc1; /**< Dequeue Counter 1 0x34 */
92817 + uint32_t fmqm_dc2; /**< Dequeue Counter 2 0x38 */
92818 + uint32_t fmqm_dc3; /**< Dequeue Counter 3 0x3c */
92819 + uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter 0x40 */
92820 + uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter 0x44 */
92821 + uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter 0x48 */
92822 + uint32_t fmqm_dcc; /**< Dequeue Confirm Counter 0x4c */
92823 + uint32_t res0050[7]; /**< 0x50 - 0x6b */
92824 + uint32_t fmqm_tapc; /**< Tnum Aging Period Control 0x6c */
92825 + uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter 0x70 */
92826 + uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter 0x74 */
92827 + uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter 0x78 */
92828 + uint32_t res007c; /**< 0x7c */
92829 + uint32_t fmqm_dtc; /**< 0x80 Debug Trap Counter 0x80 */
92830 + uint32_t fmqm_efddd; /**< 0x84 Enqueue Frame desc Dynamic dbg 0x84 */
92831 + uint32_t res0088[2]; /**< 0x88 - 0x8f */
92832 + struct {
92833 + uint32_t fmqm_dtcfg1; /**< 0x90 dbg trap cfg 1 Register 0x00 */
92834 + uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register 0x04 */
92835 + uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register 0x08 */
92836 + uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register 0x0c */
92837 + uint32_t fmqm_dtcfg2; /**< dbg Trap cfg 2 Register 0x10 */
92838 + uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register 0x14 */
92839 + uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register 0x18 */
92840 + uint32_t res001c; /**< 0x1c */
92841 + } dbg_traps[3]; /**< 0x90 - 0xef */
92842 + uint8_t res00f0[0x400 - 0xf0]; /**< 0xf0 - 0x3ff */
92843 +};
92844 +
92845 +struct fman_dma_regs {
92846 + uint32_t fmdmsr; /**< FM DMA status register 0x00 */
92847 + uint32_t fmdmmr; /**< FM DMA mode register 0x04 */
92848 + uint32_t fmdmtr; /**< FM DMA bus threshold register 0x08 */
92849 + uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x0c */
92850 + uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x10 */
92851 + uint32_t fmdmtah; /**< FM DMA transfer bus address high reg 0x14 */
92852 + uint32_t fmdmtal; /**< FM DMA transfer bus address low reg 0x18 */
92853 + uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID reg 0x1c */
92854 + uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x20 */
92855 + uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x24 */
92856 + uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x28 */
92857 + uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x2c */
92858 + uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug reg 0x30 */
92859 + uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value reg #1 0x34 */
92860 + uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value reg #2 0x38 */
92861 + uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x3c */
92862 + uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x40 */
92863 + uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x44 */
92864 + uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Cntr 0x48 */
92865 + uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Cntr 0x4c */
92866 + uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x50 */
92867 + uint32_t fmdmdcr; /**< FM DMA Debug Counter 0x54 */
92868 + uint32_t fmdmemsr; /**< FM DMA Emergency Smoother Register 0x58 */
92869 + uint32_t res005c; /**< 0x5c */
92870 + uint32_t fmdmplr[FMAN_LIODN_TBL / 2]; /**< DMA LIODN regs 0x60-0xdf */
92871 + uint32_t res00e0[0x400 - 56];
92872 +};
92873 +
92874 +struct fman_rg {
92875 + struct fman_fpm_regs *fpm_rg;
92876 + struct fman_dma_regs *dma_rg;
92877 + struct fman_bmi_regs *bmi_rg;
92878 + struct fman_qmi_regs *qmi_rg;
92879 +};
92880 +
92881 +enum fman_dma_cache_override {
92882 + E_FMAN_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
92883 + E_FMAN_DMA_NO_STASH_DATA, /**< No data stashing in system level cache */
92884 + E_FMAN_DMA_MAY_STASH_DATA, /**< Stashing allowed in sys level cache */
92885 + E_FMAN_DMA_STASH_DATA /**< Stashing performed in system level cache */
92886 +};
92887 +
92888 +enum fman_dma_aid_mode {
92889 + E_FMAN_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
92890 + E_FMAN_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
92891 +};
92892 +
92893 +enum fman_dma_dbg_cnt_mode {
92894 + E_FMAN_DMA_DBG_NO_CNT = 0, /**< No counting */
92895 + E_FMAN_DMA_DBG_CNT_DONE, /**< Count DONE commands */
92896 + E_FMAN_DMA_DBG_CNT_COMM_Q_EM, /**< command Q emergency signal */
92897 + E_FMAN_DMA_DBG_CNT_INT_READ_EM, /**< Read buf emergency signal */
92898 + E_FMAN_DMA_DBG_CNT_INT_WRITE_EM, /**< Write buf emergency signal */
92899 + E_FMAN_DMA_DBG_CNT_FPM_WAIT, /**< FPM WAIT signal */
92900 + E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors */
92901 + E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT /**< RAW & WAR protection counter */
92902 +};
92903 +
92904 +enum fman_dma_emergency_level {
92905 + E_FMAN_DMA_EM_EBS = 0, /**< EBS emergency */
92906 + E_FMAN_DMA_EM_SOS /**< SOS emergency */
92907 +};
92908 +
92909 +enum fman_catastrophic_err {
92910 + E_FMAN_CATAST_ERR_STALL_PORT = 0, /**< Port_ID stalled reset required */
92911 + E_FMAN_CATAST_ERR_STALL_TASK /**< Only erroneous task is stalled */
92912 +};
92913 +
92914 +enum fman_dma_err {
92915 + E_FMAN_DMA_ERR_CATASTROPHIC = 0, /**< Catastrophic DMA error */
92916 + E_FMAN_DMA_ERR_REPORT /**< Reported DMA error */
92917 +};
92918 +
92919 +struct fman_cfg {
92920 + uint16_t liodn_bs_pr_port[FMAN_LIODN_TBL];/* base per port */
92921 + bool en_counters;
92922 + uint8_t disp_limit_tsh;
92923 + uint8_t prs_disp_tsh;
92924 + uint8_t plcr_disp_tsh;
92925 + uint8_t kg_disp_tsh;
92926 + uint8_t bmi_disp_tsh;
92927 + uint8_t qmi_enq_disp_tsh;
92928 + uint8_t qmi_deq_disp_tsh;
92929 + uint8_t fm_ctl1_disp_tsh;
92930 + uint8_t fm_ctl2_disp_tsh;
92931 + enum fman_dma_cache_override dma_cache_override;
92932 + enum fman_dma_aid_mode dma_aid_mode;
92933 + bool dma_aid_override;
92934 + uint8_t dma_axi_dbg_num_of_beats;
92935 + uint8_t dma_cam_num_of_entries;
92936 + uint32_t dma_watchdog;
92937 + uint8_t dma_comm_qtsh_asrt_emer;
92938 + uint8_t dma_write_buf_tsh_asrt_emer;
92939 + uint8_t dma_read_buf_tsh_asrt_emer;
92940 + uint8_t dma_comm_qtsh_clr_emer;
92941 + uint8_t dma_write_buf_tsh_clr_emer;
92942 + uint8_t dma_read_buf_tsh_clr_emer;
92943 + uint32_t dma_sos_emergency;
92944 + enum fman_dma_dbg_cnt_mode dma_dbg_cnt_mode;
92945 + bool dma_stop_on_bus_error;
92946 + bool dma_en_emergency;
92947 + uint32_t dma_emergency_bus_select;
92948 + enum fman_dma_emergency_level dma_emergency_level;
92949 + bool dma_en_emergency_smoother;
92950 + uint32_t dma_emergency_switch_counter;
92951 + bool halt_on_external_activ;
92952 + bool halt_on_unrecov_ecc_err;
92953 + enum fman_catastrophic_err catastrophic_err;
92954 + enum fman_dma_err dma_err;
92955 + bool en_muram_test_mode;
92956 + bool en_iram_test_mode;
92957 + bool external_ecc_rams_enable;
92958 + uint16_t tnum_aging_period;
92959 + uint32_t exceptions;
92960 + uint16_t clk_freq;
92961 + bool pedantic_dma;
92962 + uint32_t cam_base_addr;
92963 + uint32_t fifo_base_addr;
92964 + uint32_t total_fifo_size;
92965 + uint8_t total_num_of_tasks;
92966 + bool qmi_deq_option_support;
92967 + uint32_t qmi_def_tnums_thresh;
92968 + bool fman_partition_array;
92969 + uint8_t num_of_fman_ctrl_evnt_regs;
92970 +};
92971 +
92972 +/**************************************************************************//**
92973 + @Description Exceptions
92974 +*//***************************************************************************/
92975 +#define FMAN_EX_DMA_BUS_ERROR 0x80000000
92976 +#define FMAN_EX_DMA_READ_ECC 0x40000000
92977 +#define FMAN_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
92978 +#define FMAN_EX_DMA_FM_WRITE_ECC 0x10000000
92979 +#define FMAN_EX_FPM_STALL_ON_TASKS 0x08000000
92980 +#define FMAN_EX_FPM_SINGLE_ECC 0x04000000
92981 +#define FMAN_EX_FPM_DOUBLE_ECC 0x02000000
92982 +#define FMAN_EX_QMI_SINGLE_ECC 0x01000000
92983 +#define FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000
92984 +#define FMAN_EX_QMI_DOUBLE_ECC 0x00400000
92985 +#define FMAN_EX_BMI_LIST_RAM_ECC 0x00200000
92986 +#define FMAN_EX_BMI_PIPELINE_ECC 0x00100000
92987 +#define FMAN_EX_BMI_STATISTICS_RAM_ECC 0x00080000
92988 +#define FMAN_EX_IRAM_ECC 0x00040000
92989 +#define FMAN_EX_NURAM_ECC 0x00020000
92990 +#define FMAN_EX_BMI_DISPATCH_RAM_ECC 0x00010000
92991 +
92992 +enum fman_exceptions {
92993 + E_FMAN_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
92994 + E_FMAN_EX_DMA_READ_ECC, /**< Read Buffer ECC error */
92995 + E_FMAN_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC err on sys side */
92996 + E_FMAN_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */
92997 + E_FMAN_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
92998 + E_FMAN_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
92999 + E_FMAN_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
93000 + E_FMAN_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
93001 + E_FMAN_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
93002 + E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< DeQ from unknown port id */
93003 + E_FMAN_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
93004 + E_FMAN_EX_BMI_STORAGE_PROFILE_ECC, /**< storage profile */
93005 + E_FMAN_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics RAM ECC Err Enable */
93006 + E_FMAN_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
93007 + E_FMAN_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
93008 + E_FMAN_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
93009 +};
93010 +
93011 +enum fman_counters {
93012 + E_FMAN_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI tot enQ frames counter */
93013 + E_FMAN_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI tot deQ frames counter */
93014 + E_FMAN_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
93015 + E_FMAN_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
93016 + E_FMAN_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
93017 + E_FMAN_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
93018 + E_FMAN_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI deQ from dflt queue cntr */
93019 + E_FMAN_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI deQ from FQ context cntr */
93020 + E_FMAN_COUNTERS_DEQ_FROM_FD, /**< QMI deQ from FD command field cntr */
93021 + E_FMAN_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
93022 + E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA full entry cntr */
93023 + E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA full CAM Q cntr */
93024 + E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA sync counter */
93025 +};
93026 +
93027 +#define FPM_PRT_FM_CTL1 0x00000001
93028 +#define FPM_PRT_FM_CTL2 0x00000002
93029 +
93030 +/**************************************************************************//**
93031 + @Description DMA definitions
93032 +*//***************************************************************************/
93033 +
93034 +/* masks */
93035 +#define DMA_MODE_AID_OR 0x20000000
93036 +#define DMA_MODE_SBER 0x10000000
93037 +#define DMA_MODE_BER 0x00200000
93038 +#define DMA_MODE_EB 0x00100000
93039 +#define DMA_MODE_ECC 0x00000020
93040 +#define DMA_MODE_PRIVILEGE_PROT 0x00001000
93041 +#define DMA_MODE_SECURE_PROT 0x00000800
93042 +#define DMA_MODE_EMER_READ 0x00080000
93043 +#define DMA_MODE_EMER_WRITE 0x00040000
93044 +#define DMA_MODE_CACHE_OR_MASK 0xC0000000
93045 +#define DMA_MODE_CEN_MASK 0x0000E000
93046 +#define DMA_MODE_DBG_MASK 0x00000380
93047 +#define DMA_MODE_AXI_DBG_MASK 0x0F000000
93048 +
93049 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
93050 +
93051 +#define DMA_TRANSFER_PORTID_MASK 0xFF000000
93052 +#define DMA_TRANSFER_TNUM_MASK 0x00FF0000
93053 +#define DMA_TRANSFER_LIODN_MASK 0x00000FFF
93054 +
93055 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
93056 +#define DMA_LOW_LIODN_MASK 0x00000FFF
93057 +
93058 +#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000
93059 +#define DMA_STATUS_BUS_ERR 0x08000000
93060 +#define DMA_STATUS_READ_ECC 0x04000000
93061 +#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000
93062 +#define DMA_STATUS_FM_WRITE_ECC 0x01000000
93063 +#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000
93064 +#define DMA_STATUS_FM_DPEXT_ECC 0x00400000
93065 +#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000
93066 +#define DMA_STATUS_FM_DPDAT_ECC 0x00100000
93067 +#define DMA_STATUS_FM_SPDAT_ECC 0x00080000
93068 +
93069 +#define FM_LIODN_BASE_MASK 0x00000FFF
93070 +
93071 +/* shifts */
93072 +#define DMA_MODE_CACHE_OR_SHIFT 30
93073 +#define DMA_MODE_BUS_PRI_SHIFT 16
93074 +#define DMA_MODE_AXI_DBG_SHIFT 24
93075 +#define DMA_MODE_CEN_SHIFT 13
93076 +#define DMA_MODE_BUS_PROT_SHIFT 10
93077 +#define DMA_MODE_DBG_SHIFT 7
93078 +#define DMA_MODE_EMER_LVL_SHIFT 6
93079 +#define DMA_MODE_AID_MODE_SHIFT 4
93080 +#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16
93081 +#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32
93082 +
93083 +#define DMA_THRESH_COMMQ_SHIFT 24
93084 +#define DMA_THRESH_READ_INT_BUF_SHIFT 16
93085 +
93086 +#define DMA_LIODN_SHIFT 16
93087 +
93088 +#define DMA_TRANSFER_PORTID_SHIFT 24
93089 +#define DMA_TRANSFER_TNUM_SHIFT 16
93090 +
93091 +/* sizes */
93092 +#define DMA_MAX_WATCHDOG 0xffffffff
93093 +
93094 +/* others */
93095 +#define DMA_CAM_SIZEOF_ENTRY 0x40
93096 +#define DMA_CAM_ALIGN 0x1000
93097 +#define DMA_CAM_UNITS 8
93098 +
93099 +/**************************************************************************//**
93100 + @Description General defines
93101 +*//***************************************************************************/
93102 +
93103 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
93104 +#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL
93105 +
93106 +/**************************************************************************//**
93107 + @Description FPM defines
93108 +*//***************************************************************************/
93109 +
93110 +/* masks */
93111 +#define FPM_EV_MASK_DOUBLE_ECC 0x80000000
93112 +#define FPM_EV_MASK_STALL 0x40000000
93113 +#define FPM_EV_MASK_SINGLE_ECC 0x20000000
93114 +#define FPM_EV_MASK_RELEASE_FM 0x00010000
93115 +#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000
93116 +#define FPM_EV_MASK_STALL_EN 0x00004000
93117 +#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000
93118 +#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008
93119 +#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004
93120 +
93121 +#define FPM_RAM_RAMS_ECC_EN 0x80000000
93122 +#define FPM_RAM_IRAM_ECC_EN 0x40000000
93123 +#define FPM_RAM_MURAM_ECC 0x00008000
93124 +#define FPM_RAM_IRAM_ECC 0x00004000
93125 +#define FPM_RAM_MURAM_TEST_ECC 0x20000000
93126 +#define FPM_RAM_IRAM_TEST_ECC 0x10000000
93127 +#define FPM_RAM_RAMS_ECC_EN_SRC_SEL 0x08000000
93128 +
93129 +#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000
93130 +#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000
93131 +
93132 +#define FPM_REV1_MAJOR_MASK 0x0000FF00
93133 +#define FPM_REV1_MINOR_MASK 0x000000FF
93134 +
93135 +#define FPM_REV2_INTEG_MASK 0x00FF0000
93136 +#define FPM_REV2_ERR_MASK 0x0000FF00
93137 +#define FPM_REV2_CFG_MASK 0x000000FF
93138 +
93139 +#define FPM_TS_FRACTION_MASK 0x0000FFFF
93140 +#define FPM_TS_CTL_EN 0x80000000
93141 +
93142 +#define FPM_PRC_REALSE_STALLED 0x00800000
93143 +
93144 +#define FPM_PS_STALLED 0x00800000
93145 +#define FPM_PS_FM_CTL1_SEL 0x80000000
93146 +#define FPM_PS_FM_CTL2_SEL 0x40000000
93147 +#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL)
93148 +
93149 +#define FPM_RSTC_FM_RESET 0x80000000
93150 +#define FPM_RSTC_10G0_RESET 0x04000000
93151 +#define FPM_RSTC_1G0_RESET 0x40000000
93152 +#define FPM_RSTC_1G1_RESET 0x20000000
93153 +#define FPM_RSTC_1G2_RESET 0x10000000
93154 +#define FPM_RSTC_1G3_RESET 0x08000000
93155 +#define FPM_RSTC_1G4_RESET 0x02000000
93156 +
93157 +
93158 +#define FPM_DISP_LIMIT_MASK 0x1F000000
93159 +#define FPM_THR1_PRS_MASK 0xFF000000
93160 +#define FPM_THR1_KG_MASK 0x00FF0000
93161 +#define FPM_THR1_PLCR_MASK 0x0000FF00
93162 +#define FPM_THR1_BMI_MASK 0x000000FF
93163 +
93164 +#define FPM_THR2_QMI_ENQ_MASK 0xFF000000
93165 +#define FPM_THR2_QMI_DEQ_MASK 0x000000FF
93166 +#define FPM_THR2_FM_CTL1_MASK 0x00FF0000
93167 +#define FPM_THR2_FM_CTL2_MASK 0x0000FF00
93168 +
93169 +/* shifts */
93170 +#define FPM_DISP_LIMIT_SHIFT 24
93171 +
93172 +#define FPM_THR1_PRS_SHIFT 24
93173 +#define FPM_THR1_KG_SHIFT 16
93174 +#define FPM_THR1_PLCR_SHIFT 8
93175 +#define FPM_THR1_BMI_SHIFT 0
93176 +
93177 +#define FPM_THR2_QMI_ENQ_SHIFT 24
93178 +#define FPM_THR2_QMI_DEQ_SHIFT 0
93179 +#define FPM_THR2_FM_CTL1_SHIFT 16
93180 +#define FPM_THR2_FM_CTL2_SHIFT 8
93181 +
93182 +#define FPM_EV_MASK_CAT_ERR_SHIFT 1
93183 +#define FPM_EV_MASK_DMA_ERR_SHIFT 0
93184 +
93185 +#define FPM_REV1_MAJOR_SHIFT 8
93186 +#define FPM_REV1_MINOR_SHIFT 0
93187 +
93188 +#define FPM_REV2_INTEG_SHIFT 16
93189 +#define FPM_REV2_ERR_SHIFT 8
93190 +#define FPM_REV2_CFG_SHIFT 0
93191 +
93192 +#define FPM_TS_INT_SHIFT 16
93193 +
93194 +#define FPM_PORT_FM_CTL_PORTID_SHIFT 24
93195 +
93196 +#define FPM_PS_FM_CTL_SEL_SHIFT 30
93197 +#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16
93198 +
93199 +#define FPM_DISP_LIMIT_SHIFT 24
93200 +
93201 +/* Interrupts defines */
93202 +#define FPM_EVENT_FM_CTL_0 0x00008000
93203 +#define FPM_EVENT_FM_CTL 0x0000FF00
93204 +#define FPM_EVENT_FM_CTL_BRK 0x00000080
93205 +
93206 +/* others */
93207 +#define FPM_MAX_DISP_LIMIT 31
93208 +#define FPM_RSTC_FM_RESET 0x80000000
93209 +#define FPM_RSTC_1G0_RESET 0x40000000
93210 +#define FPM_RSTC_1G1_RESET 0x20000000
93211 +#define FPM_RSTC_1G2_RESET 0x10000000
93212 +#define FPM_RSTC_1G3_RESET 0x08000000
93213 +#define FPM_RSTC_10G0_RESET 0x04000000
93214 +#define FPM_RSTC_1G4_RESET 0x02000000
93215 +#define FPM_RSTC_1G5_RESET 0x01000000
93216 +#define FPM_RSTC_1G6_RESET 0x00800000
93217 +#define FPM_RSTC_1G7_RESET 0x00400000
93218 +#define FPM_RSTC_10G1_RESET 0x00200000
93219 +/**************************************************************************//**
93220 + @Description BMI defines
93221 +*//***************************************************************************/
93222 +/* masks */
93223 +#define BMI_INIT_START 0x80000000
93224 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
93225 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
93226 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
93227 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
93228 +#define BMI_NUM_OF_TASKS_MASK 0x3F000000
93229 +#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000
93230 +#define BMI_NUM_OF_DMAS_MASK 0x00000F00
93231 +#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F
93232 +#define BMI_FIFO_SIZE_MASK 0x000003FF
93233 +#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000
93234 +#define BMI_CFG2_DMAS_MASK 0x0000003F
93235 +#define BMI_TOTAL_FIFO_SIZE_MASK 0x07FF0000
93236 +#define BMI_TOTAL_NUM_OF_TASKS_MASK 0x007F0000
93237 +
93238 +/* shifts */
93239 +#define BMI_CFG2_TASKS_SHIFT 16
93240 +#define BMI_CFG2_DMAS_SHIFT 0
93241 +#define BMI_CFG1_FIFO_SIZE_SHIFT 16
93242 +#define BMI_FIFO_SIZE_SHIFT 0
93243 +#define BMI_EXTRA_FIFO_SIZE_SHIFT 16
93244 +#define BMI_NUM_OF_TASKS_SHIFT 24
93245 +#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16
93246 +#define BMI_NUM_OF_DMAS_SHIFT 8
93247 +#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0
93248 +
93249 +/* others */
93250 +#define BMI_FIFO_ALIGN 0x100
93251 +#define FMAN_BMI_FIFO_UNITS 0x100
93252 +
93253 +
93254 +/**************************************************************************//**
93255 + @Description QMI defines
93256 +*//***************************************************************************/
93257 +/* masks */
93258 +#define QMI_CFG_ENQ_EN 0x80000000
93259 +#define QMI_CFG_DEQ_EN 0x40000000
93260 +#define QMI_CFG_EN_COUNTERS 0x10000000
93261 +#define QMI_CFG_SOFT_RESET 0x01000000
93262 +#define QMI_CFG_DEQ_MASK 0x0000003F
93263 +#define QMI_CFG_ENQ_MASK 0x00003F00
93264 +
93265 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
93266 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
93267 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
93268 +
93269 +/* shifts */
93270 +#define QMI_CFG_ENQ_SHIFT 8
93271 +#define QMI_TAPC_TAP 22
93272 +
93273 +#define QMI_GS_HALT_NOT_BUSY 0x00000002
93274 +
93275 +/**************************************************************************//**
93276 + @Description IRAM defines
93277 +*//***************************************************************************/
93278 +/* masks */
93279 +#define IRAM_IADD_AIE 0x80000000
93280 +#define IRAM_READY 0x80000000
93281 +
93282 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg);
93283 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg);
93284 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg);
93285 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg);
93286 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg);
93287 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg);
93288 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg);
93289 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg);
93290 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg);
93291 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg);
93292 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg,
93293 + uint8_t event_reg_id);
93294 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg);
93295 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg);
93296 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
93297 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg);
93298 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
93299 + uint8_t port_id);
93300 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
93301 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg,
93302 + uint8_t port_id);
93303 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
93304 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg,
93305 + uint8_t port_id);
93306 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg);
93307 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg,
93308 + uint8_t reg_id);
93309 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg);
93310 +void fman_get_revision(struct fman_fpm_regs *fpm_rg, uint8_t *major,
93311 + uint8_t *minor);
93312 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
93313 + enum fman_counters reg_name);
93314 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg);
93315 +
93316 +
93317 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg);
93318 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id,
93319 + uint32_t enable_events);
93320 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
93321 + uint8_t port_id,
93322 + uint8_t num_fman_ctrls,
93323 + uint32_t or_fman_ctrl);
93324 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
93325 + uint8_t port_id,
93326 + bool independent_mode,
93327 + bool is_rx_port);
93328 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
93329 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
93330 +void fman_set_liodn_per_port(struct fman_rg *fman_rg,
93331 + uint8_t port_id,
93332 + uint16_t liodn_base,
93333 + uint16_t liodn_offset);
93334 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
93335 + uint8_t port_id,
93336 + uint32_t size_of_fifo,
93337 + uint32_t extra_size_of_fifo);
93338 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
93339 + uint8_t port_id,
93340 + uint8_t num_of_tasks,
93341 + uint8_t num_of_extra_tasks);
93342 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
93343 + uint8_t port_id,
93344 + uint8_t num_of_open_dmas,
93345 + uint8_t num_of_extra_open_dmas,
93346 + uint8_t total_num_of_dmas);
93347 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights);
93348 +int fman_set_exception(struct fman_rg *fman_rg,
93349 + enum fman_exceptions exception,
93350 + bool enable);
93351 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, bool is_write,
93352 + bool enable);
93353 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri);
93354 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
93355 + uint32_t congestion_group_id,
93356 + uint8_t piority_bit_map,
93357 + uint32_t reg_num);
93358 +
93359 +
93360 +void fman_defconfig(struct fman_cfg *cfg, bool is_master);
93361 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg);
93362 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg);
93363 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg);
93364 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg);
93365 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg);
93366 +void fman_free_resources(struct fman_rg *fman_rg);
93367 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg);
93368 +void fman_reset(struct fman_fpm_regs *fpm_rg);
93369 +void fman_resume(struct fman_fpm_regs *fpm_rg);
93370 +
93371 +
93372 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
93373 + uint8_t count1ubit,
93374 + uint16_t fm_clk_freq);
93375 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg);
93376 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg);
93377 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg);
93378 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
93379 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t macId, bool is_10g);
93380 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
93381 +bool fman_rams_ecc_is_external_ctl(struct fman_fpm_regs *fpm_rg);
93382 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg);
93383 +int fman_modify_counter(struct fman_rg *fman_rg,
93384 + enum fman_counters reg_name,
93385 + uint32_t val);
93386 +void fman_force_intr(struct fman_rg *fman_rg,
93387 + enum fman_exceptions exception);
93388 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
93389 + uint8_t port_id,
93390 + uint8_t base_storage_profile,
93391 + uint8_t log2_num_of_profiles);
93392 +
93393 +/**************************************************************************//**
93394 + @Description default values
93395 +*//***************************************************************************/
93396 +#define DEFAULT_CATASTROPHIC_ERR E_FMAN_CATAST_ERR_STALL_PORT
93397 +#define DEFAULT_DMA_ERR E_FMAN_DMA_ERR_CATASTROPHIC
93398 +#define DEFAULT_HALT_ON_EXTERNAL_ACTIVATION FALSE /* do not change! if changed, must be disabled for rev1 ! */
93399 +#define DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR FALSE /* do not change! if changed, must be disabled for rev1 ! */
93400 +#define DEFAULT_EXTERNAL_ECC_RAMS_ENABLE FALSE
93401 +#define DEFAULT_AID_OVERRIDE FALSE
93402 +#define DEFAULT_AID_MODE E_FMAN_DMA_AID_OUT_TNUM
93403 +#define DEFAULT_DMA_COMM_Q_LOW 0x2A
93404 +#define DEFAULT_DMA_COMM_Q_HIGH 0x3F
93405 +#define DEFAULT_CACHE_OVERRIDE E_FMAN_DMA_NO_CACHE_OR
93406 +#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES 64
93407 +#define DEFAULT_DMA_DBG_CNT_MODE E_FMAN_DMA_DBG_NO_CNT
93408 +#define DEFAULT_DMA_EN_EMERGENCY FALSE
93409 +#define DEFAULT_DMA_SOS_EMERGENCY 0
93410 +#define DEFAULT_DMA_WATCHDOG 0 /* disabled */
93411 +#define DEFAULT_DMA_EN_EMERGENCY_SMOOTHER FALSE
93412 +#define DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER 0
93413 +#define DEFAULT_DISP_LIMIT 0
93414 +#define DEFAULT_PRS_DISP_TH 16
93415 +#define DEFAULT_PLCR_DISP_TH 16
93416 +#define DEFAULT_KG_DISP_TH 16
93417 +#define DEFAULT_BMI_DISP_TH 16
93418 +#define DEFAULT_QMI_ENQ_DISP_TH 16
93419 +#define DEFAULT_QMI_DEQ_DISP_TH 16
93420 +#define DEFAULT_FM_CTL1_DISP_TH 16
93421 +#define DEFAULT_FM_CTL2_DISP_TH 16
93422 +#define DEFAULT_TNUM_AGING_PERIOD 4
93423 +
93424 +
93425 +#endif /* __FSL_FMAN_H */
93426 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
93427 new file mode 100644
93428 index 00000000..6004e478
93429 --- /dev/null
93430 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
93431 @@ -0,0 +1,1096 @@
93432 +/*
93433 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93434 + *
93435 + * Redistribution and use in source and binary forms, with or without
93436 + * modification, are permitted provided that the following conditions are met:
93437 + * * Redistributions of source code must retain the above copyright
93438 + * notice, this list of conditions and the following disclaimer.
93439 + * * Redistributions in binary form must reproduce the above copyright
93440 + * notice, this list of conditions and the following disclaimer in the
93441 + * documentation and/or other materials provided with the distribution.
93442 + * * Neither the name of Freescale Semiconductor nor the
93443 + * names of its contributors may be used to endorse or promote products
93444 + * derived from this software without specific prior written permission.
93445 + *
93446 + *
93447 + * ALTERNATIVELY, this software may be distributed under the terms of the
93448 + * GNU General Public License ("GPL") as published by the Free Software
93449 + * Foundation, either version 2 of that License or (at your option) any
93450 + * later version.
93451 + *
93452 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93453 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93454 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93455 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93456 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93457 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93458 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93459 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93460 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93461 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93462 + */
93463 +
93464 +#ifndef __FSL_FMAN_DTSEC_H
93465 +#define __FSL_FMAN_DTSEC_H
93466 +
93467 +#include "common/general.h"
93468 +#include "fsl_enet.h"
93469 +
93470 +/**
93471 + * DOC: dTSEC Init sequence
93472 + *
93473 + * To prepare dTSEC block for transfer use the following call sequence:
93474 + *
93475 + * - fman_dtsec_defconfig() - This step is optional and yet recommended. Its
93476 + * use is to obtain the default dTSEC configuration parameters.
93477 + *
93478 + * - Change dtsec configuration in &dtsec_cfg. This structure will be used
93479 + * to customize the dTSEC behavior.
93480 + *
93481 + * - fman_dtsec_init() - Applies the configuration on dTSEC hardware. Note that
93482 + * dTSEC is initialized while both Tx and Rx are disabled.
93483 + *
93484 + * - fman_dtsec_set_mac_address() - Set the station address (mac address).
93485 + * This is used by dTSEC to match against received packets.
93486 + *
93487 + * - fman_dtsec_adjust_link() - Set the link speed and duplex parameters
93488 + * after the PHY establishes the link.
93489 + *
93490 + * - dtsec_enable_tx() and dtsec_enable_rx() to enable transmission and
93491 + * reception.
93492 + */
93493 +
93494 +/**
93495 + * DOC: dTSEC Graceful stop
93496 + *
93497 + * To temporary stop dTSEC activity use fman_dtsec_stop_tx() and
93498 + * fman_dtsec_stop_rx(). Note that these functions request dTSEC graceful stop
93499 + * but return before this stop is complete. To query for graceful stop
93500 + * completion use fman_dtsec_get_event() and check DTSEC_IEVENT_GTSC and
93501 + * DTSEC_IEVENT_GRSC bits. Alternatively the dTSEC interrupt mask can be set to
93502 + * enable graceful stop interrupts.
93503 + *
93504 + * To resume operation after graceful stop use fman_dtsec_start_tx() and
93505 + * fman_dtsec_start_rx().
93506 + */
93507 +
93508 +/**
93509 + * DOC: dTSEC interrupt handling
93510 + *
93511 + * This code does not provide an interrupt handler for dTSEC. Instead this
93512 + * handler should be implemented and registered to the operating system by the
93513 + * caller. Some primitives for accessing the event status and mask registers
93514 + * are provided.
93515 + *
93516 + * See "dTSEC Events" section for a list of events that dTSEC can generate.
93517 + */
93518 +
93519 +/**
93520 + * DOC: dTSEC Events
93521 + *
93522 + * Interrupt events cause dTSEC event bits to be set. Software may poll the
93523 + * event register at any time to check for pending interrupts. If an event
93524 + * occurs and its corresponding enable bit is set in the interrupt mask
93525 + * register, the event also causes a hardware interrupt at the PIC.
93526 + *
93527 + * To poll for event status use the fman_dtsec_get_event() function.
93528 + * To configure the interrupt mask use fman_dtsec_enable_interrupt() and
93529 + * fman_dtsec_disable_interrupt() functions.
93530 + * After servicing a dTSEC interrupt use fman_dtsec_ack_event to reset the
93531 + * serviced event bit.
93532 + *
93533 + * The following events may be signaled by dTSEC hardware:
93534 + *
93535 + * %DTSEC_IEVENT_BABR - Babbling receive error. This bit indicates that
93536 + * a frame was received with length in excess of the MAC's maximum frame length
93537 + * register.
93538 + *
93539 + * %DTSEC_IEVENT_RXC - Receive control (pause frame) interrupt. A pause
93540 + * control frame was received while Rx pause frame handling is enabled.
93541 + * Also see fman_dtsec_handle_rx_pause().
93542 + *
93543 + * %DTSEC_IEVENT_MSRO - MIB counter overflow. The count for one of the MIB
93544 + * counters has exceeded the size of its register.
93545 + *
93546 + * %DTSEC_IEVENT_GTSC - Graceful transmit stop complete. Graceful stop is now
93547 + * complete. The transmitter is in a stopped state, in which only pause frames
93548 + * can be transmitted.
93549 + * Also see fman_dtsec_stop_tx().
93550 + *
93551 + * %DTSEC_IEVENT_BABT - Babbling transmit error. The transmitted frame length
93552 + * has exceeded the value in the MAC's Maximum Frame Length register.
93553 + *
93554 + * %DTSEC_IEVENT_TXC - Transmit control (pause frame) interrupt. his bit
93555 + * indicates that a control frame was transmitted.
93556 + *
93557 + * %DTSEC_IEVENT_TXE - Transmit error. This bit indicates that an error
93558 + * occurred on the transmitted channel. This bit is set whenever any transmit
93559 + * error occurs which causes the dTSEC to discard all or part of a frame
93560 + * (LC, CRL, XFUN).
93561 + *
93562 + * %DTSEC_IEVENT_LC - Late collision. This bit indicates that a collision
93563 + * occurred beyond the collision window (slot time) in half-duplex mode.
93564 + * The frame is truncated with a bad CRC and the remainder of the frame
93565 + * is discarded.
93566 + *
93567 + * %DTSEC_IEVENT_CRL - Collision retry limit. is bit indicates that the number
93568 + * of successive transmission collisions has exceeded the MAC's half-duplex
93569 + * register's retransmission maximum count. The frame is discarded without
93570 + * being transmitted and transmission of the next frame commences. This only
93571 + * occurs while in half-duplex mode.
93572 + * The number of retransmit attempts can be set in
93573 + * &dtsec_halfdup_cfg.@retransmit before calling fman_dtsec_init().
93574 + *
93575 + * %DTSEC_IEVENT_XFUN - Transmit FIFO underrun. This bit indicates that the
93576 + * transmit FIFO became empty before the complete frame was transmitted.
93577 + * The frame is truncated with a bad CRC and the remainder of the frame is
93578 + * discarded.
93579 + *
93580 + * %DTSEC_IEVENT_MAG - TBD
93581 + *
93582 + * %DTSEC_IEVENT_MMRD - MII management read completion.
93583 + *
93584 + * %DTSEC_IEVENT_MMWR - MII management write completion.
93585 + *
93586 + * %DTSEC_IEVENT_GRSC - Graceful receive stop complete. It allows the user to
93587 + * know if the system has completed the stop and it is safe to write to receive
93588 + * registers (status, control or configuration registers) that are used by the
93589 + * system during normal operation.
93590 + *
93591 + * %DTSEC_IEVENT_TDPE - Internal data error on transmit. This bit indicates
93592 + * that the dTSEC has detected a parity error on its stored transmit data, which
93593 + * is likely to compromise the validity of recently transferred frames.
93594 + *
93595 + * %DTSEC_IEVENT_RDPE - Internal data error on receive. This bit indicates that
93596 + * the dTSEC has detected a parity error on its stored receive data, which is
93597 + * likely to compromise the validity of recently transferred frames.
93598 + */
93599 +/* Interrupt Mask Register (IMASK) */
93600 +#define DTSEC_IMASK_BREN 0x80000000
93601 +#define DTSEC_IMASK_RXCEN 0x40000000
93602 +#define DTSEC_IMASK_MSROEN 0x04000000
93603 +#define DTSEC_IMASK_GTSCEN 0x02000000
93604 +#define DTSEC_IMASK_BTEN 0x01000000
93605 +#define DTSEC_IMASK_TXCEN 0x00800000
93606 +#define DTSEC_IMASK_TXEEN 0x00400000
93607 +#define DTSEC_IMASK_LCEN 0x00040000
93608 +#define DTSEC_IMASK_CRLEN 0x00020000
93609 +#define DTSEC_IMASK_XFUNEN 0x00010000
93610 +#define DTSEC_IMASK_ABRTEN 0x00008000
93611 +#define DTSEC_IMASK_IFERREN 0x00004000
93612 +#define DTSEC_IMASK_MAGEN 0x00000800
93613 +#define DTSEC_IMASK_MMRDEN 0x00000400
93614 +#define DTSEC_IMASK_MMWREN 0x00000200
93615 +#define DTSEC_IMASK_GRSCEN 0x00000100
93616 +#define DTSEC_IMASK_TDPEEN 0x00000002
93617 +#define DTSEC_IMASK_RDPEEN 0x00000001
93618 +
93619 +#define DTSEC_EVENTS_MASK \
93620 + ((uint32_t)(DTSEC_IMASK_BREN | \
93621 + DTSEC_IMASK_RXCEN | \
93622 + DTSEC_IMASK_BTEN | \
93623 + DTSEC_IMASK_TXCEN | \
93624 + DTSEC_IMASK_TXEEN | \
93625 + DTSEC_IMASK_ABRTEN | \
93626 + DTSEC_IMASK_LCEN | \
93627 + DTSEC_IMASK_CRLEN | \
93628 + DTSEC_IMASK_XFUNEN | \
93629 + DTSEC_IMASK_IFERREN | \
93630 + DTSEC_IMASK_MAGEN | \
93631 + DTSEC_IMASK_TDPEEN | \
93632 + DTSEC_IMASK_RDPEEN))
93633 +
93634 +/* dtsec timestamp event bits */
93635 +#define TMR_PEMASK_TSREEN 0x00010000
93636 +#define TMR_PEVENT_TSRE 0x00010000
93637 +
93638 +/* Group address bit indication */
93639 +#define MAC_GROUP_ADDRESS 0x0000010000000000ULL
93640 +/* size in bytes of L2 address */
93641 +#define MAC_ADDRLEN 6
93642 +
93643 +#define DEFAULT_HALFDUP_ON FALSE
93644 +#define DEFAULT_HALFDUP_RETRANSMIT 0xf
93645 +#define DEFAULT_HALFDUP_COLL_WINDOW 0x37
93646 +#define DEFAULT_HALFDUP_EXCESS_DEFER TRUE
93647 +#define DEFAULT_HALFDUP_NO_BACKOFF FALSE
93648 +#define DEFAULT_HALFDUP_BP_NO_BACKOFF FALSE
93649 +#define DEFAULT_HALFDUP_ALT_BACKOFF_VAL 0x0A
93650 +#define DEFAULT_HALFDUP_ALT_BACKOFF_EN FALSE
93651 +#define DEFAULT_RX_DROP_BCAST FALSE
93652 +#define DEFAULT_RX_SHORT_FRM TRUE
93653 +#define DEFAULT_RX_LEN_CHECK FALSE
93654 +#define DEFAULT_TX_PAD_CRC TRUE
93655 +#define DEFAULT_TX_CRC FALSE
93656 +#define DEFAULT_RX_CTRL_ACC FALSE
93657 +#define DEFAULT_TX_PAUSE_TIME 0xf000
93658 +#define DEFAULT_TBIPA 5
93659 +#define DEFAULT_RX_PREPEND 0
93660 +#define DEFAULT_PTP_TSU_EN TRUE
93661 +#define DEFAULT_PTP_EXCEPTION_EN TRUE
93662 +#define DEFAULT_PREAMBLE_LEN 7
93663 +#define DEFAULT_RX_PREAMBLE FALSE
93664 +#define DEFAULT_TX_PREAMBLE FALSE
93665 +#define DEFAULT_LOOPBACK FALSE
93666 +#define DEFAULT_RX_TIME_STAMP_EN FALSE
93667 +#define DEFAULT_TX_TIME_STAMP_EN FALSE
93668 +#define DEFAULT_RX_FLOW TRUE
93669 +#define DEFAULT_TX_FLOW TRUE
93670 +#define DEFAULT_RX_GROUP_HASH_EXD FALSE
93671 +#define DEFAULT_TX_PAUSE_TIME_EXTD 0
93672 +#define DEFAULT_RX_PROMISC FALSE
93673 +#define DEFAULT_NON_BACK_TO_BACK_IPG1 0x40
93674 +#define DEFAULT_NON_BACK_TO_BACK_IPG2 0x60
93675 +#define DEFAULT_MIN_IFG_ENFORCEMENT 0x50
93676 +#define DEFAULT_BACK_TO_BACK_IPG 0x60
93677 +#define DEFAULT_MAXIMUM_FRAME 0x600
93678 +#define DEFAULT_TBI_PHY_ADDR 5
93679 +#define DEFAULT_WAKE_ON_LAN FALSE
93680 +
93681 +/* register related defines (bits, field offsets..) */
93682 +#define DTSEC_ID1_ID 0xffff0000
93683 +#define DTSEC_ID1_REV_MJ 0x0000FF00
93684 +#define DTSEC_ID1_REV_MN 0x000000ff
93685 +
93686 +#define DTSEC_ID2_INT_REDUCED_OFF 0x00010000
93687 +#define DTSEC_ID2_INT_NORMAL_OFF 0x00020000
93688 +
93689 +#define DTSEC_ECNTRL_CLRCNT 0x00004000
93690 +#define DTSEC_ECNTRL_AUTOZ 0x00002000
93691 +#define DTSEC_ECNTRL_STEN 0x00001000
93692 +#define DTSEC_ECNTRL_CFG_RO 0x80000000
93693 +#define DTSEC_ECNTRL_GMIIM 0x00000040
93694 +#define DTSEC_ECNTRL_TBIM 0x00000020
93695 +#define DTSEC_ECNTRL_SGMIIM 0x00000002
93696 +#define DTSEC_ECNTRL_RPM 0x00000010
93697 +#define DTSEC_ECNTRL_R100M 0x00000008
93698 +#define DTSEC_ECNTRL_RMM 0x00000004
93699 +#define DTSEC_ECNTRL_QSGMIIM 0x00000001
93700 +
93701 +#define DTSEC_TCTRL_THDF 0x00000800
93702 +#define DTSEC_TCTRL_TTSE 0x00000040
93703 +#define DTSEC_TCTRL_GTS 0x00000020
93704 +#define DTSEC_TCTRL_TFC_PAUSE 0x00000010
93705 +
93706 +/* PTV offsets */
93707 +#define PTV_PTE_OFST 16
93708 +
93709 +#define RCTRL_CFA 0x00008000
93710 +#define RCTRL_GHTX 0x00000400
93711 +#define RCTRL_RTSE 0x00000040
93712 +#define RCTRL_GRS 0x00000020
93713 +#define RCTRL_BC_REJ 0x00000010
93714 +#define RCTRL_MPROM 0x00000008
93715 +#define RCTRL_RSF 0x00000004
93716 +#define RCTRL_UPROM 0x00000001
93717 +#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM)
93718 +
93719 +#define TMR_CTL_ESFDP 0x00000800
93720 +#define TMR_CTL_ESFDE 0x00000400
93721 +
93722 +#define MACCFG1_SOFT_RESET 0x80000000
93723 +#define MACCFG1_LOOPBACK 0x00000100
93724 +#define MACCFG1_RX_FLOW 0x00000020
93725 +#define MACCFG1_TX_FLOW 0x00000010
93726 +#define MACCFG1_TX_EN 0x00000001
93727 +#define MACCFG1_RX_EN 0x00000004
93728 +#define MACCFG1_RESET_RxMC 0x00080000
93729 +#define MACCFG1_RESET_TxMC 0x00040000
93730 +#define MACCFG1_RESET_RxFUN 0x00020000
93731 +#define MACCFG1_RESET_TxFUN 0x00010000
93732 +
93733 +#define MACCFG2_NIBBLE_MODE 0x00000100
93734 +#define MACCFG2_BYTE_MODE 0x00000200
93735 +#define MACCFG2_PRE_AM_Rx_EN 0x00000080
93736 +#define MACCFG2_PRE_AM_Tx_EN 0x00000040
93737 +#define MACCFG2_LENGTH_CHECK 0x00000010
93738 +#define MACCFG2_MAGIC_PACKET_EN 0x00000008
93739 +#define MACCFG2_PAD_CRC_EN 0x00000004
93740 +#define MACCFG2_CRC_EN 0x00000002
93741 +#define MACCFG2_FULL_DUPLEX 0x00000001
93742 +
93743 +#define PREAMBLE_LENGTH_SHIFT 12
93744 +
93745 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24
93746 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16
93747 +#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8
93748 +
93749 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000
93750 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000
93751 +#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00
93752 +#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F
93753 +
93754 +#define HAFDUP_ALT_BEB 0x00080000
93755 +#define HAFDUP_BP_NO_BACKOFF 0x00040000
93756 +#define HAFDUP_NO_BACKOFF 0x00020000
93757 +#define HAFDUP_EXCESS_DEFER 0x00010000
93758 +#define HAFDUP_COLLISION_WINDOW 0x000003ff
93759 +
93760 +#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20
93761 +#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12
93762 +#define HAFDUP_RETRANSMISSION_MAX 0x0000f000
93763 +
93764 +#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */
93765 +
93766 +/* CAR1/2 bits */
93767 +#define DTSEC_CAR1_TR64 0x80000000
93768 +#define DTSEC_CAR1_TR127 0x40000000
93769 +#define DTSEC_CAR1_TR255 0x20000000
93770 +#define DTSEC_CAR1_TR511 0x10000000
93771 +#define DTSEC_CAR1_TRK1 0x08000000
93772 +#define DTSEC_CAR1_TRMAX 0x04000000
93773 +#define DTSEC_CAR1_TRMGV 0x02000000
93774 +
93775 +#define DTSEC_CAR1_RBYT 0x00010000
93776 +#define DTSEC_CAR1_RPKT 0x00008000
93777 +#define DTSEC_CAR1_RFCS 0x00004000
93778 +#define DTSEC_CAR1_RMCA 0x00002000
93779 +#define DTSEC_CAR1_RBCA 0x00001000
93780 +#define DTSEC_CAR1_RXCF 0x00000800
93781 +#define DTSEC_CAR1_RXPF 0x00000400
93782 +#define DTSEC_CAR1_RXUO 0x00000200
93783 +#define DTSEC_CAR1_RALN 0x00000100
93784 +#define DTSEC_CAR1_RFLR 0x00000080
93785 +#define DTSEC_CAR1_RCDE 0x00000040
93786 +#define DTSEC_CAR1_RCSE 0x00000020
93787 +#define DTSEC_CAR1_RUND 0x00000010
93788 +#define DTSEC_CAR1_ROVR 0x00000008
93789 +#define DTSEC_CAR1_RFRG 0x00000004
93790 +#define DTSEC_CAR1_RJBR 0x00000002
93791 +#define DTSEC_CAR1_RDRP 0x00000001
93792 +
93793 +#define DTSEC_CAR2_TJBR 0x00080000
93794 +#define DTSEC_CAR2_TFCS 0x00040000
93795 +#define DTSEC_CAR2_TXCF 0x00020000
93796 +#define DTSEC_CAR2_TOVR 0x00010000
93797 +#define DTSEC_CAR2_TUND 0x00008000
93798 +#define DTSEC_CAR2_TFRG 0x00004000
93799 +#define DTSEC_CAR2_TBYT 0x00002000
93800 +#define DTSEC_CAR2_TPKT 0x00001000
93801 +#define DTSEC_CAR2_TMCA 0x00000800
93802 +#define DTSEC_CAR2_TBCA 0x00000400
93803 +#define DTSEC_CAR2_TXPF 0x00000200
93804 +#define DTSEC_CAR2_TDFR 0x00000100
93805 +#define DTSEC_CAR2_TEDF 0x00000080
93806 +#define DTSEC_CAR2_TSCL 0x00000040
93807 +#define DTSEC_CAR2_TMCL 0x00000020
93808 +#define DTSEC_CAR2_TLCL 0x00000010
93809 +#define DTSEC_CAR2_TXCL 0x00000008
93810 +#define DTSEC_CAR2_TNCL 0x00000004
93811 +#define DTSEC_CAR2_TDRP 0x00000001
93812 +
93813 +#define CAM1_ERRORS_ONLY \
93814 + (DTSEC_CAR1_RXPF | DTSEC_CAR1_RALN | DTSEC_CAR1_RFLR \
93815 + | DTSEC_CAR1_RCDE | DTSEC_CAR1_RCSE | DTSEC_CAR1_RUND \
93816 + | DTSEC_CAR1_ROVR | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93817 + | DTSEC_CAR1_RDRP)
93818 +
93819 +#define CAM2_ERRORS_ONLY (DTSEC_CAR2_TFCS | DTSEC_CAR2_TXPF | DTSEC_CAR2_TDRP)
93820 +
93821 +/*
93822 + * Group of dTSEC specific counters relating to the standard RMON MIB Group 1
93823 + * (or Ethernet) statistics.
93824 + */
93825 +#define CAM1_MIB_GRP_1 \
93826 + (DTSEC_CAR1_RDRP | DTSEC_CAR1_RBYT | DTSEC_CAR1_RPKT | DTSEC_CAR1_RMCA\
93827 + | DTSEC_CAR1_RBCA | DTSEC_CAR1_RALN | DTSEC_CAR1_RUND | DTSEC_CAR1_ROVR\
93828 + | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93829 + | DTSEC_CAR1_TR64 | DTSEC_CAR1_TR127 | DTSEC_CAR1_TR255 \
93830 + | DTSEC_CAR1_TR511 | DTSEC_CAR1_TRMAX)
93831 +
93832 +#define CAM2_MIB_GRP_1 (DTSEC_CAR2_TNCL | DTSEC_CAR2_TDRP)
93833 +
93834 +/* memory map */
93835 +
93836 +struct dtsec_regs {
93837 + /* dTSEC General Control and Status Registers */
93838 + uint32_t tsec_id; /* 0x000 ETSEC_ID register */
93839 + uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */
93840 + uint32_t ievent; /* 0x008 Interrupt event register */
93841 + uint32_t imask; /* 0x00C Interrupt mask register */
93842 + uint32_t reserved0010[1];
93843 + uint32_t ecntrl; /* 0x014 E control register */
93844 + uint32_t ptv; /* 0x018 Pause time value register */
93845 + uint32_t tbipa; /* 0x01C TBI PHY address register */
93846 + uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */
93847 + uint32_t tmr_pevent; /* 0x024 Time-stamp event register */
93848 + uint32_t tmr_pemask; /* 0x028 Timer event mask register */
93849 + uint32_t reserved002c[5];
93850 + uint32_t tctrl; /* 0x040 Transmit control register */
93851 + uint32_t reserved0044[3];
93852 + uint32_t rctrl; /* 0x050 Receive control register */
93853 + uint32_t reserved0054[11];
93854 + uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address */
93855 + uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */
93856 + uint32_t reserved00c0[16];
93857 + uint32_t maccfg1; /* 0x100 MAC configuration #1 */
93858 + uint32_t maccfg2; /* 0x104 MAC configuration #2 */
93859 + uint32_t ipgifg; /* 0x108 IPG/IFG */
93860 + uint32_t hafdup; /* 0x10C Half-duplex */
93861 + uint32_t maxfrm; /* 0x110 Maximum frame */
93862 + uint32_t reserved0114[10];
93863 + uint32_t ifstat; /* 0x13C Interface status */
93864 + uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */
93865 + uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */
93866 + struct {
93867 + uint32_t exact_match1; /* octets 1-4 */
93868 + uint32_t exact_match2; /* octets 5-6 */
93869 + } macaddr[15]; /* 0x148-0x1BC mac exact match addresses 1-15 */
93870 + uint32_t reserved01c0[16];
93871 + uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */
93872 + uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame
93873 + * counter */
93874 + uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame
93875 + * counter */
93876 + uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame
93877 + * counter */
93878 + uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame
93879 + * counter */
93880 + uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame
93881 + * counter */
93882 + uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good
93883 + * VLAN frame count */
93884 + uint32_t rbyt; /* 0x21C receive byte counter */
93885 + uint32_t rpkt; /* 0x220 receive packet counter */
93886 + uint32_t rfcs; /* 0x224 receive FCS error counter */
93887 + uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */
93888 + uint32_t rbca; /* 0x22C receive broadcast packet counter */
93889 + uint32_t rxcf; /* 0x230 receive control frame packet counter */
93890 + uint32_t rxpf; /* 0x234 receive pause frame packet counter */
93891 + uint32_t rxuo; /* 0x238 receive unknown OP code counter */
93892 + uint32_t raln; /* 0x23C receive alignment error counter */
93893 + uint32_t rflr; /* 0x240 receive frame length error counter */
93894 + uint32_t rcde; /* 0x244 receive code error counter */
93895 + uint32_t rcse; /* 0x248 receive carrier sense error counter */
93896 + uint32_t rund; /* 0x24C receive undersize packet counter */
93897 + uint32_t rovr; /* 0x250 receive oversize packet counter */
93898 + uint32_t rfrg; /* 0x254 receive fragments counter */
93899 + uint32_t rjbr; /* 0x258 receive jabber counter */
93900 + uint32_t rdrp; /* 0x25C receive drop */
93901 + uint32_t tbyt; /* 0x260 transmit byte counter */
93902 + uint32_t tpkt; /* 0x264 transmit packet counter */
93903 + uint32_t tmca; /* 0x268 transmit multicast packet counter */
93904 + uint32_t tbca; /* 0x26C transmit broadcast packet counter */
93905 + uint32_t txpf; /* 0x270 transmit pause control frame counter */
93906 + uint32_t tdfr; /* 0x274 transmit deferral packet counter */
93907 + uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */
93908 + uint32_t tscl; /* 0x27C transmit single collision packet counter */
93909 + uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */
93910 + uint32_t tlcl; /* 0x284 transmit late collision packet counter */
93911 + uint32_t txcl; /* 0x288 transmit excessive collision packet counter */
93912 + uint32_t tncl; /* 0x28C transmit total collision counter */
93913 + uint32_t reserved0290[1];
93914 + uint32_t tdrp; /* 0x294 transmit drop frame counter */
93915 + uint32_t tjbr; /* 0x298 transmit jabber frame counter */
93916 + uint32_t tfcs; /* 0x29C transmit FCS error counter */
93917 + uint32_t txcf; /* 0x2A0 transmit control frame counter */
93918 + uint32_t tovr; /* 0x2A4 transmit oversize frame counter */
93919 + uint32_t tund; /* 0x2A8 transmit undersize frame counter */
93920 + uint32_t tfrg; /* 0x2AC transmit fragments frame counter */
93921 + uint32_t car1; /* 0x2B0 carry register one register* */
93922 + uint32_t car2; /* 0x2B4 carry register two register* */
93923 + uint32_t cam1; /* 0x2B8 carry register one mask register */
93924 + uint32_t cam2; /* 0x2BC carry register two mask register */
93925 + uint32_t reserved02c0[848];
93926 +};
93927 +
93928 +/**
93929 + * struct dtsec_mib_grp_1_counters - MIB counter overflows
93930 + *
93931 + * @tr64: Transmit and Receive 64 byte frame count. Increment for each
93932 + * good or bad frame, of any type, transmitted or received, which
93933 + * is 64 bytes in length.
93934 + * @tr127: Transmit and Receive 65 to 127 byte frame count. Increments for
93935 + * each good or bad frame of any type, transmitted or received,
93936 + * which is 65-127 bytes in length.
93937 + * @tr255: Transmit and Receive 128 to 255 byte frame count. Increments
93938 + * for each good or bad frame, of any type, transmitted or
93939 + * received, which is 128-255 bytes in length.
93940 + * @tr511: Transmit and Receive 256 to 511 byte frame count. Increments
93941 + * for each good or bad frame, of any type, transmitted or
93942 + * received, which is 256-511 bytes in length.
93943 + * @tr1k: Transmit and Receive 512 to 1023 byte frame count. Increments
93944 + * for each good or bad frame, of any type, transmitted or
93945 + * received, which is 512-1023 bytes in length.
93946 + * @trmax: Transmit and Receive 1024 to 1518 byte frame count. Increments
93947 + * for each good or bad frame, of any type, transmitted or
93948 + * received, which is 1024-1518 bytes in length.
93949 + * @rfrg: Receive fragments count. Increments for each received frame
93950 + * which is less than 64 bytes in length and contains an invalid
93951 + * FCS. This includes integral and non-integral lengths.
93952 + * @rjbr: Receive jabber count. Increments for received frames which
93953 + * exceed 1518 (non VLAN) or 1522 (VLAN) bytes and contain an
93954 + * invalid FCS. This includes alignment errors.
93955 + * @rdrp: Receive dropped packets count. Increments for received frames
93956 + * which are streamed to system but are later dropped due to lack
93957 + * of system resources. Does not increment for frames rejected due
93958 + * to address filtering.
93959 + * @raln: Receive alignment error count. Increments for each received
93960 + * frame from 64 to 1518 (non VLAN) or 1522 (VLAN) which contains
93961 + * an invalid FCS and is not an integral number of bytes.
93962 + * @rund: Receive undersize packet count. Increments each time a frame is
93963 + * received which is less than 64 bytes in length and contains a
93964 + * valid FCS and is otherwise well formed. This count does not
93965 + * include range length errors.
93966 + * @rovr: Receive oversize packet count. Increments each time a frame is
93967 + * received which exceeded 1518 (non VLAN) or 1522 (VLAN) and
93968 + * contains a valid FCS and is otherwise well formed.
93969 + * @rbyt: Receive byte count. Increments by the byte count of frames
93970 + * received, including those in bad packets, excluding preamble and
93971 + * SFD but including FCS bytes.
93972 + * @rpkt: Receive packet count. Increments for each received frame
93973 + * (including bad packets, all unicast, broadcast, and multicast
93974 + * packets).
93975 + * @rmca: Receive multicast packet count. Increments for each multicast
93976 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93977 + * 1522 (VLAN), excluding broadcast frames. This count does not
93978 + * include range/length errors.
93979 + * @rbca: Receive broadcast packet count. Increments for each broadcast
93980 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93981 + * 1522 (VLAN), excluding multicast frames. Does not include
93982 + * range/length errors.
93983 + * @tdrp: Transmit drop frame count. Increments each time a memory error
93984 + * or an underrun has occurred.
93985 + * @tncl: Transmit total collision counter. Increments by the number of
93986 + * collisions experienced during the transmission of a frame. Does
93987 + * not increment for aborted frames.
93988 + *
93989 + * The structure contains a group of dTSEC HW specific counters relating to the
93990 + * standard RMON MIB Group 1 (or Ethernet statistics) counters. This structure
93991 + * is counting only the carry events of the corresponding HW counters.
93992 + *
93993 + * tr64 to trmax notes: Frame sizes specified are considered excluding preamble
93994 + * and SFD but including FCS bytes.
93995 + */
93996 +struct dtsec_mib_grp_1_counters {
93997 + uint64_t rdrp;
93998 + uint64_t tdrp;
93999 + uint64_t rbyt;
94000 + uint64_t rpkt;
94001 + uint64_t rbca;
94002 + uint64_t rmca;
94003 + uint64_t raln;
94004 + uint64_t rund;
94005 + uint64_t rovr;
94006 + uint64_t rfrg;
94007 + uint64_t rjbr;
94008 + uint64_t tncl;
94009 + uint64_t tr64;
94010 + uint64_t tr127;
94011 + uint64_t tr255;
94012 + uint64_t tr511;
94013 + uint64_t tr1k;
94014 + uint64_t trmax;
94015 +};
94016 +
94017 +enum dtsec_stat_counters {
94018 + E_DTSEC_STAT_TR64,
94019 + E_DTSEC_STAT_TR127,
94020 + E_DTSEC_STAT_TR255,
94021 + E_DTSEC_STAT_TR511,
94022 + E_DTSEC_STAT_TR1K,
94023 + E_DTSEC_STAT_TRMAX,
94024 + E_DTSEC_STAT_TRMGV,
94025 + E_DTSEC_STAT_RBYT,
94026 + E_DTSEC_STAT_RPKT,
94027 + E_DTSEC_STAT_RMCA,
94028 + E_DTSEC_STAT_RBCA,
94029 + E_DTSEC_STAT_RXPF,
94030 + E_DTSEC_STAT_RALN,
94031 + E_DTSEC_STAT_RFLR,
94032 + E_DTSEC_STAT_RCDE,
94033 + E_DTSEC_STAT_RCSE,
94034 + E_DTSEC_STAT_RUND,
94035 + E_DTSEC_STAT_ROVR,
94036 + E_DTSEC_STAT_RFRG,
94037 + E_DTSEC_STAT_RJBR,
94038 + E_DTSEC_STAT_RDRP,
94039 + E_DTSEC_STAT_TFCS,
94040 + E_DTSEC_STAT_TBYT,
94041 + E_DTSEC_STAT_TPKT,
94042 + E_DTSEC_STAT_TMCA,
94043 + E_DTSEC_STAT_TBCA,
94044 + E_DTSEC_STAT_TXPF,
94045 + E_DTSEC_STAT_TNCL,
94046 + E_DTSEC_STAT_TDRP
94047 +};
94048 +
94049 +enum dtsec_stat_level {
94050 + /* No statistics */
94051 + E_MAC_STAT_NONE = 0,
94052 + /* Only RMON MIB group 1 (ether stats). Optimized for performance */
94053 + E_MAC_STAT_MIB_GRP1,
94054 + /* Only error counters are available. Optimized for performance */
94055 + E_MAC_STAT_PARTIAL,
94056 + /* All counters available. Not optimized for performance */
94057 + E_MAC_STAT_FULL
94058 +};
94059 +
94060 +
94061 +/**
94062 + * struct dtsec_cfg - dTSEC configuration
94063 + *
94064 + * @halfdup_on: Transmit half-duplex flow control, under software
94065 + * control for 10/100-Mbps half-duplex media. If set,
94066 + * back pressure is applied to media by raising carrier.
94067 + * @halfdup_retransmit: Number of retransmission attempts following a collision.
94068 + * If this is exceeded dTSEC aborts transmission due to
94069 + * excessive collisions. The standard specifies the
94070 + * attempt limit to be 15.
94071 + * @halfdup_coll_window:The number of bytes of the frame during which
94072 + * collisions may occur. The default value of 55
94073 + * corresponds to the frame byte at the end of the
94074 + * standard 512-bit slot time window. If collisions are
94075 + * detected after this byte, the late collision event is
94076 + * asserted and transmission of current frame is aborted.
94077 + * @rx_drop_bcast: Discard broadcast frames. If set, all broadcast frames
94078 + * will be discarded by dTSEC.
94079 + * @rx_short_frm: Accept short frames. If set, dTSEC will accept frames
94080 + * of length 14..63 bytes.
94081 + * @rx_len_check: Length check for received frames. If set, the MAC
94082 + * checks the frame's length field on receive to ensure it
94083 + * matches the actual data field length. This only works
94084 + * for received frames with length field less than 1500.
94085 + * No check is performed for larger frames.
94086 + * @tx_pad_crc: Pad and append CRC. If set, the MAC pads all
94087 + * transmitted short frames and appends a CRC to every
94088 + * frame regardless of padding requirement.
94089 + * @tx_crc: Transmission CRC enable. If set, the MAC appends a CRC
94090 + * to all frames. If frames presented to the MAC have a
94091 + * valid length and contain a valid CRC, @tx_crc should be
94092 + * reset.
94093 + * This field is ignored if @tx_pad_crc is set.
94094 + * @rx_ctrl_acc: Control frame accept. If set, this overrides 802.3
94095 + * standard control frame behavior, and all Ethernet frames
94096 + * that have an ethertype of 0x8808 are treated as normal
94097 + * Ethernet frames and passed up to the packet interface on
94098 + * a DA match. Received pause control frames are passed to
94099 + * the packet interface only if Rx flow control is also
94100 + * disabled. See fman_dtsec_handle_rx_pause() function.
94101 + * @tx_pause_time: Transmit pause time value. This pause value is used as
94102 + * part of the pause frame to be sent when a transmit pause
94103 + * frame is initiated. If set to 0 this disables
94104 + * transmission of pause frames.
94105 + * @rx_preamble: Receive preamble enable. If set, the MAC recovers the
94106 + * received Ethernet 7-byte preamble and passes it to the
94107 + * packet interface at the start of each received frame.
94108 + * This field should be reset for internal MAC loop-back
94109 + * mode.
94110 + * @tx_preamble: User defined preamble enable for transmitted frames.
94111 + * If set, a user-defined preamble must passed to the MAC
94112 + * and it is transmitted instead of the standard preamble.
94113 + * @preamble_len: Length, in bytes, of the preamble field preceding each
94114 + * Ethernet start-of-frame delimiter byte. The default
94115 + * value of 0x7 should be used in order to guarantee
94116 + * reliable operation with IEEE 802.3 compliant hardware.
94117 + * @rx_prepend: Packet alignment padding length. The specified number
94118 + * of bytes (1-31) of zero padding are inserted before the
94119 + * start of each received frame. For Ethernet, where
94120 + * optional preamble extraction is enabled, the padding
94121 + * appears before the preamble, otherwise the padding
94122 + * precedes the layer 2 header.
94123 + *
94124 + * This structure contains basic dTSEC configuration and must be passed to
94125 + * fman_dtsec_init() function. A default set of configuration values can be
94126 + * obtained by calling fman_dtsec_defconfig().
94127 + */
94128 +struct dtsec_cfg {
94129 + bool halfdup_on;
94130 + bool halfdup_alt_backoff_en;
94131 + bool halfdup_excess_defer;
94132 + bool halfdup_no_backoff;
94133 + bool halfdup_bp_no_backoff;
94134 + uint8_t halfdup_alt_backoff_val;
94135 + uint16_t halfdup_retransmit;
94136 + uint16_t halfdup_coll_window;
94137 + bool rx_drop_bcast;
94138 + bool rx_short_frm;
94139 + bool rx_len_check;
94140 + bool tx_pad_crc;
94141 + bool tx_crc;
94142 + bool rx_ctrl_acc;
94143 + unsigned short tx_pause_time;
94144 + unsigned short tbipa;
94145 + bool ptp_tsu_en;
94146 + bool ptp_exception_en;
94147 + bool rx_preamble;
94148 + bool tx_preamble;
94149 + unsigned char preamble_len;
94150 + unsigned char rx_prepend;
94151 + bool loopback;
94152 + bool rx_time_stamp_en;
94153 + bool tx_time_stamp_en;
94154 + bool rx_flow;
94155 + bool tx_flow;
94156 + bool rx_group_hash_exd;
94157 + bool rx_promisc;
94158 + uint8_t tbi_phy_addr;
94159 + uint16_t tx_pause_time_extd;
94160 + uint16_t maximum_frame;
94161 + uint32_t non_back_to_back_ipg1;
94162 + uint32_t non_back_to_back_ipg2;
94163 + uint32_t min_ifg_enforcement;
94164 + uint32_t back_to_back_ipg;
94165 + bool wake_on_lan;
94166 +};
94167 +
94168 +
94169 +/**
94170 + * fman_dtsec_defconfig() - Get default dTSEC configuration
94171 + * @cfg: pointer to configuration structure.
94172 + *
94173 + * Call this function to obtain a default set of configuration values for
94174 + * initializing dTSEC. The user can overwrite any of the values before calling
94175 + * fman_dtsec_init(), if specific configuration needs to be applied.
94176 + */
94177 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg);
94178 +
94179 +/**
94180 + * fman_dtsec_init() - Init dTSEC hardware block
94181 + * @regs: Pointer to dTSEC register block
94182 + * @cfg: dTSEC configuration data
94183 + * @iface_mode: dTSEC interface mode, the type of MAC - PHY interface.
94184 + * @iface_speed: 1G or 10G
94185 + * @macaddr: MAC station address to be assigned to the device
94186 + * @fm_rev_maj: major rev number
94187 + * @fm_rev_min: minor rev number
94188 + * @exceptions_mask: initial exceptions mask
94189 + *
94190 + * This function initializes dTSEC and applies basic configuration.
94191 + *
94192 + * dTSEC initialization sequence:
94193 + * Before enabling Rx/Tx call dtsec_set_address() to set MAC address,
94194 + * fman_dtsec_adjust_link() to configure interface speed and duplex and finally
94195 + * dtsec_enable_tx()/dtsec_enable_rx() to start transmission and reception.
94196 + *
94197 + * Returns: 0 if successful, an error code otherwise.
94198 + */
94199 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
94200 + enum enet_interface iface_mode,
94201 + enum enet_speed iface_speed,
94202 + uint8_t *macaddr, uint8_t fm_rev_maj,
94203 + uint8_t fm_rev_min,
94204 + uint32_t exception_mask);
94205 +
94206 +/**
94207 + * fman_dtsec_enable() - Enable dTSEC Tx and Tx
94208 + * @regs: Pointer to dTSEC register block
94209 + * @apply_rx: enable rx side
94210 + * @apply_tx: enable tx side
94211 + *
94212 + * This function resets Tx and Rx graceful stop bit and enables dTSEC Tx and Rx.
94213 + */
94214 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
94215 +
94216 +/**
94217 + * fman_dtsec_disable() - Disable dTSEC Tx and Rx
94218 + * @regs: Pointer to dTSEC register block
94219 + * @apply_rx: disable rx side
94220 + * @apply_tx: disable tx side
94221 + *
94222 + * This function disables Tx and Rx in dTSEC.
94223 + */
94224 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
94225 +
94226 +/**
94227 + * fman_dtsec_get_revision() - Get dTSEC hardware revision
94228 + * @regs: Pointer to dTSEC register block
94229 + *
94230 + * Returns dtsec_id content
94231 + *
94232 + * Call this function to obtain the dTSEC hardware version.
94233 + */
94234 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs);
94235 +
94236 +/**
94237 + * fman_dtsec_set_mac_address() - Set MAC station address
94238 + * @regs: Pointer to dTSEC register block
94239 + * @macaddr: MAC address array
94240 + *
94241 + * This function sets MAC station address. To enable unicast reception call
94242 + * this after fman_dtsec_init(). While promiscuous mode is disabled dTSEC will
94243 + * match the destination address of received unicast frames against this
94244 + * address.
94245 + */
94246 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
94247 +
94248 +/**
94249 + * fman_dtsec_get_mac_address() - Query MAC station address
94250 + * @regs: Pointer to dTSEC register block
94251 + * @macaddr: MAC address array
94252 + */
94253 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
94254 +
94255 +/**
94256 + * fman_dtsec_set_uc_promisc() - Sets unicast promiscuous mode
94257 + * @regs: Pointer to dTSEC register block
94258 + * @enable: Enable unicast promiscuous mode
94259 + *
94260 + * Use this function to enable/disable dTSEC L2 address filtering. If the
94261 + * address filtering is disabled all unicast packets are accepted.
94262 + * To set dTSEC in promiscuous mode call both fman_dtsec_set_uc_promisc() and
94263 + * fman_dtsec_set_mc_promisc() to disable filtering for both unicast and
94264 + * multicast addresses.
94265 + */
94266 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable);
94267 +
94268 +/**
94269 + * fman_dtsec_set_wol() - Enable/Disable wake on lan
94270 + * (magic packet support)
94271 + * @regs: Pointer to dTSEC register block
94272 + * @en: Enable Wake On Lan support in dTSEC
94273 + *
94274 + */
94275 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en);
94276 +
94277 +/**
94278 + * fman_dtsec_adjust_link() - Adjust dTSEC speed/duplex settings
94279 + * @regs: Pointer to dTSEC register block
94280 + * @iface_mode: dTSEC interface mode
94281 + * @speed: Link speed
94282 + * @full_dx: True for full-duplex, false for half-duplex.
94283 + *
94284 + * This function configures the MAC to function and the desired rates. Use it
94285 + * to configure dTSEC after fman_dtsec_init() and whenever the link speed
94286 + * changes (for instance following PHY auto-negociation).
94287 + *
94288 + * Returns: 0 if successful, an error code otherwise.
94289 + */
94290 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
94291 + enum enet_interface iface_mode,
94292 + enum enet_speed speed, bool full_dx);
94293 +
94294 +/**
94295 + * fman_dtsec_set_tbi_phy_addr() - Updates TBI address field
94296 + * @regs: Pointer to dTSEC register block
94297 + * @address: Valid PHY address in the range of 1 to 31. 0 is reserved.
94298 + *
94299 + * In SGMII mode, the dTSEC's TBIPA field must contain a valid TBI PHY address
94300 + * so that the associated TBI PHY (i.e. the link) may be initialized.
94301 + *
94302 + * Returns: 0 if successful, an error code otherwise.
94303 + */
94304 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
94305 + uint8_t addr);
94306 +
94307 +/**
94308 + * fman_dtsec_set_max_frame_len() - Set max frame length
94309 + * @regs: Pointer to dTSEC register block
94310 + * @length: Max frame length.
94311 + *
94312 + * Sets maximum frame length for received and transmitted frames. Frames that
94313 + * exceeds this length are truncated.
94314 + */
94315 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length);
94316 +
94317 +/**
94318 + * fman_dtsec_get_max_frame_len() - Query max frame length
94319 + * @regs: Pointer to dTSEC register block
94320 + *
94321 + * Returns: the current value of the maximum frame length.
94322 + */
94323 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs);
94324 +
94325 +/**
94326 + * fman_dtsec_handle_rx_pause() - Configure pause frame handling
94327 + * @regs: Pointer to dTSEC register block
94328 + * @en: Enable pause frame handling in dTSEC
94329 + *
94330 + * If enabled, dTSEC will handle pause frames internally. This must be disabled
94331 + * if dTSEC is set in half-duplex mode.
94332 + * If pause frame handling is disabled and &dtsec_cfg.rx_ctrl_acc is set, pause
94333 + * frames will be transferred to the packet interface just like regular Ethernet
94334 + * frames.
94335 + */
94336 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en);
94337 +
94338 +/**
94339 + * fman_dtsec_set_tx_pause_frames() - Configure Tx pause time
94340 + * @regs: Pointer to dTSEC register block
94341 + * @time: Time value included in pause frames
94342 + *
94343 + * Call this function to set the time value used in transmitted pause frames.
94344 + * If time is 0, transmission of pause frames is disabled
94345 + */
94346 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time);
94347 +
94348 +/**
94349 + * fman_dtsec_ack_event() - Acknowledge handled events
94350 + * @regs: Pointer to dTSEC register block
94351 + * @ev_mask: Events to acknowledge
94352 + *
94353 + * After handling events signaled by dTSEC in either polling or interrupt mode,
94354 + * call this function to reset the associated status bits in dTSEC event
94355 + * register.
94356 + */
94357 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask);
94358 +
94359 +/**
94360 + * fman_dtsec_get_event() - Returns currently asserted events
94361 + * @regs: Pointer to dTSEC register block
94362 + * @ev_mask: Mask of relevant events
94363 + *
94364 + * Call this function to obtain a bit-mask of events that are currently asserted
94365 + * in dTSEC, taken from IEVENT register.
94366 + *
94367 + * Returns: a bit-mask of events asserted in dTSEC.
94368 + */
94369 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask);
94370 +
94371 +/**
94372 + * fman_dtsec_get_interrupt_mask() - Returns a bit-mask of enabled interrupts
94373 + * @regs: Pointer to dTSEC register block
94374 + *
94375 + * Call this function to obtain a bit-mask of enabled interrupts
94376 + * in dTSEC, taken from IMASK register.
94377 + *
94378 + * Returns: a bit-mask of enabled interrupts in dTSEC.
94379 + */
94380 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs);
94381 +
94382 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs,
94383 + uint8_t paddr_num);
94384 +
94385 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
94386 + uint64_t addr,
94387 + uint8_t paddr_num);
94388 +
94389 +void fman_dtsec_enable_tmr_interrupt (struct dtsec_regs *regs);
94390 +
94391 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs);
94392 +
94393 +/**
94394 + * fman_dtsec_disable_interrupt() - Disables interrupts for the specified events
94395 + * @regs: Pointer to dTSEC register block
94396 + * @ev_mask: Mask of relevant events
94397 + *
94398 + * Call this function to disable interrupts in dTSEC for the specified events.
94399 + * To enable interrupts use fman_dtsec_enable_interrupt().
94400 + */
94401 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
94402 +
94403 +/**
94404 + * fman_dtsec_enable_interrupt() - Enable interrupts for the specified events
94405 + * @regs: Pointer to dTSEC register block
94406 + * @ev_mask: Mask of relevant events
94407 + *
94408 + * Call this function to enable interrupts in dTSEC for the specified events.
94409 + * To disable interrupts use fman_dtsec_disable_interrupt().
94410 + */
94411 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
94412 +
94413 +/**
94414 + * fman_dtsec_set_ts() - Enables dTSEC timestamps
94415 + * @regs: Pointer to dTSEC register block
94416 + * @en: true to enable timestamps, false to disable them
94417 + *
94418 + * Call this function to enable/disable dTSEC timestamps. This affects both
94419 + * Tx and Rx.
94420 + */
94421 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en);
94422 +
94423 +/**
94424 + * fman_dtsec_set_bucket() - Enables/disables a filter bucket
94425 + * @regs: Pointer to dTSEC register block
94426 + * @bucket: Bucket index
94427 + * @enable: true/false to enable/disable this bucket
94428 + *
94429 + * This function enables or disables the specified bucket. Enabling a bucket
94430 + * associated with an address configures dTSEC to accept received packets
94431 + * with that destination address.
94432 + * Multiple addresses may be associated with the same bucket. Disabling a
94433 + * bucket will affect all addresses associated with that bucket. A bucket that
94434 + * is enabled requires further filtering and verification in the upper layers
94435 + *
94436 + */
94437 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable);
94438 +
94439 +/**
94440 + * dtsec_set_hash_table() - insert a crc code into thr filter table
94441 + * @regs: Pointer to dTSEC register block
94442 + * @crc: crc to insert
94443 + * @mcast: true is this is a multicast address
94444 + * @ghtx: true if we are in ghtx mode
94445 + *
94446 + * This function inserts a crc code into the filter table.
94447 + */
94448 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc,
94449 + bool mcast, bool ghtx);
94450 +
94451 +/**
94452 + * fman_dtsec_reset_filter_table() - Resets the address filtering table
94453 + * @regs: Pointer to dTSEC register block
94454 + * @mcast: Reset multicast entries
94455 + * @ucast: Reset unicast entries
94456 + *
94457 + * Resets all entries in L2 address filter table. After calling this function
94458 + * all buckets enabled using fman_dtsec_set_bucket() will be disabled.
94459 + * If dtsec_init_filter_table() was called with @unicast_hash set to false,
94460 + * @ucast argument is ignored.
94461 + * This does not affect the primary nor the 15 additional addresses configured
94462 + * using dtsec_set_address() or dtsec_set_match_address().
94463 + */
94464 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast,
94465 + bool ucast);
94466 +
94467 +/**
94468 + * fman_dtsec_set_mc_promisc() - Set multicast promiscuous mode
94469 + * @regs: Pointer to dTSEC register block
94470 + * @enable: Enable multicast promiscuous mode
94471 + *
94472 + * Call this to enable/disable L2 address filtering for multicast packets.
94473 + */
94474 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable);
94475 +
94476 +/* statistics APIs */
94477 +
94478 +/**
94479 + * fman_dtsec_set_stat_level() - Enable a group of MIB statistics counters
94480 + * @regs: Pointer to dTSEC register block
94481 + * @level: Specifies a certain group of dTSEC MIB HW counters or _all_,
94482 + * to specify all the existing counters.
94483 + * If set to _none_, it disables all the counters.
94484 + *
94485 + * Enables the MIB statistics hw counters and sets up the carry interrupt
94486 + * masks for the counters corresponding to the @level input parameter.
94487 + *
94488 + * Returns: error if invalid @level value given.
94489 + */
94490 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs,
94491 + enum dtsec_stat_level level);
94492 +
94493 +/**
94494 + * fman_dtsec_reset_stat() - Completely resets all dTSEC HW counters
94495 + * @regs: Pointer to dTSEC register block
94496 + */
94497 +void fman_dtsec_reset_stat(struct dtsec_regs *regs);
94498 +
94499 +/**
94500 + * fman_dtsec_get_clear_carry_regs() - Read and clear carry bits (CAR1-2 registers)
94501 + * @regs: Pointer to dTSEC register block
94502 + * @car1: car1 register value
94503 + * @car2: car2 register value
94504 + *
94505 + * When set, the carry bits signal that an overflow occurred on the
94506 + * corresponding counters.
94507 + * Note that the carry bits (CAR1-2 registers) will assert the
94508 + * %DTSEC_IEVENT_MSRO interrupt if unmasked (via CAM1-2 regs).
94509 + *
94510 + * Returns: true if overflow occurred, otherwise - false
94511 + */
94512 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
94513 + uint32_t *car1, uint32_t *car2);
94514 +
94515 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs);
94516 +
94517 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
94518 + enum dtsec_stat_counters reg_name);
94519 +
94520 +void fman_dtsec_start_tx(struct dtsec_regs *regs);
94521 +void fman_dtsec_start_rx(struct dtsec_regs *regs);
94522 +void fman_dtsec_stop_tx(struct dtsec_regs *regs);
94523 +void fman_dtsec_stop_rx(struct dtsec_regs *regs);
94524 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs);
94525 +
94526 +
94527 +#endif /* __FSL_FMAN_DTSEC_H */
94528 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
94529 new file mode 100644
94530 index 00000000..0dda09c3
94531 --- /dev/null
94532 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
94533 @@ -0,0 +1,107 @@
94534 +/*
94535 + * Copyright 2008-2013 Freescale Semiconductor Inc.
94536 + *
94537 + * Redistribution and use in source and binary forms, with or without
94538 + * modification, are permitted provided that the following conditions are met:
94539 + * * Redistributions of source code must retain the above copyright
94540 + * notice, this list of conditions and the following disclaimer.
94541 + * * Redistributions in binary form must reproduce the above copyright
94542 + * notice, this list of conditions and the following disclaimer in the
94543 + * documentation and/or other materials provided with the distribution.
94544 + * * Neither the name of Freescale Semiconductor nor the
94545 + * names of its contributors may be used to endorse or promote products
94546 + * derived from this software without specific prior written permission.
94547 + *
94548 + *
94549 + * ALTERNATIVELY, this software may be distributed under the terms of the
94550 + * GNU General Public License ("GPL") as published by the Free Software
94551 + * Foundation, either version 2 of that License or (at your option) any
94552 + * later version.
94553 + *
94554 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94555 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94556 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94557 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94558 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94559 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94560 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94561 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94562 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94563 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94564 + */
94565 +
94566 +#ifndef __FSL_FMAN_DTSEC_MII_ACC_H
94567 +#define __FSL_FMAN_DTSEC_MII_ACC_H
94568 +
94569 +#include "common/general.h"
94570 +
94571 +
94572 +/* MII Management Configuration Register */
94573 +#define MIIMCFG_RESET_MGMT 0x80000000
94574 +#define MIIMCFG_MGNTCLK_MASK 0x00000007
94575 +#define MIIMCFG_MGNTCLK_SHIFT 0
94576 +
94577 +/* MII Management Command Register */
94578 +#define MIIMCOM_SCAN_CYCLE 0x00000002
94579 +#define MIIMCOM_READ_CYCLE 0x00000001
94580 +
94581 +/* MII Management Address Register */
94582 +#define MIIMADD_PHY_ADDR_SHIFT 8
94583 +#define MIIMADD_PHY_ADDR_MASK 0x00001f00
94584 +
94585 +#define MIIMADD_REG_ADDR_SHIFT 0
94586 +#define MIIMADD_REG_ADDR_MASK 0x0000001f
94587 +
94588 +/* MII Management Indicator Register */
94589 +#define MIIMIND_BUSY 0x00000001
94590 +
94591 +
94592 +/* PHY Control Register */
94593 +#define PHY_CR_PHY_RESET 0x8000
94594 +#define PHY_CR_LOOPBACK 0x4000
94595 +#define PHY_CR_SPEED0 0x2000
94596 +#define PHY_CR_ANE 0x1000
94597 +#define PHY_CR_RESET_AN 0x0200
94598 +#define PHY_CR_FULLDUPLEX 0x0100
94599 +#define PHY_CR_SPEED1 0x0040
94600 +
94601 +#define PHY_TBICON_SRESET 0x8000
94602 +#define PHY_TBICON_SPEED2 0x0020
94603 +#define PHY_TBICON_CLK_SEL 0x0020
94604 +#define PHY_TBIANA_SGMII 0x4001
94605 +#define PHY_TBIANA_1000X 0x01a0
94606 +/* register map */
94607 +
94608 +/* MII Configuration Control Memory Map Registers */
94609 +struct dtsec_mii_reg {
94610 + uint32_t reserved1[72];
94611 + uint32_t miimcfg; /* MII Mgmt:configuration */
94612 + uint32_t miimcom; /* MII Mgmt:command */
94613 + uint32_t miimadd; /* MII Mgmt:address */
94614 + uint32_t miimcon; /* MII Mgmt:control 3 */
94615 + uint32_t miimstat; /* MII Mgmt:status */
94616 + uint32_t miimind; /* MII Mgmt:indicators */
94617 +};
94618 +
94619 +/* dTSEC MII API */
94620 +
94621 +/* functions to access the mii registers for phy configuration.
94622 + * this functionality may not be available for all dtsecs in the system.
94623 + * consult the reference manual for details */
94624 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs);
94625 +/* frequency is in MHz.
94626 + * note that dtsec clock is 1/2 of fman clock */
94627 +void fman_dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq);
94628 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs,
94629 + uint8_t addr,
94630 + uint8_t reg,
94631 + uint16_t data,
94632 + uint16_t dtsec_freq);
94633 +
94634 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs,
94635 + uint8_t addr,
94636 + uint8_t reg,
94637 + uint16_t *data,
94638 + uint16_t dtsec_freq);
94639 +
94640 +#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */
94641 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
94642 new file mode 100644
94643 index 00000000..010e4b70
94644 --- /dev/null
94645 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
94646 @@ -0,0 +1,514 @@
94647 +/*
94648 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94649 + *
94650 + * Redistribution and use in source and binary forms, with or without
94651 + * modification, are permitted provided that the following conditions are met:
94652 + * * Redistributions of source code must retain the above copyright
94653 + * notice, this list of conditions and the following disclaimer.
94654 + * * Redistributions in binary form must reproduce the above copyright
94655 + * notice, this list of conditions and the following disclaimer in the
94656 + * documentation and/or other materials provided with the distribution.
94657 + * * Neither the name of Freescale Semiconductor nor the
94658 + * names of its contributors may be used to endorse or promote products
94659 + * derived from this software without specific prior written permission.
94660 + *
94661 + *
94662 + * ALTERNATIVELY, this software may be distributed under the terms of the
94663 + * GNU General Public License ("GPL") as published by the Free Software
94664 + * Foundation, either version 2 of that License or (at your option) any
94665 + * later version.
94666 + *
94667 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94668 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94669 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94670 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94671 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94672 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94673 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94674 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94675 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94676 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94677 + */
94678 +
94679 +#ifndef __FSL_FMAN_KG_H
94680 +#define __FSL_FMAN_KG_H
94681 +
94682 +#include "common/general.h"
94683 +
94684 +#define FM_KG_NUM_OF_GENERIC_REGS 8 /**< Num of generic KeyGen regs */
94685 +#define FMAN_MAX_NUM_OF_HW_PORTS 64
94686 +/**< Total num of masks allowed on KG extractions */
94687 +#define FM_KG_EXTRACT_MASKS_NUM 4
94688 +#define FM_KG_NUM_CLS_PLAN_ENTR 8 /**< Num of class. plan regs */
94689 +#define FM_KG_CLS_PLAN_GRPS_NUM 32 /**< Max num of class. groups */
94690 +
94691 +struct fman_kg_regs {
94692 + uint32_t fmkg_gcr;
94693 + uint32_t res004;
94694 + uint32_t res008;
94695 + uint32_t fmkg_eer;
94696 + uint32_t fmkg_eeer;
94697 + uint32_t res014;
94698 + uint32_t res018;
94699 + uint32_t fmkg_seer;
94700 + uint32_t fmkg_seeer;
94701 + uint32_t fmkg_gsr;
94702 + uint32_t fmkg_tpc;
94703 + uint32_t fmkg_serc;
94704 + uint32_t res030[4];
94705 + uint32_t fmkg_fdor;
94706 + uint32_t fmkg_gdv0r;
94707 + uint32_t fmkg_gdv1r;
94708 + uint32_t res04c[6];
94709 + uint32_t fmkg_feer;
94710 + uint32_t res068[38];
94711 + uint32_t fmkg_indirect[63];
94712 + uint32_t fmkg_ar;
94713 +};
94714 +
94715 +struct fman_kg_scheme_regs {
94716 + uint32_t kgse_mode; /**< MODE */
94717 + uint32_t kgse_ekfc; /**< Extract Known Fields Command */
94718 + uint32_t kgse_ekdv; /**< Extract Known Default Value */
94719 + uint32_t kgse_bmch; /**< Bit Mask Command High */
94720 + uint32_t kgse_bmcl; /**< Bit Mask Command Low */
94721 + uint32_t kgse_fqb; /**< Frame Queue Base */
94722 + uint32_t kgse_hc; /**< Hash Command */
94723 + uint32_t kgse_ppc; /**< Policer Profile Command */
94724 + uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
94725 + /**< Generic Extract Command */
94726 + uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */
94727 + uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
94728 + uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
94729 + uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
94730 + uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
94731 + uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */
94732 + uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */
94733 +};
94734 +
94735 +struct fman_kg_pe_regs{
94736 + uint32_t fmkg_pe_sp;
94737 + uint32_t fmkg_pe_cpp;
94738 +};
94739 +
94740 +struct fman_kg_cp_regs {
94741 + uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR];
94742 +};
94743 +
94744 +
94745 +#define FM_KG_KGAR_GO 0x80000000
94746 +#define FM_KG_KGAR_READ 0x40000000
94747 +#define FM_KG_KGAR_WRITE 0x00000000
94748 +#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000
94749 +#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000
94750 +
94751 +#define KG_SCH_PP_SHIFT_HIGH 0x80000000
94752 +#define KG_SCH_PP_NO_GEN 0x10000000
94753 +#define KG_SCH_PP_SHIFT_LOW 0x0000F000
94754 +#define KG_SCH_MODE_NIA_PLCR 0x40000000
94755 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94756 +#define KG_SCH_BITMASK_MASK 0x000000FF
94757 +#define KG_SCH_GEN_VALID 0x80000000
94758 +#define KG_SCH_GEN_MASK 0x00FF0000
94759 +#define FM_PCD_KG_KGAR_ERR 0x20000000
94760 +#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000
94761 +#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000
94762 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000
94763 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000
94764 +#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00
94765 +#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000
94766 +#define KG_SCH_HASH_CONFIG_SYM 0x40000000
94767 +
94768 +#define FM_EX_KG_DOUBLE_ECC 0x80000000
94769 +#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000
94770 +
94771 +/* ECC capture register */
94772 +#define KG_FMKG_SERC_CAP 0x80000000
94773 +#define KG_FMKG_SERC_CET 0x40000000
94774 +#define KG_FMKG_SERC_CNT_MSK 0x00FF0000
94775 +#define KG_FMKG_SERC_CNT_SHIFT 16
94776 +#define KG_FMKG_SERC_ADDR_MSK 0x000003FF
94777 +
94778 +/* Masks */
94779 +#define FM_KG_KGGCR_EN 0x80000000
94780 +#define KG_SCH_GEN_VALID 0x80000000
94781 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94782 +#define KG_ERR_TYPE_DOUBLE 0x40000000
94783 +#define KG_ERR_ADDR_MASK 0x00000FFF
94784 +#define KG_SCH_MODE_EN 0x80000000
94785 +
94786 +/* shifts */
94787 +#define FM_KG_KGAR_NUM_SHIFT 16
94788 +#define FM_KG_PE_CPP_MASK_SHIFT 16
94789 +#define FM_KG_KGAR_WSEL_SHIFT 8
94790 +
94791 +#define FM_KG_SCH_GEN_HT_INVALID 0
94792 +
94793 +#define FM_KG_MASK_SEL_GEN_BASE 0x20
94794 +
94795 +#define KG_GET_MASK_SEL_SHIFT(shift, i) \
94796 +switch (i) \
94797 +{ \
94798 + case 0: (shift) = 26; break; \
94799 + case 1: (shift) = 20; break; \
94800 + case 2: (shift) = 10; break; \
94801 + case 3: (shift) = 4; break; \
94802 + default: (shift) = 0; \
94803 +}
94804 +
94805 +#define KG_GET_MASK_OFFSET_SHIFT(shift, i) \
94806 +switch (i) \
94807 +{ \
94808 + case 0: (shift) = 16; break; \
94809 + case 1: (shift) = 0; break; \
94810 + case 2: (shift) = 28; break; \
94811 + case 3: (shift) = 24; break; \
94812 + default: (shift) = 0; \
94813 +}
94814 +
94815 +#define KG_GET_MASK_SHIFT(shift, i) \
94816 +switch (i) \
94817 +{ \
94818 + case 0: shift = 24; break; \
94819 + case 1: shift = 16; break; \
94820 + case 2: shift = 8; break; \
94821 + case 3: shift = 0; break; \
94822 + default: shift = 0; \
94823 +}
94824 +
94825 +/* Port entry CPP register */
94826 +#define FMAN_KG_PE_CPP_MASK_SHIFT 16
94827 +
94828 +/* Scheme registers */
94829 +#define FMAN_KG_SCH_MODE_EN 0x80000000
94830 +#define FMAN_KG_SCH_MODE_NIA_PLCR 0x40000000
94831 +#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT 24
94832 +
94833 +#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT 30
94834 +#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT 28
94835 +#define FMAN_KG_SCH_DEF_ETYPE_SHIFT 26
94836 +#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT 24
94837 +#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT 22
94838 +#define FMAN_KG_SCH_DEF_MPLS_SHIFT 20
94839 +#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT 18
94840 +#define FMAN_KG_SCH_DEF_PTYPE_SHIFT 16
94841 +#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT 14
94842 +#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT 12
94843 +#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT 10
94844 +#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT 8
94845 +#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT 6
94846 +
94847 +#define FMAN_KG_SCH_GEN_VALID 0x80000000
94848 +#define FMAN_KG_SCH_GEN_SIZE_MAX 16
94849 +#define FMAN_KG_SCH_GEN_OR 0x00008000
94850 +
94851 +#define FMAN_KG_SCH_GEN_DEF_SHIFT 29
94852 +#define FMAN_KG_SCH_GEN_SIZE_SHIFT 24
94853 +#define FMAN_KG_SCH_GEN_MASK_SHIFT 16
94854 +#define FMAN_KG_SCH_GEN_HT_SHIFT 8
94855 +
94856 +#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT 24
94857 +#define FMAN_KG_SCH_HASH_HSHIFT_MAX 0x28
94858 +#define FMAN_KG_SCH_HASH_SYM 0x40000000
94859 +#define FMAN_KG_SCH_HASH_NO_FQID_GEN 0x80000000
94860 +
94861 +#define FMAN_KG_SCH_PP_SH_SHIFT 27
94862 +#define FMAN_KG_SCH_PP_SL_SHIFT 12
94863 +#define FMAN_KG_SCH_PP_SH_MASK 0x80000000
94864 +#define FMAN_KG_SCH_PP_SL_MASK 0x0000F000
94865 +#define FMAN_KG_SCH_PP_SHIFT_MAX 0x17
94866 +#define FMAN_KG_SCH_PP_MASK_SHIFT 16
94867 +#define FMAN_KG_SCH_PP_NO_GEN 0x10000000
94868 +
94869 +enum fman_kg_gen_extract_src {
94870 + E_FMAN_KG_GEN_EXTRACT_ETH,
94871 + E_FMAN_KG_GEN_EXTRACT_ETYPE,
94872 + E_FMAN_KG_GEN_EXTRACT_SNAP,
94873 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1,
94874 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N,
94875 + E_FMAN_KG_GEN_EXTRACT_PPPoE,
94876 + E_FMAN_KG_GEN_EXTRACT_MPLS_1,
94877 + E_FMAN_KG_GEN_EXTRACT_MPLS_2,
94878 + E_FMAN_KG_GEN_EXTRACT_MPLS_3,
94879 + E_FMAN_KG_GEN_EXTRACT_MPLS_N,
94880 + E_FMAN_KG_GEN_EXTRACT_IPv4_1,
94881 + E_FMAN_KG_GEN_EXTRACT_IPv6_1,
94882 + E_FMAN_KG_GEN_EXTRACT_IPv4_2,
94883 + E_FMAN_KG_GEN_EXTRACT_IPv6_2,
94884 + E_FMAN_KG_GEN_EXTRACT_MINENCAP,
94885 + E_FMAN_KG_GEN_EXTRACT_IP_PID,
94886 + E_FMAN_KG_GEN_EXTRACT_GRE,
94887 + E_FMAN_KG_GEN_EXTRACT_TCP,
94888 + E_FMAN_KG_GEN_EXTRACT_UDP,
94889 + E_FMAN_KG_GEN_EXTRACT_SCTP,
94890 + E_FMAN_KG_GEN_EXTRACT_DCCP,
94891 + E_FMAN_KG_GEN_EXTRACT_IPSEC_AH,
94892 + E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP,
94893 + E_FMAN_KG_GEN_EXTRACT_SHIM_1,
94894 + E_FMAN_KG_GEN_EXTRACT_SHIM_2,
94895 + E_FMAN_KG_GEN_EXTRACT_FROM_DFLT,
94896 + E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START,
94897 + E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT,
94898 + E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE,
94899 + E_FMAN_KG_GEN_EXTRACT_FROM_FQID
94900 +};
94901 +
94902 +struct fman_kg_ex_ecc_attr
94903 +{
94904 + bool valid;
94905 + bool double_ecc;
94906 + uint16_t addr;
94907 + uint8_t single_ecc_count;
94908 +};
94909 +
94910 +enum fman_kg_def_select
94911 +{
94912 + E_FMAN_KG_DEF_GLOBAL_0,
94913 + E_FMAN_KG_DEF_GLOBAL_1,
94914 + E_FMAN_KG_DEF_SCHEME_0,
94915 + E_FMAN_KG_DEF_SCHEME_1
94916 +};
94917 +
94918 +struct fman_kg_extract_def
94919 +{
94920 + enum fman_kg_def_select mac_addr;
94921 + enum fman_kg_def_select vlan_tci;
94922 + enum fman_kg_def_select etype;
94923 + enum fman_kg_def_select ppp_sid;
94924 + enum fman_kg_def_select ppp_pid;
94925 + enum fman_kg_def_select mpls;
94926 + enum fman_kg_def_select ip_addr;
94927 + enum fman_kg_def_select ptype;
94928 + enum fman_kg_def_select ip_tos_tc;
94929 + enum fman_kg_def_select ipv6_fl;
94930 + enum fman_kg_def_select ipsec_spi;
94931 + enum fman_kg_def_select l4_port;
94932 + enum fman_kg_def_select tcp_flg;
94933 +};
94934 +
94935 +enum fman_kg_gen_extract_type
94936 +{
94937 + E_FMAN_KG_HASH_EXTRACT,
94938 + E_FMAN_KG_OR_EXTRACT
94939 +};
94940 +
94941 +struct fman_kg_gen_extract_params
94942 +{
94943 + /* Hash or Or-ed extract */
94944 + enum fman_kg_gen_extract_type type;
94945 + enum fman_kg_gen_extract_src src;
94946 + bool no_validation;
94947 + /* Extraction offset from the header location specified above */
94948 + uint8_t offset;
94949 + /* Size of extraction for FMAN_KG_HASH_EXTRACT,
94950 + * hash result shift for FMAN_KG_OR_EXTRACT */
94951 + uint8_t extract;
94952 + uint8_t mask;
94953 + /* Default value to use when header specified
94954 + * by fman_kg_gen_extract_src doesn't present */
94955 + enum fman_kg_def_select def_val;
94956 +};
94957 +
94958 +struct fman_kg_extract_mask
94959 +{
94960 + /**< Indication if mask is on known field extraction or
94961 + * on general extraction; TRUE for known field */
94962 + bool is_known;
94963 + /**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and
94964 + * generic register index for generic extracts mask */
94965 + uint32_t field_or_gen_idx;
94966 + /**< Byte offset from start of the extracted data specified
94967 + * by field_or_gen_idx */
94968 + uint8_t offset;
94969 + /**< Byte mask (selected bits will be used) */
94970 + uint8_t mask;
94971 +};
94972 +
94973 +struct fman_kg_extract_params
94974 +{
94975 + /* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */
94976 + uint32_t known_fields;
94977 + struct fman_kg_extract_def known_fields_def;
94978 + /* Number of entries in gen_extract */
94979 + uint8_t gen_extract_num;
94980 + struct fman_kg_gen_extract_params gen_extract[FM_KG_NUM_OF_GENERIC_REGS];
94981 + /* Number of entries in masks */
94982 + uint8_t masks_num;
94983 + struct fman_kg_extract_mask masks[FM_KG_EXTRACT_MASKS_NUM];
94984 + uint32_t def_scheme_0;
94985 + uint32_t def_scheme_1;
94986 +};
94987 +
94988 +struct fman_kg_hash_params
94989 +{
94990 + bool use_hash;
94991 + uint8_t shift_r;
94992 + uint32_t mask; /**< 24-bit mask */
94993 + bool sym; /**< Symmetric hash for src and dest pairs */
94994 +};
94995 +
94996 +struct fman_kg_pp_params
94997 +{
94998 + uint8_t base;
94999 + uint8_t shift;
95000 + uint8_t mask;
95001 + bool bypass_pp_gen;
95002 +};
95003 +
95004 +struct fman_kg_cc_params
95005 +{
95006 + uint8_t base_offset;
95007 + uint32_t qlcv_bits_sel;
95008 +};
95009 +
95010 +enum fman_pcd_engine
95011 +{
95012 + E_FMAN_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/
95013 + E_FMAN_PCD_DONE, /**< No PCD Engine indicated */
95014 + E_FMAN_PCD_KG, /**< Keygen indicated */
95015 + E_FMAN_PCD_CC, /**< Coarse classification indicated */
95016 + E_FMAN_PCD_PLCR, /**< Policer indicated */
95017 + E_FMAN_PCD_PRS /**< Parser indicated */
95018 +};
95019 +
95020 +struct fman_kg_cls_plan_params
95021 +{
95022 + uint8_t entries_mask;
95023 + uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR];
95024 +};
95025 +
95026 +struct fman_kg_scheme_params
95027 +{
95028 + uint32_t match_vector;
95029 + struct fman_kg_extract_params extract_params;
95030 + struct fman_kg_hash_params hash_params;
95031 + uint32_t base_fqid;
95032 + /* What we do w/features supported per FM version ?? */
95033 + bool bypass_fqid_gen;
95034 + struct fman_kg_pp_params policer_params;
95035 + struct fman_kg_cc_params cc_params;
95036 + bool update_counter;
95037 + /**< counter_value: Set scheme counter to the specified value;
95038 + * relevant only when update_counter = TRUE. */
95039 + uint32_t counter_value;
95040 + enum fman_pcd_engine next_engine;
95041 + /**< Next engine action code */
95042 + uint32_t next_engine_action;
95043 +};
95044 +
95045 +
95046 +
95047 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar);
95048 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add);
95049 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp);
95050 +void fman_kg_get_event(struct fman_kg_regs *regs,
95051 + uint32_t *event,
95052 + uint32_t *scheme_idx);
95053 +void fman_kg_init(struct fman_kg_regs *regs,
95054 + uint32_t exceptions,
95055 + uint32_t dflt_nia);
95056 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs);
95057 +void fman_kg_enable(struct fman_kg_regs *regs);
95058 +void fman_kg_disable(struct fman_kg_regs *regs);
95059 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
95060 + uint8_t hwport_id,
95061 + uint32_t bind_cls_plans);
95062 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
95063 + uint8_t grp_mask,
95064 + uint32_t *bind_cls_plans);
95065 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
95066 + uint8_t hwport_id,
95067 + uint32_t schemes);
95068 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
95069 + uint8_t grp_id,
95070 + uint8_t entries_mask,
95071 + uint8_t hwport_id,
95072 + struct fman_kg_cp_regs *cls_plan_regs);
95073 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
95074 + struct fman_kg_cp_regs *cls_plan_regs);
95075 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs);
95076 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
95077 + uint8_t scheme_id,
95078 + uint8_t hwport_id,
95079 + uint32_t counter);
95080 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
95081 + uint8_t scheme_id,
95082 + uint8_t hwport_id,
95083 + uint32_t *counter);
95084 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
95085 + uint8_t scheme_id,
95086 + uint8_t hwport_id);
95087 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
95088 + uint8_t scheme_id,
95089 + uint8_t hwport_id,
95090 + struct fman_kg_scheme_regs *scheme_regs,
95091 + bool update_counter);
95092 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
95093 + struct fman_kg_scheme_regs *scheme_regs);
95094 +void fman_kg_get_capture(struct fman_kg_regs *regs,
95095 + struct fman_kg_ex_ecc_attr *ecc_attr,
95096 + bool clear);
95097 +void fman_kg_get_exception(struct fman_kg_regs *regs,
95098 + uint32_t *events,
95099 + uint32_t *scheme_ids,
95100 + bool clear);
95101 +void fman_kg_set_exception(struct fman_kg_regs *regs,
95102 + uint32_t exception,
95103 + bool enable);
95104 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
95105 + uint8_t def_id,
95106 + uint32_t val);
95107 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset);
95108 +
95109 +
95110 +
95111 +/**************************************************************************//**
95112 + @Description NIA Description
95113 +*//***************************************************************************/
95114 +#define KG_NIA_ORDER_RESTOR 0x00800000
95115 +#define KG_NIA_ENG_FM_CTL 0x00000000
95116 +#define KG_NIA_ENG_PRS 0x00440000
95117 +#define KG_NIA_ENG_KG 0x00480000
95118 +#define KG_NIA_ENG_PLCR 0x004C0000
95119 +#define KG_NIA_ENG_BMI 0x00500000
95120 +#define KG_NIA_ENG_QMI_ENQ 0x00540000
95121 +#define KG_NIA_ENG_QMI_DEQ 0x00580000
95122 +#define KG_NIA_ENG_MASK 0x007C0000
95123 +
95124 +#define KG_NIA_AC_MASK 0x0003FFFF
95125 +
95126 +#define KG_NIA_INVALID 0xFFFFFFFF
95127 +
95128 +static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine,
95129 + uint32_t next_engine_action)
95130 +{
95131 + uint32_t nia;
95132 +
95133 + if (next_engine_action & ~KG_NIA_AC_MASK)
95134 + return KG_NIA_INVALID;
95135 +
95136 + switch (next_engine) {
95137 + case E_FMAN_PCD_DONE:
95138 + nia = KG_NIA_ENG_BMI | next_engine_action;
95139 + break;
95140 +
95141 + case E_FMAN_PCD_KG:
95142 + nia = KG_NIA_ENG_KG | next_engine_action;
95143 + break;
95144 +
95145 + case E_FMAN_PCD_CC:
95146 + nia = KG_NIA_ENG_FM_CTL | next_engine_action;
95147 + break;
95148 +
95149 + case E_FMAN_PCD_PLCR:
95150 + nia = KG_NIA_ENG_PLCR | next_engine_action;
95151 + break;
95152 +
95153 + default:
95154 + nia = KG_NIA_INVALID;
95155 + }
95156 +
95157 + return nia;
95158 +}
95159 +
95160 +#endif /* __FSL_FMAN_KG_H */
95161 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
95162 new file mode 100644
95163 index 00000000..058da159
95164 --- /dev/null
95165 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
95166 @@ -0,0 +1,434 @@
95167 +/*
95168 + * Copyright 2008-2012 Freescale Semiconductor Inc.
95169 + *
95170 + * Redistribution and use in source and binary forms, with or without
95171 + * modification, are permitted provided that the following conditions are met:
95172 + * * Redistributions of source code must retain the above copyright
95173 + * notice, this list of conditions and the following disclaimer.
95174 + * * Redistributions in binary form must reproduce the above copyright
95175 + * notice, this list of conditions and the following disclaimer in the
95176 + * documentation and/or other materials provided with the distribution.
95177 + * * Neither the name of Freescale Semiconductor nor the
95178 + * names of its contributors may be used to endorse or promote products
95179 + * derived from this software without specific prior written permission.
95180 + *
95181 + *
95182 + * ALTERNATIVELY, this software may be distributed under the terms of the
95183 + * GNU General Public License ("GPL") as published by the Free Software
95184 + * Foundation, either version 2 of that License or (at your option) any
95185 + * later version.
95186 + *
95187 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95188 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95189 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95190 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95191 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95192 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95193 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95194 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95195 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95196 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95197 + */
95198 +
95199 +
95200 +#ifndef __FSL_FMAN_MEMAC_H
95201 +#define __FSL_FMAN_MEMAC_H
95202 +
95203 +#include "common/general.h"
95204 +#include "fsl_enet.h"
95205 +
95206 +
95207 +#define MEMAC_NUM_OF_PADDRS 7 /* Num of additional exact match MAC adr regs */
95208 +
95209 +/* Control and Configuration Register (COMMAND_CONFIG) */
95210 +#define CMD_CFG_MG 0x80000000 /* 00 Magic Packet detection */
95211 +#define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */
95212 +#define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */
95213 +#define CMD_CFG_SFD_ANY 0x00200000 /* 10 Disable SFD check */
95214 +#define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */
95215 +#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */
95216 +#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 Force idle generation */
95217 +#define CMD_CFG_CNT_FRM_EN 0x00002000 /* 18 Control frame rx enable */
95218 +#define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */
95219 +#define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */
95220 +#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 XGMII/GMII loopback enable */
95221 +#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 Tx source MAC addr insertion */
95222 +#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */
95223 +#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 Terminate/frwd Pause frames */
95224 +#define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */
95225 +#define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */
95226 +#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */
95227 +#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN mode enable */
95228 +#define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */
95229 +#define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */
95230 +
95231 +/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */
95232 +#define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000
95233 +#define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF
95234 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000
95235 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000
95236 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G 0x00360000
95237 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G 0x00040000
95238 +#define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019
95239 +#define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020
95240 +#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060
95241 +
95242 +#define GET_TX_EMPTY_DEFAULT_VALUE(_val) \
95243 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
95244 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
95245 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) : \
95246 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));
95247 +
95248 +#define GET_TX_EMPTY_PFC_VALUE(_val) \
95249 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
95250 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
95251 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G) : \
95252 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G));
95253 +
95254 +/* Interface Mode Register (IF_MODE) */
95255 +#define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */
95256 +#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */
95257 +#define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */
95258 +#define IF_MODE_RGMII 0x00000004
95259 +#define IF_MODE_RGMII_AUTO 0x00008000
95260 +#define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */
95261 +#define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */
95262 +#define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */
95263 +#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */
95264 +#define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */
95265 +#define IF_MODE_HD 0x00000040 /* Half duplex operation */
95266 +
95267 +/* Hash table Control Register (HASHTABLE_CTRL) */
95268 +#define HASH_CTRL_MCAST_SHIFT 26
95269 +#define HASH_CTRL_MCAST_EN 0x00000100 /* 23 Mcast frame rx for hash */
95270 +#define HASH_CTRL_ADDR_MASK 0x0000003F /* 26-31 Hash table address code */
95271 +
95272 +#define GROUP_ADDRESS 0x0000010000000000LL /* MAC mcast indication */
95273 +#define HASH_TABLE_SIZE 64 /* Hash tbl size */
95274 +
95275 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
95276 +#define MEMAC_TX_IPG_LENGTH_MASK 0x0000003F
95277 +
95278 +/* Statistics Configuration Register (STATN_CONFIG) */
95279 +#define STATS_CFG_CLR 0x00000004 /* 29 Reset all counters */
95280 +#define STATS_CFG_CLR_ON_RD 0x00000002 /* 30 Clear on read */
95281 +#define STATS_CFG_SATURATE 0x00000001 /* 31 Saturate at the maximum val */
95282 +
95283 +/* Interrupt Mask Register (IMASK) */
95284 +#define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */
95285 +#define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */
95286 +#define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */
95287 +#define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */
95288 +
95289 +#define MEMAC_ALL_ERRS_IMASK \
95290 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | \
95291 + MEMAC_IMASK_TECC_ER | \
95292 + MEMAC_IMASK_RECC_ER | \
95293 + MEMAC_IMASK_MGI))
95294 +
95295 +#define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */
95296 +#define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */
95297 +#define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */
95298 +#define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */
95299 +#define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error */
95300 +#define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */
95301 +#define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */
95302 +#define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */
95303 +#define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */
95304 +#define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */
95305 +#define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */
95306 +#define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */
95307 +#define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */
95308 +#define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */
95309 +#define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */
95310 +#define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */
95311 +#define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */
95312 +
95313 +enum memac_counters {
95314 + E_MEMAC_COUNTER_R64,
95315 + E_MEMAC_COUNTER_T64,
95316 + E_MEMAC_COUNTER_R127,
95317 + E_MEMAC_COUNTER_T127,
95318 + E_MEMAC_COUNTER_R255,
95319 + E_MEMAC_COUNTER_T255,
95320 + E_MEMAC_COUNTER_R511,
95321 + E_MEMAC_COUNTER_T511,
95322 + E_MEMAC_COUNTER_R1023,
95323 + E_MEMAC_COUNTER_T1023,
95324 + E_MEMAC_COUNTER_R1518,
95325 + E_MEMAC_COUNTER_T1518,
95326 + E_MEMAC_COUNTER_R1519X,
95327 + E_MEMAC_COUNTER_T1519X,
95328 + E_MEMAC_COUNTER_RFRG,
95329 + E_MEMAC_COUNTER_RJBR,
95330 + E_MEMAC_COUNTER_RDRP,
95331 + E_MEMAC_COUNTER_RALN,
95332 + E_MEMAC_COUNTER_TUND,
95333 + E_MEMAC_COUNTER_ROVR,
95334 + E_MEMAC_COUNTER_RXPF,
95335 + E_MEMAC_COUNTER_TXPF,
95336 + E_MEMAC_COUNTER_ROCT,
95337 + E_MEMAC_COUNTER_RMCA,
95338 + E_MEMAC_COUNTER_RBCA,
95339 + E_MEMAC_COUNTER_RPKT,
95340 + E_MEMAC_COUNTER_RUCA,
95341 + E_MEMAC_COUNTER_RERR,
95342 + E_MEMAC_COUNTER_TOCT,
95343 + E_MEMAC_COUNTER_TMCA,
95344 + E_MEMAC_COUNTER_TBCA,
95345 + E_MEMAC_COUNTER_TUCA,
95346 + E_MEMAC_COUNTER_TERR
95347 +};
95348 +
95349 +#define DEFAULT_PAUSE_QUANTA 0xf000
95350 +#define DEFAULT_FRAME_LENGTH 0x600
95351 +#define DEFAULT_TX_IPG_LENGTH 12
95352 +
95353 +/*
95354 + * memory map
95355 + */
95356 +
95357 +struct mac_addr {
95358 + uint32_t mac_addr_l; /* Lower 32 bits of 48-bit MAC address */
95359 + uint32_t mac_addr_u; /* Upper 16 bits of 48-bit MAC address */
95360 +};
95361 +
95362 +struct memac_regs {
95363 + /* General Control and Status */
95364 + uint32_t res0000[2];
95365 + uint32_t command_config; /* 0x008 Ctrl and cfg */
95366 + struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */
95367 + uint32_t maxfrm; /* 0x014 Max frame length */
95368 + uint32_t res0018[1];
95369 + uint32_t rx_fifo_sections; /* Receive FIFO configuration reg */
95370 + uint32_t tx_fifo_sections; /* Transmit FIFO configuration reg */
95371 + uint32_t res0024[2];
95372 + uint32_t hashtable_ctrl; /* 0x02C Hash table control */
95373 + uint32_t res0030[4];
95374 + uint32_t ievent; /* 0x040 Interrupt event */
95375 + uint32_t tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */
95376 + uint32_t res0048;
95377 + uint32_t imask; /* 0x04C Interrupt mask */
95378 + uint32_t res0050;
95379 + uint32_t pause_quanta[4]; /* 0x054 Pause quanta */
95380 + uint32_t pause_thresh[4]; /* 0x064 Pause quanta threshold */
95381 + uint32_t rx_pause_status; /* 0x074 Receive pause status */
95382 + uint32_t res0078[2];
95383 + struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS]; /* 0x80-0x0B4 mac padr */
95384 + uint32_t lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */
95385 + uint32_t sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */
95386 + uint32_t res00c0[8];
95387 + uint32_t statn_config; /* 0x0E0 Statistics configuration */
95388 + uint32_t res00e4[7];
95389 + /* Rx Statistics Counter */
95390 + uint32_t reoct_l;
95391 + uint32_t reoct_u;
95392 + uint32_t roct_l;
95393 + uint32_t roct_u;
95394 + uint32_t raln_l;
95395 + uint32_t raln_u;
95396 + uint32_t rxpf_l;
95397 + uint32_t rxpf_u;
95398 + uint32_t rfrm_l;
95399 + uint32_t rfrm_u;
95400 + uint32_t rfcs_l;
95401 + uint32_t rfcs_u;
95402 + uint32_t rvlan_l;
95403 + uint32_t rvlan_u;
95404 + uint32_t rerr_l;
95405 + uint32_t rerr_u;
95406 + uint32_t ruca_l;
95407 + uint32_t ruca_u;
95408 + uint32_t rmca_l;
95409 + uint32_t rmca_u;
95410 + uint32_t rbca_l;
95411 + uint32_t rbca_u;
95412 + uint32_t rdrp_l;
95413 + uint32_t rdrp_u;
95414 + uint32_t rpkt_l;
95415 + uint32_t rpkt_u;
95416 + uint32_t rund_l;
95417 + uint32_t rund_u;
95418 + uint32_t r64_l;
95419 + uint32_t r64_u;
95420 + uint32_t r127_l;
95421 + uint32_t r127_u;
95422 + uint32_t r255_l;
95423 + uint32_t r255_u;
95424 + uint32_t r511_l;
95425 + uint32_t r511_u;
95426 + uint32_t r1023_l;
95427 + uint32_t r1023_u;
95428 + uint32_t r1518_l;
95429 + uint32_t r1518_u;
95430 + uint32_t r1519x_l;
95431 + uint32_t r1519x_u;
95432 + uint32_t rovr_l;
95433 + uint32_t rovr_u;
95434 + uint32_t rjbr_l;
95435 + uint32_t rjbr_u;
95436 + uint32_t rfrg_l;
95437 + uint32_t rfrg_u;
95438 + uint32_t rcnp_l;
95439 + uint32_t rcnp_u;
95440 + uint32_t rdrntp_l;
95441 + uint32_t rdrntp_u;
95442 + uint32_t res01d0[12];
95443 + /* Tx Statistics Counter */
95444 + uint32_t teoct_l;
95445 + uint32_t teoct_u;
95446 + uint32_t toct_l;
95447 + uint32_t toct_u;
95448 + uint32_t res0210[2];
95449 + uint32_t txpf_l;
95450 + uint32_t txpf_u;
95451 + uint32_t tfrm_l;
95452 + uint32_t tfrm_u;
95453 + uint32_t tfcs_l;
95454 + uint32_t tfcs_u;
95455 + uint32_t tvlan_l;
95456 + uint32_t tvlan_u;
95457 + uint32_t terr_l;
95458 + uint32_t terr_u;
95459 + uint32_t tuca_l;
95460 + uint32_t tuca_u;
95461 + uint32_t tmca_l;
95462 + uint32_t tmca_u;
95463 + uint32_t tbca_l;
95464 + uint32_t tbca_u;
95465 + uint32_t res0258[2];
95466 + uint32_t tpkt_l;
95467 + uint32_t tpkt_u;
95468 + uint32_t tund_l;
95469 + uint32_t tund_u;
95470 + uint32_t t64_l;
95471 + uint32_t t64_u;
95472 + uint32_t t127_l;
95473 + uint32_t t127_u;
95474 + uint32_t t255_l;
95475 + uint32_t t255_u;
95476 + uint32_t t511_l;
95477 + uint32_t t511_u;
95478 + uint32_t t1023_l;
95479 + uint32_t t1023_u;
95480 + uint32_t t1518_l;
95481 + uint32_t t1518_u;
95482 + uint32_t t1519x_l;
95483 + uint32_t t1519x_u;
95484 + uint32_t res02a8[6];
95485 + uint32_t tcnp_l;
95486 + uint32_t tcnp_u;
95487 + uint32_t res02c8[14];
95488 + /* Line Interface Control */
95489 + uint32_t if_mode; /* 0x300 Interface Mode Control */
95490 + uint32_t if_status; /* 0x304 Interface Status */
95491 + uint32_t res0308[14];
95492 + /* HiGig/2 */
95493 + uint32_t hg_config; /* 0x340 Control and cfg */
95494 + uint32_t res0344[3];
95495 + uint32_t hg_pause_quanta; /* 0x350 Pause quanta */
95496 + uint32_t res0354[3];
95497 + uint32_t hg_pause_thresh; /* 0x360 Pause quanta threshold */
95498 + uint32_t res0364[3];
95499 + uint32_t hgrx_pause_status; /* 0x370 Receive pause status */
95500 + uint32_t hg_fifos_status; /* 0x374 fifos status */
95501 + uint32_t rhm; /* 0x378 rx messages counter */
95502 + uint32_t thm; /* 0x37C tx messages counter */
95503 +};
95504 +
95505 +struct memac_cfg {
95506 + bool reset_on_init;
95507 + bool rx_error_discard;
95508 + bool pause_ignore;
95509 + bool pause_forward_enable;
95510 + bool no_length_check_enable;
95511 + bool cmd_frame_enable;
95512 + bool send_idle_enable;
95513 + bool wan_mode_enable;
95514 + bool promiscuous_mode_enable;
95515 + bool tx_addr_ins_enable;
95516 + bool loopback_enable;
95517 + bool lgth_check_nostdr;
95518 + bool time_stamp_enable;
95519 + bool pad_enable;
95520 + bool phy_tx_ena_on;
95521 + bool rx_sfd_any;
95522 + bool rx_pbl_fwd;
95523 + bool tx_pbl_fwd;
95524 + bool debug_mode;
95525 + bool wake_on_lan;
95526 + uint16_t max_frame_length;
95527 + uint16_t pause_quanta;
95528 + uint32_t tx_ipg_length;
95529 +};
95530 +
95531 +
95532 +/**
95533 + * fman_memac_defconfig() - Get default MEMAC configuration
95534 + * @cfg: pointer to configuration structure.
95535 + *
95536 + * Call this function to obtain a default set of configuration values for
95537 + * initializing MEMAC. The user can overwrite any of the values before calling
95538 + * fman_memac_init(), if specific configuration needs to be applied.
95539 + */
95540 +void fman_memac_defconfig(struct memac_cfg *cfg);
95541 +
95542 +int fman_memac_init(struct memac_regs *regs,
95543 + struct memac_cfg *cfg,
95544 + enum enet_interface enet_interface,
95545 + enum enet_speed enet_speed,
95546 + bool slow_10g_if,
95547 + uint32_t exceptions);
95548 +
95549 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
95550 +
95551 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
95552 +
95553 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val);
95554 +
95555 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
95556 + uint8_t *adr,
95557 + uint8_t paddr_num);
95558 +
95559 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
95560 + uint8_t paddr_num);
95561 +
95562 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
95563 + enum memac_counters reg_name);
95564 +
95565 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
95566 + uint8_t priority, uint16_t pauseTime, uint16_t threshTime);
95567 +
95568 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs);
95569 +
95570 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val,
95571 + bool enable);
95572 +
95573 +void fman_memac_reset_stat(struct memac_regs *regs);
95574 +
95575 +void fman_memac_reset(struct memac_regs *regs);
95576 +
95577 +void fman_memac_reset_filter_table(struct memac_regs *regs);
95578 +
95579 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc);
95580 +
95581 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val);
95582 +
95583 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,
95584 + bool enable);
95585 +
95586 +void fman_memac_set_wol(struct memac_regs *regs, bool enable);
95587 +
95588 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask);
95589 +
95590 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask);
95591 +
95592 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs);
95593 +
95594 +void fman_memac_adjust_link(struct memac_regs *regs,
95595 + enum enet_interface iface_mode,
95596 + enum enet_speed speed, bool full_dx);
95597 +
95598 +
95599 +
95600 +#endif /*__FSL_FMAN_MEMAC_H*/
95601 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
95602 new file mode 100755
95603 index 00000000..b4304450
95604 --- /dev/null
95605 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
95606 @@ -0,0 +1,78 @@
95607 +/*
95608 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95609 + *
95610 + * Redistribution and use in source and binary forms, with or without
95611 + * modification, are permitted provided that the following conditions are met:
95612 + * * Redistributions of source code must retain the above copyright
95613 + * notice, this list of conditions and the following disclaimer.
95614 + * * Redistributions in binary form must reproduce the above copyright
95615 + * notice, this list of conditions and the following disclaimer in the
95616 + * documentation and/or other materials provided with the distribution.
95617 + * * Neither the name of Freescale Semiconductor nor the
95618 + * names of its contributors may be used to endorse or promote products
95619 + * derived from this software without specific prior written permission.
95620 + *
95621 + *
95622 + * ALTERNATIVELY, this software may be distributed under the terms of the
95623 + * GNU General Public License ("GPL") as published by the Free Software
95624 + * Foundation, either version 2 of that License or (at your option) any
95625 + * later version.
95626 + *
95627 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95628 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95629 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95630 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95631 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95632 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95633 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95634 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95635 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95636 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95637 + */
95638 +
95639 +#ifndef __FSL_FMAN_MEMAC_MII_ACC_H
95640 +#define __FSL_FMAN_MEMAC_MII_ACC_H
95641 +
95642 +#include "common/general.h"
95643 +#include "fsl_enet.h"
95644 +/* MII Management Registers */
95645 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
95646 +#define MDIO_CFG_CLK_DIV_SHIFT 7
95647 +#define MDIO_CFG_HOLD_MASK 0x0000001c
95648 +#define MDIO_CFG_ENC45 0x00000040
95649 +#define MDIO_CFG_READ_ERR 0x00000002
95650 +#define MDIO_CFG_BSY 0x00000001
95651 +
95652 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
95653 +#define MDIO_CTL_READ 0x00008000
95654 +
95655 +#define MDIO_DATA_BSY 0x80000000
95656 +
95657 +/*MEMAC Internal PHY Registers - SGMII */
95658 +#define PHY_SGMII_CR_PHY_RESET 0x8000
95659 +#define PHY_SGMII_CR_RESET_AN 0x0200
95660 +#define PHY_SGMII_CR_DEF_VAL 0x1140
95661 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
95662 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
95663 +#define PHY_SGMII_IF_MODE_AN 0x0002
95664 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
95665 +#define PHY_SGMII_IF_MODE_1000X 0x0000
95666 +
95667 +/*----------------------------------------------------*/
95668 +/* MII Configuration Control Memory Map Registers */
95669 +/*----------------------------------------------------*/
95670 +struct memac_mii_access_mem_map {
95671 + uint32_t mdio_cfg; /* 0x030 */
95672 + uint32_t mdio_ctrl; /* 0x034 */
95673 + uint32_t mdio_data; /* 0x038 */
95674 + uint32_t mdio_addr; /* 0x03c */
95675 +};
95676 +
95677 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95678 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
95679 + enum enet_speed enet_speed);
95680 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95681 + uint8_t phy_addr, uint8_t reg, uint16_t data,
95682 + enum enet_speed enet_speed);
95683 +
95684 +#endif /* __MAC_API_MEMAC_MII_ACC_H */
95685 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
95686 new file mode 100755
95687 index 00000000..080a23e9
95688 --- /dev/null
95689 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
95690 @@ -0,0 +1,593 @@
95691 +/*
95692 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95693 + *
95694 + * Redistribution and use in source and binary forms, with or without
95695 + * modification, are permitted provided that the following conditions are met:
95696 + * * Redistributions of source code must retain the above copyright
95697 + * notice, this list of conditions and the following disclaimer.
95698 + * * Redistributions in binary form must reproduce the above copyright
95699 + * notice, this list of conditions and the following disclaimer in the
95700 + * documentation and/or other materials provided with the distribution.
95701 + * * Neither the name of Freescale Semiconductor nor the
95702 + * names of its contributors may be used to endorse or promote products
95703 + * derived from this software without specific prior written permission.
95704 + *
95705 + *
95706 + * ALTERNATIVELY, this software may be distributed under the terms of the
95707 + * GNU General Public License ("GPL") as published by the Free Software
95708 + * Foundation, either version 2 of that License or (at your option) any
95709 + * later version.
95710 + *
95711 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95712 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95713 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95714 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95715 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95716 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95717 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95718 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95719 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95720 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95721 + */
95722 +
95723 +#ifndef __FSL_FMAN_PORT_H
95724 +#define __FSL_FMAN_PORT_H
95725 +
95726 +#include "fsl_fman_sp.h"
95727 +
95728 +/** @Collection Registers bit fields */
95729 +
95730 +/** @Description BMI defines */
95731 +#define BMI_EBD_EN 0x80000000
95732 +
95733 +#define BMI_PORT_CFG_EN 0x80000000
95734 +#define BMI_PORT_CFG_FDOVR 0x02000000
95735 +#define BMI_PORT_CFG_IM 0x01000000
95736 +
95737 +#define BMI_PORT_STATUS_BSY 0x80000000
95738 +
95739 +#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT
95740 +#define BMI_DMA_ATTR_IC_STASH_ON 0x10000000
95741 +#define BMI_DMA_ATTR_HDR_STASH_ON 0x04000000
95742 +#define BMI_DMA_ATTR_SG_STASH_ON 0x01000000
95743 +#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
95744 +
95745 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
95746 +#define BMI_RX_FIFO_THRESHOLD_ETHE 0x80000000
95747 +
95748 +#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24
95749 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
95750 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
95751 +
95752 +#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT
95753 +#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT
95754 +
95755 +#define BMI_INT_BUF_MARG_SHIFT 28
95756 +#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT
95757 +
95758 +#define BMI_CMD_MR_LEAC 0x00200000
95759 +#define BMI_CMD_MR_SLEAC 0x00100000
95760 +#define BMI_CMD_MR_MA 0x00080000
95761 +#define BMI_CMD_MR_DEAS 0x00040000
95762 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
95763 + BMI_CMD_MR_SLEAC | \
95764 + BMI_CMD_MR_MA | \
95765 + BMI_CMD_MR_DEAS)
95766 +#define BMI_CMD_TX_MR_DEF 0
95767 +#define BMI_CMD_OP_MR_DEF (BMI_CMD_MR_DEAS | \
95768 + BMI_CMD_MR_MA)
95769 +
95770 +#define BMI_CMD_ATTR_ORDER 0x80000000
95771 +#define BMI_CMD_ATTR_SYNC 0x02000000
95772 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
95773 +
95774 +#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12
95775 +#define BMI_NEXT_ENG_FD_BITS_SHIFT 24
95776 +#define BMI_FRAME_END_CS_IGNORE_SHIFT 24
95777 +
95778 +#define BMI_COUNTERS_EN 0x80000000
95779 +
95780 +#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID
95781 +#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER
95782 +#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP
95783 +#define BMI_EXT_BUF_POOL_ID_SHIFT 16
95784 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
95785 +#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16
95786 +
95787 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
95788 +#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12
95789 +
95790 +#define MAX_PERFORMANCE_TASK_COMP 64
95791 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
95792 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
95793 +#define MAX_PERFORMANCE_DMA_COMP 16
95794 +#define MAX_PERFORMANCE_FIFO_COMP 1024
95795 +
95796 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
95797 +#define BMI_PERFORMANCE_QUEUE_COMP_SHIFT 16
95798 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
95799 +
95800 +#define BMI_RATE_LIMIT_GRAN_TX 16000 /* In Kbps */
95801 +#define BMI_RATE_LIMIT_GRAN_OP 10000 /* In frames */
95802 +#define BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS 1024
95803 +#define BMI_RATE_LIMIT_MAX_BURST_SIZE 1024 /* In KBytes */
95804 +#define BMI_RATE_LIMIT_MAX_BURST_SHIFT 16
95805 +#define BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN 0x80000000
95806 +#define BMI_RATE_LIMIT_SCALE_TSBS_SHIFT 16
95807 +#define BMI_RATE_LIMIT_SCALE_EN 0x80000000
95808 +#define BMI_SG_DISABLE FMAN_SP_SG_DISABLE
95809 +
95810 +/** @Description QMI defines */
95811 +#define QMI_PORT_CFG_EN 0x80000000
95812 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
95813 +
95814 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
95815 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
95816 +
95817 +#define QMI_DEQ_CFG_PRI 0x80000000
95818 +#define QMI_DEQ_CFG_TYPE1 0x10000000
95819 +#define QMI_DEQ_CFG_TYPE2 0x20000000
95820 +#define QMI_DEQ_CFG_TYPE3 0x30000000
95821 +#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x01000000
95822 +#define QMI_DEQ_CFG_PREFETCH_FULL 0x03000000
95823 +#define QMI_DEQ_CFG_SP_MASK 0xf
95824 +#define QMI_DEQ_CFG_SP_SHIFT 20
95825 +
95826 +
95827 +/** @Description General port defines */
95828 +#define FMAN_PORT_EXT_POOLS_NUM(fm_rev_maj) \
95829 + (((fm_rev_maj) == 4) ? 4 : 8)
95830 +#define FMAN_PORT_MAX_EXT_POOLS_NUM 8
95831 +#define FMAN_PORT_OBS_EXT_POOLS_NUM 2
95832 +#define FMAN_PORT_CG_MAP_NUM 8
95833 +#define FMAN_PORT_PRS_RESULT_WORDS_NUM 8
95834 +#define FMAN_PORT_BMI_FIFO_UNITS 0x100
95835 +#define FMAN_PORT_IC_OFFSET_UNITS 0x10
95836 +
95837 +
95838 +/** @Collection FM Port Register Map */
95839 +
95840 +/** @Description BMI Rx port register map */
95841 +struct fman_port_rx_bmi_regs {
95842 + uint32_t fmbm_rcfg; /**< Rx Configuration */
95843 + uint32_t fmbm_rst; /**< Rx Status */
95844 + uint32_t fmbm_rda; /**< Rx DMA attributes*/
95845 + uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
95846 + uint32_t fmbm_rfed; /**< Rx Frame End Data*/
95847 + uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
95848 + uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
95849 + uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
95850 + uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
95851 + uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
95852 + uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
95853 + uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
95854 + uint32_t fmbm_rpp; /**< Rx Policer Profile */
95855 + uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
95856 + uint32_t fmbm_reth; /**< Rx Excessive Threshold */
95857 + uint32_t reserved003c[1]; /**< (0x03C 0x03F) */
95858 + uint32_t fmbm_rprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95859 + /**< Rx Parse Results Array Init*/
95860 + uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
95861 + uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
95862 + uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
95863 + uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
95864 + uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
95865 + uint32_t reserved0074[0x2]; /**< (0x074-0x07C) */
95866 + uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
95867 + uint32_t reserved0080[0x20];/**< (0x080 0x0FF) */
95868 + uint32_t fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];
95869 + /**< Buffer Manager pool Information-*/
95870 + uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];
95871 + /**< Allocate Counter-*/
95872 + uint32_t reserved0130[8];
95873 + /**< 0x130/0x140 - 0x15F reserved -*/
95874 + uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM];
95875 + /**< Congestion Group Map*/
95876 + uint32_t fmbm_mpd; /**< BM Pool Depletion */
95877 + uint32_t reserved0184[0x1F]; /**< (0x184 0x1FF) */
95878 + uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
95879 + uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
95880 + uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
95881 + uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
95882 + uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
95883 + uint32_t fmbm_rfdc; /**< Rx Frame Discard Counter*/
95884 + uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
95885 + uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard nntr*/
95886 + uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/
95887 + uint32_t reserved0224[0x17]; /**< (0x224 0x27F) */
95888 + uint32_t fmbm_rpc; /**< Rx Performance Counters*/
95889 + uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
95890 + uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
95891 + uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
95892 + uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization cntr*/
95893 + uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
95894 + uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
95895 + uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
95896 + uint32_t reserved02a0[0x18]; /**< (0x2A0 0x2FF) */
95897 + uint32_t fmbm_rdbg; /**< Rx Debug-*/
95898 +};
95899 +
95900 +/** @Description BMI Tx port register map */
95901 +struct fman_port_tx_bmi_regs {
95902 + uint32_t fmbm_tcfg; /**< Tx Configuration */
95903 + uint32_t fmbm_tst; /**< Tx Status */
95904 + uint32_t fmbm_tda; /**< Tx DMA attributes */
95905 + uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
95906 + uint32_t fmbm_tfed; /**< Tx Frame End Data */
95907 + uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
95908 + uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
95909 + uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
95910 + uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
95911 + uint32_t fmbm_tefqid; /**< Tx Frame Error Queue ID */
95912 + uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
95913 + uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
95914 + uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
95915 + uint32_t reserved0034[0x0e]; /**< (0x034-0x6c) */
95916 + uint32_t fmbm_tccb; /**< Tx Coarse Classification base */
95917 + uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
95918 + uint32_t fmbm_tpfcm[0x02]; /**< Tx Priority based Flow Control (PFC) Mapping */
95919 + uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
95920 + uint32_t reserved0080[0x60]; /**< (0x080-0x200) */
95921 + uint32_t fmbm_tstc; /**< Tx Statistics Counters */
95922 + uint32_t fmbm_tfrc; /**< Tx Frame Counter */
95923 + uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
95924 + uint32_t fmbm_tfledc; /**< Tx Frame len error discard cntr */
95925 + uint32_t fmbm_tfufdc; /**< Tx Frame unsprt frmt discard cntr*/
95926 + uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
95927 + uint32_t reserved0218[0x1A]; /**< (0x218-0x280) */
95928 + uint32_t fmbm_tpc; /**< Tx Performance Counters*/
95929 + uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
95930 + uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
95931 + uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
95932 + uint32_t fmbm_ttcquc; /**< Tx Transmit conf Q util Counter*/
95933 + uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
95934 + uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
95935 +};
95936 +
95937 +/** @Description BMI O/H port register map */
95938 +struct fman_port_oh_bmi_regs {
95939 + uint32_t fmbm_ocfg; /**< O/H Configuration */
95940 + uint32_t fmbm_ost; /**< O/H Status */
95941 + uint32_t fmbm_oda; /**< O/H DMA attributes */
95942 + uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
95943 + uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
95944 + uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
95945 + uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
95946 + uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
95947 + uint32_t fmbm_opso; /**< O/H Parse Start Offset */
95948 + uint32_t fmbm_opp; /**< O/H Policer Profile */
95949 + uint32_t fmbm_occb; /**< O/H Coarse Classification base */
95950 + uint32_t fmbm_oim; /**< O/H Internal margins*/
95951 + uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
95952 + uint32_t fmbm_ofed; /**< O/H Frame End Data*/
95953 + uint32_t reserved0030[2]; /**< (0x038 - 0x03F) */
95954 + uint32_t fmbm_oprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95955 + /**< O/H Parse Results Array Initialization */
95956 + uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
95957 + uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
95958 + uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
95959 + uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
95960 + uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
95961 + uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
95962 + uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
95963 + uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
95964 + uint32_t reserved0080[0x20]; /**< 0x080 - 0x0FF Reserved */
95965 + uint32_t fmbm_oebmpi[2]; /**< Buf Mngr Observed Pool Info */
95966 + uint32_t reserved0108[0x16]; /**< 0x108 - 0x15F Reserved */
95967 + uint32_t fmbm_ocgm[FMAN_PORT_CG_MAP_NUM]; /**< Observed Congestion Group Map */
95968 + uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
95969 + uint32_t reserved0184[0x1F]; /**< 0x184 - 0x1FF Reserved */
95970 + uint32_t fmbm_ostc; /**< O/H Statistics Counters */
95971 + uint32_t fmbm_ofrc; /**< O/H Frame Counter */
95972 + uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
95973 + uint32_t fmbm_ofledc; /**< O/H Frames Len Err Discard Cntr */
95974 + uint32_t fmbm_ofufdc; /**< O/H Frames Unsprtd Discard Cutr */
95975 + uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
95976 + uint32_t fmbm_ofwdc; /**< Rx Frames WRED Discard Counter */
95977 + uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Cntr */
95978 + uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
95979 + uint32_t reserved0218[0x17]; /**< (0x218 - 0x27F) */
95980 + uint32_t fmbm_opc; /**< O/H Performance Counters */
95981 + uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
95982 + uint32_t fmbm_occn; /**< O/H Cycle Counter */
95983 + uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
95984 + uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
95985 + uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
95986 +};
95987 +
95988 +/** @Description BMI port register map */
95989 +union fman_port_bmi_regs {
95990 + struct fman_port_rx_bmi_regs rx;
95991 + struct fman_port_tx_bmi_regs tx;
95992 + struct fman_port_oh_bmi_regs oh;
95993 +};
95994 +
95995 +/** @Description QMI port register map */
95996 +struct fman_port_qmi_regs {
95997 + uint32_t fmqm_pnc; /**< PortID n Configuration Register */
95998 + uint32_t fmqm_pns; /**< PortID n Status Register */
95999 + uint32_t fmqm_pnts; /**< PortID n Task Status Register */
96000 + uint32_t reserved00c[4]; /**< 0xn00C - 0xn01B */
96001 + uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
96002 + uint32_t fmqm_pnetfc; /**< PortID n Enq Total Frame Counter */
96003 + uint32_t reserved024[2]; /**< 0xn024 - 0x02B */
96004 + uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
96005 + uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
96006 + uint32_t fmqm_pndtfc; /**< PortID n Dequeue tot Frame cntr */
96007 + uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID Dflt Cntr */
96008 + uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
96009 +};
96010 +
96011 +
96012 +enum fman_port_dma_swap {
96013 + E_FMAN_PORT_DMA_NO_SWAP, /**< No swap, transfer data as is */
96014 + E_FMAN_PORT_DMA_SWAP_LE,
96015 + /**< The transferred data should be swapped in PPC Little Endian mode */
96016 + E_FMAN_PORT_DMA_SWAP_BE
96017 + /**< The transferred data should be swapped in Big Endian mode */
96018 +};
96019 +
96020 +/* Default port color */
96021 +enum fman_port_color {
96022 + E_FMAN_PORT_COLOR_GREEN, /**< Default port color is green */
96023 + E_FMAN_PORT_COLOR_YELLOW, /**< Default port color is yellow */
96024 + E_FMAN_PORT_COLOR_RED, /**< Default port color is red */
96025 + E_FMAN_PORT_COLOR_OVERRIDE /**< Ignore color */
96026 +};
96027 +
96028 +/* QMI dequeue from the SP channel - types */
96029 +enum fman_port_deq_type {
96030 + E_FMAN_PORT_DEQ_BY_PRI,
96031 + /**< Priority precedence and Intra-Class scheduling */
96032 + E_FMAN_PORT_DEQ_ACTIVE_FQ,
96033 + /**< Active FQ precedence and Intra-Class scheduling */
96034 + E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS
96035 + /**< Active FQ precedence and override Intra-Class scheduling */
96036 +};
96037 +
96038 +/* QMI dequeue prefetch modes */
96039 +enum fman_port_deq_prefetch {
96040 + E_FMAN_PORT_DEQ_NO_PREFETCH, /**< No prefetch mode */
96041 + E_FMAN_PORT_DEQ_PART_PREFETCH, /**< Partial prefetch mode */
96042 + E_FMAN_PORT_DEQ_FULL_PREFETCH /**< Full prefetch mode */
96043 +};
96044 +
96045 +/* Parameters for defining performance counters behavior */
96046 +struct fman_port_perf_cnt_params {
96047 + uint8_t task_val; /**< Task compare value */
96048 + uint8_t queue_val;
96049 + /**< Rx or Tx conf queue compare value (unused for O/H ports) */
96050 + uint8_t dma_val; /**< Dma compare value */
96051 + uint32_t fifo_val; /**< Fifo compare value (in bytes) */
96052 +};
96053 +
96054 +/** @Description FM Port configuration structure, used at init */
96055 +struct fman_port_cfg {
96056 + struct fman_port_perf_cnt_params perf_cnt_params;
96057 + /* BMI parameters */
96058 + enum fman_port_dma_swap dma_swap_data;
96059 + bool dma_ic_stash_on;
96060 + bool dma_header_stash_on;
96061 + bool dma_sg_stash_on;
96062 + bool dma_write_optimize;
96063 + uint16_t ic_ext_offset;
96064 + uint8_t ic_int_offset;
96065 + uint16_t ic_size;
96066 + enum fman_port_color color;
96067 + bool sync_req;
96068 + bool discard_override;
96069 + uint8_t checksum_bytes_ignore;
96070 + uint8_t rx_cut_end_bytes;
96071 + uint32_t rx_pri_elevation;
96072 + uint32_t rx_fifo_thr;
96073 + uint8_t rx_fd_bits;
96074 + uint8_t int_buf_start_margin;
96075 + uint16_t ext_buf_start_margin;
96076 + uint16_t ext_buf_end_margin;
96077 + uint32_t tx_fifo_min_level;
96078 + uint32_t tx_fifo_low_comf_level;
96079 + uint8_t tx_fifo_deq_pipeline_depth;
96080 + bool stats_counters_enable;
96081 + bool perf_counters_enable;
96082 + /* QMI parameters */
96083 + bool deq_high_pri;
96084 + enum fman_port_deq_type deq_type;
96085 + enum fman_port_deq_prefetch deq_prefetch_opt;
96086 + uint16_t deq_byte_cnt;
96087 + bool queue_counters_enable;
96088 + bool no_scatter_gather;
96089 + int errata_A006675;
96090 + int errata_A006320;
96091 + int excessive_threshold_register;
96092 + int fmbm_rebm_has_sgd;
96093 + int fmbm_tfne_has_features;
96094 + int qmi_deq_options_support;
96095 +};
96096 +
96097 +enum fman_port_type {
96098 + E_FMAN_PORT_TYPE_OP = 0,
96099 + /**< Offline parsing port, shares id-s with
96100 + * host command, so must have exclusive id-s */
96101 + E_FMAN_PORT_TYPE_RX, /**< 1G Rx port */
96102 + E_FMAN_PORT_TYPE_RX_10G, /**< 10G Rx port */
96103 + E_FMAN_PORT_TYPE_TX, /**< 1G Tx port */
96104 + E_FMAN_PORT_TYPE_TX_10G, /**< 10G Tx port */
96105 + E_FMAN_PORT_TYPE_DUMMY,
96106 + E_FMAN_PORT_TYPE_HC = E_FMAN_PORT_TYPE_DUMMY
96107 + /**< Host command port, shares id-s with
96108 + * offline parsing ports, so must have exclusive id-s */
96109 +};
96110 +
96111 +struct fman_port_params {
96112 + uint32_t discard_mask;
96113 + uint32_t err_mask;
96114 + uint32_t dflt_fqid;
96115 + uint32_t err_fqid;
96116 + uint8_t deq_sp;
96117 + bool dont_release_buf;
96118 +};
96119 +
96120 +/* Port context - used by most API functions */
96121 +struct fman_port {
96122 + enum fman_port_type type;
96123 + uint8_t fm_rev_maj;
96124 + uint8_t fm_rev_min;
96125 + union fman_port_bmi_regs *bmi_regs;
96126 + struct fman_port_qmi_regs *qmi_regs;
96127 + bool im_en;
96128 + uint8_t ext_pools_num;
96129 +};
96130 +
96131 +/** @Description External buffer pools configuration */
96132 +struct fman_port_bpools {
96133 + uint8_t count; /**< Num of pools to set up */
96134 + bool counters_enable; /**< Enable allocate counters */
96135 + uint8_t grp_bp_depleted_num;
96136 + /**< Number of depleted pools - if reached the BMI indicates
96137 + * the MAC to send a pause frame */
96138 + struct {
96139 + uint8_t bpid; /**< BM pool ID */
96140 + uint16_t size;
96141 + /**< Pool's size - must be in ascending order */
96142 + bool is_backup;
96143 + /**< If this is a backup pool */
96144 + bool grp_bp_depleted;
96145 + /**< Consider this buffer in multiple pools depletion criteria*/
96146 + bool single_bp_depleted;
96147 + /**< Consider this buffer in single pool depletion criteria */
96148 + bool pfc_priorities_en;
96149 + } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];
96150 +};
96151 +
96152 +enum fman_port_rate_limiter_scale_down {
96153 + E_FMAN_PORT_RATE_DOWN_NONE,
96154 + E_FMAN_PORT_RATE_DOWN_BY_2,
96155 + E_FMAN_PORT_RATE_DOWN_BY_4,
96156 + E_FMAN_PORT_RATE_DOWN_BY_8
96157 +};
96158 +
96159 +/* Rate limiter configuration */
96160 +struct fman_port_rate_limiter {
96161 + uint8_t count_1micro_bit;
96162 + bool high_burst_size_gran;
96163 + /**< Defines burst_size granularity for OP ports; when TRUE,
96164 + * burst_size below counts in frames, otherwise in 10^3 frames */
96165 + uint16_t burst_size;
96166 + /**< Max burst size, in KBytes for Tx port, according to
96167 + * high_burst_size_gran definition for OP port */
96168 + uint32_t rate;
96169 + /**< In Kbps for Tx port, in frames/sec for OP port */
96170 + enum fman_port_rate_limiter_scale_down rate_factor;
96171 +};
96172 +
96173 +/* BMI statistics counters */
96174 +enum fman_port_stats_counters {
96175 + E_FMAN_PORT_STATS_CNT_FRAME,
96176 + /**< Number of processed frames; valid for all ports */
96177 + E_FMAN_PORT_STATS_CNT_DISCARD,
96178 + /**< For Rx ports - frames discarded by QMAN, for Tx or O/H ports -
96179 + * frames discarded due to DMA error; valid for all ports */
96180 + E_FMAN_PORT_STATS_CNT_DEALLOC_BUF,
96181 + /**< Number of buffer deallocate operations; valid for all ports */
96182 + E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME,
96183 + /**< Number of bad Rx frames, like CRC error, Rx FIFO overflow etc;
96184 + * valid for Rx ports only */
96185 + E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME,
96186 + /**< Number of Rx oversized frames, that is frames exceeding max frame
96187 + * size configured for the corresponding ETH controller;
96188 + * valid for Rx ports only */
96189 + E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF,
96190 + /**< Frames discarded due to lack of external buffers; valid for
96191 + * Rx ports only */
96192 + E_FMAN_PORT_STATS_CNT_LEN_ERR,
96193 + /**< Frames discarded due to frame length error; valid for Tx and
96194 + * O/H ports only */
96195 + E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT,
96196 + /**< Frames discarded due to unsupported FD format; valid for Tx
96197 + * and O/H ports only */
96198 + E_FMAN_PORT_STATS_CNT_FILTERED_FRAME,
96199 + /**< Number of frames filtered out by PCD module; valid for
96200 + * Rx and OP ports only */
96201 + E_FMAN_PORT_STATS_CNT_DMA_ERR,
96202 + /**< Frames rejected by QMAN that were not able to release their
96203 + * buffers due to DMA error; valid for Rx and O/H ports only */
96204 + E_FMAN_PORT_STATS_CNT_WRED_DISCARD
96205 + /**< Frames going through O/H port that were not able to to enter the
96206 + * return queue due to WRED algorithm; valid for O/H ports only */
96207 +};
96208 +
96209 +/* BMI performance counters */
96210 +enum fman_port_perf_counters {
96211 + E_FMAN_PORT_PERF_CNT_CYCLE, /**< Cycle counter */
96212 + E_FMAN_PORT_PERF_CNT_TASK_UTIL, /**< Tasks utilization counter */
96213 + E_FMAN_PORT_PERF_CNT_QUEUE_UTIL,
96214 + /**< For Rx ports - Rx queue utilization, for Tx ports - Tx conf queue
96215 + * utilization; not valid for O/H ports */
96216 + E_FMAN_PORT_PERF_CNT_DMA_UTIL, /**< DMA utilization counter */
96217 + E_FMAN_PORT_PERF_CNT_FIFO_UTIL, /**< FIFO utilization counter */
96218 + E_FMAN_PORT_PERF_CNT_RX_PAUSE
96219 + /**< Number of cycles in which Rx pause activation control is on;
96220 + * valid for Rx ports only */
96221 +};
96222 +
96223 +/* QMI counters */
96224 +enum fman_port_qmi_counters {
96225 + E_FMAN_PORT_ENQ_TOTAL, /**< EnQ tot frame cntr */
96226 + E_FMAN_PORT_DEQ_TOTAL, /**< DeQ tot frame cntr; invalid for Rx ports */
96227 + E_FMAN_PORT_DEQ_FROM_DFLT,
96228 + /**< Dequeue from default FQID counter not valid for Rx ports */
96229 + E_FMAN_PORT_DEQ_CONFIRM /**< DeQ confirm cntr invalid for Rx ports */
96230 +};
96231 +
96232 +
96233 +/** @Collection FM Port API */
96234 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type);
96235 +int fman_port_init(struct fman_port *port,
96236 + struct fman_port_cfg *cfg,
96237 + struct fman_port_params *params);
96238 +int fman_port_enable(struct fman_port *port);
96239 +int fman_port_disable(const struct fman_port *port);
96240 +int fman_port_set_bpools(const struct fman_port *port,
96241 + const struct fman_port_bpools *bp);
96242 +int fman_port_set_rate_limiter(struct fman_port *port,
96243 + struct fman_port_rate_limiter *rate_limiter);
96244 +int fman_port_delete_rate_limiter(struct fman_port *port);
96245 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask);
96246 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask);
96247 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
96248 + uint8_t rx_fd_bits,
96249 + bool add);
96250 +int fman_port_set_perf_cnt_params(struct fman_port *port,
96251 + struct fman_port_perf_cnt_params *params);
96252 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable);
96253 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable);
96254 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable);
96255 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
96256 + uint8_t bpid,
96257 + bool enable);
96258 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
96259 + enum fman_port_stats_counters counter);
96260 +void fman_port_set_stats_counter(struct fman_port *port,
96261 + enum fman_port_stats_counters counter,
96262 + uint32_t value);
96263 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
96264 + enum fman_port_perf_counters counter);
96265 +void fman_port_set_perf_counter(struct fman_port *port,
96266 + enum fman_port_perf_counters counter,
96267 + uint32_t value);
96268 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
96269 + enum fman_port_qmi_counters counter);
96270 +void fman_port_set_qmi_counter(struct fman_port *port,
96271 + enum fman_port_qmi_counters counter,
96272 + uint32_t value);
96273 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid);
96274 +void fman_port_set_bpool_counter(struct fman_port *port,
96275 + uint8_t bpid,
96276 + uint32_t value);
96277 +int fman_port_add_congestion_grps(struct fman_port *port,
96278 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
96279 +int fman_port_remove_congestion_grps(struct fman_port *port,
96280 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
96281 +
96282 +
96283 +#endif /* __FSL_FMAN_PORT_H */
96284 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
96285 new file mode 100644
96286 index 00000000..b18997dc
96287 --- /dev/null
96288 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
96289 @@ -0,0 +1,102 @@
96290 +/*
96291 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96292 + *
96293 + * Redistribution and use in source and binary forms, with or without
96294 + * modification, are permitted provided that the following conditions are met:
96295 + * * Redistributions of source code must retain the above copyright
96296 + * notice, this list of conditions and the following disclaimer.
96297 + * * Redistributions in binary form must reproduce the above copyright
96298 + * notice, this list of conditions and the following disclaimer in the
96299 + * documentation and/or other materials provided with the distribution.
96300 + * * Neither the name of Freescale Semiconductor nor the
96301 + * names of its contributors may be used to endorse or promote products
96302 + * derived from this software without specific prior written permission.
96303 + *
96304 + *
96305 + * ALTERNATIVELY, this software may be distributed under the terms of the
96306 + * GNU General Public License ("GPL") as published by the Free Software
96307 + * Foundation, either version 2 of that License or (at your option) any
96308 + * later version.
96309 + *
96310 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96311 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96312 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96313 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96314 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96315 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96316 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96317 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96318 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96319 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96320 + */
96321 +
96322 +#ifndef __FSL_FMAN_PRS_H
96323 +#define __FSL_FMAN_PRS_H
96324 +
96325 +#include "common/general.h"
96326 +
96327 +#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000
96328 +#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000
96329 +
96330 +#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000
96331 +#define FM_PCD_PRS_RPIMAC_EN 0x00000001
96332 +#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000
96333 +#define FM_PCD_PRS_SINGLE_ECC 0x00004000
96334 +#define FM_PCD_PRS_DOUBLE_ECC 0x00004000
96335 +#define PRS_MAX_CYCLE_LIMIT 8191
96336 +
96337 +#define DEFAULT_MAX_PRS_CYC_LIM 0
96338 +
96339 +struct fman_prs_regs {
96340 + uint32_t fmpr_rpclim;
96341 + uint32_t fmpr_rpimac;
96342 + uint32_t pmeec;
96343 + uint32_t res00c[5];
96344 + uint32_t fmpr_pevr;
96345 + uint32_t fmpr_pever;
96346 + uint32_t res028;
96347 + uint32_t fmpr_perr;
96348 + uint32_t fmpr_perer;
96349 + uint32_t res034;
96350 + uint32_t res038[10];
96351 + uint32_t fmpr_ppsc;
96352 + uint32_t res064;
96353 + uint32_t fmpr_pds;
96354 + uint32_t fmpr_l2rrs;
96355 + uint32_t fmpr_l3rrs;
96356 + uint32_t fmpr_l4rrs;
96357 + uint32_t fmpr_srrs;
96358 + uint32_t fmpr_l2rres;
96359 + uint32_t fmpr_l3rres;
96360 + uint32_t fmpr_l4rres;
96361 + uint32_t fmpr_srres;
96362 + uint32_t fmpr_spcs;
96363 + uint32_t fmpr_spscs;
96364 + uint32_t fmpr_hxscs;
96365 + uint32_t fmpr_mrcs;
96366 + uint32_t fmpr_mwcs;
96367 + uint32_t fmpr_mrscs;
96368 + uint32_t fmpr_mwscs;
96369 + uint32_t fmpr_fcscs;
96370 +};
96371 +
96372 +struct fman_prs_cfg {
96373 + uint32_t port_id_stat;
96374 + uint16_t max_prs_cyc_lim;
96375 + uint32_t prs_exceptions;
96376 +};
96377 +
96378 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask);
96379 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs);
96380 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event);
96381 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask);
96382 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs);
96383 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event);
96384 +void fman_prs_defconfig(struct fman_prs_cfg *cfg);
96385 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg);
96386 +void fman_prs_enable(struct fman_prs_regs *regs);
96387 +void fman_prs_disable(struct fman_prs_regs *regs);
96388 +int fman_prs_is_enabled(struct fman_prs_regs *regs);
96389 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk);
96390 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable);
96391 +#endif /* __FSL_FMAN_PRS_H */
96392 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
96393 new file mode 100755
96394 index 00000000..f6b69a1f
96395 --- /dev/null
96396 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
96397 @@ -0,0 +1,449 @@
96398 +/*
96399 + * Copyright 2013 Freescale Semiconductor Inc.
96400 + *
96401 + * Redistribution and use in source and binary forms, with or without
96402 + * modification, are permitted provided that the following conditions are met:
96403 + * * Redistributions of source code must retain the above copyright
96404 + * notice, this list of conditions and the following disclaimer.
96405 + * * Redistributions in binary form must reproduce the above copyright
96406 + * notice, this list of conditions and the following disclaimer in the
96407 + * documentation and/or other materials provided with the distribution.
96408 + * * Neither the name of Freescale Semiconductor nor the
96409 + * names of its contributors may be used to endorse or promote products
96410 + * derived from this software without specific prior written permission.
96411 + *
96412 + *
96413 + * ALTERNATIVELY, this software may be distributed under the terms of the
96414 + * GNU General Public License ("GPL") as published by the Free Software
96415 + * Foundation, either version 2 of that License or (at your option) any
96416 + * later version.
96417 + *
96418 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96419 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96420 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96421 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96422 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96423 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96424 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96425 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96426 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96427 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96428 + */
96429 +
96430 +#ifndef __FSL_FMAN_RTC_H
96431 +#define __FSL_FMAN_RTC_H
96432 +
96433 +#include "common/general.h"
96434 +
96435 +/* FM RTC Registers definitions */
96436 +#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000
96437 +#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000
96438 +#define FMAN_RTC_TMR_CTRL_FS 0x10000000
96439 +#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000
96440 +#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000
96441 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000
96442 +#define FMAN_RTC_TMR_CTRL_FRD 0x00004000
96443 +#define FMAN_RTC_TMR_CTRL_SLV 0x00002000
96444 +#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100
96445 +#define FMAN_RTC_TMR_CTRL_COPH 0x00000080
96446 +#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040
96447 +#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020
96448 +#define FMAN_RTC_TMR_CTRL_DBG 0x00000010
96449 +#define FMAN_RTC_TMR_CTRL_BYP 0x00000008
96450 +#define FMAN_RTC_TMR_CTRL_TE 0x00000004
96451 +#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003
96452 +#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001
96453 +#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000
96454 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16
96455 +
96456 +#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000
96457 +#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000
96458 +#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000
96459 +#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000
96460 +#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080
96461 +#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040
96462 +#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020
96463 +#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\
96464 + FMAN_RTC_TMR_TEVENT_ETS1 |\
96465 + FMAN_RTC_TMR_TEVENT_ALM2 |\
96466 + FMAN_RTC_TMR_TEVENT_ALM1 |\
96467 + FMAN_RTC_TMR_TEVENT_PP1 |\
96468 + FMAN_RTC_TMR_TEVENT_PP2 |\
96469 + FMAN_RTC_TMR_TEVENT_PP3)
96470 +
96471 +#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF
96472 +
96473 +/**************************************************************************//**
96474 + @Description FM RTC Alarm Polarity Options.
96475 +*//***************************************************************************/
96476 +enum fman_rtc_alarm_polarity {
96477 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
96478 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
96479 +};
96480 +
96481 +/**************************************************************************//**
96482 + @Description FM RTC Trigger Polarity Options.
96483 +*//***************************************************************************/
96484 +enum fman_rtc_trigger_polarity {
96485 + E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
96486 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
96487 +};
96488 +
96489 +/**************************************************************************//**
96490 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
96491 +*//***************************************************************************/
96492 +enum fman_src_clock {
96493 + E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer
96494 + reference clock */
96495 + E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
96496 + E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
96497 +};
96498 +
96499 +/* RTC default values */
96500 +#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM
96501 +#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE
96502 +#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE
96503 +#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH
96504 +#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE
96505 +#define DEFAULT_PULSE_REALIGN FALSE
96506 +
96507 +#define FMAN_RTC_MAX_NUM_OF_ALARMS 3
96508 +#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4
96509 +#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3
96510 +
96511 +/**************************************************************************//**
96512 + @Description FM RTC timer alarm
96513 +*//***************************************************************************/
96514 +struct t_tmr_alarm{
96515 + uint32_t tmr_alarm_h; /**< */
96516 + uint32_t tmr_alarm_l; /**< */
96517 +};
96518 +
96519 +/**************************************************************************//**
96520 + @Description FM RTC timer Ex trigger
96521 +*//***************************************************************************/
96522 +struct t_tmr_ext_trigger{
96523 + uint32_t tmr_etts_h; /**< */
96524 + uint32_t tmr_etts_l; /**< */
96525 +};
96526 +
96527 +struct rtc_regs {
96528 + uint32_t tmr_id; /* 0x000 Module ID register */
96529 + uint32_t tmr_id2; /* 0x004 Controller ID register */
96530 + uint32_t reserved0008[30];
96531 + uint32_t tmr_ctrl; /* 0x0080 timer control register */
96532 + uint32_t tmr_tevent; /* 0x0084 timer event register */
96533 + uint32_t tmr_temask; /* 0x0088 timer event mask register */
96534 + uint32_t reserved008c[3];
96535 + uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */
96536 + uint32_t tmr_cnt_l; /* 0x009c timer counter low register */
96537 + uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */
96538 + uint32_t tmr_acc; /* 0x00a4 timer accumulator register */
96539 + uint32_t tmr_prsc; /* 0x00a8 timer prescale */
96540 + uint32_t reserved00ac;
96541 + uint32_t tmr_off_h; /* 0x00b0 timer offset high */
96542 + uint32_t tmr_off_l; /* 0x00b4 timer offset low */
96543 + struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer
96544 + alarm */
96545 + uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer
96546 + fixed period interval */
96547 + struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
96548 + /* 0x00e0 time stamp general purpose external */
96549 + uint32_t reserved00f0[4];
96550 +};
96551 +
96552 +struct rtc_cfg {
96553 + enum fman_src_clock src_clk;
96554 + uint32_t ext_src_clk_freq;
96555 + uint32_t rtc_freq_hz;
96556 + bool timer_slave_mode;
96557 + bool invert_input_clk_phase;
96558 + bool invert_output_clk_phase;
96559 + uint32_t events_mask;
96560 + bool bypass; /**< Indicates if frequency compensation
96561 + is bypassed */
96562 + bool pulse_realign;
96563 + enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS];
96564 + enum fman_rtc_trigger_polarity trigger_polarity
96565 + [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
96566 +};
96567 +
96568 +/**
96569 + * fman_rtc_defconfig() - Get default RTC configuration
96570 + * @cfg: pointer to configuration structure.
96571 + *
96572 + * Call this function to obtain a default set of configuration values for
96573 + * initializing RTC. The user can overwrite any of the values before calling
96574 + * fman_rtc_init(), if specific configuration needs to be applied.
96575 + */
96576 +void fman_rtc_defconfig(struct rtc_cfg *cfg);
96577 +
96578 +/**
96579 + * fman_rtc_get_events() - Get the events
96580 + * @regs: Pointer to RTC register block
96581 + *
96582 + * Returns: The events
96583 + */
96584 +uint32_t fman_rtc_get_events(struct rtc_regs *regs);
96585 +
96586 +/**
96587 + * fman_rtc_get_interrupt_mask() - Get the events mask
96588 + * @regs: Pointer to RTC register block
96589 + *
96590 + * Returns: The events mask
96591 + */
96592 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs);
96593 +
96594 +
96595 +/**
96596 + * fman_rtc_set_interrupt_mask() - Set the events mask
96597 + * @regs: Pointer to RTC register block
96598 + * @mask: The mask to set
96599 + */
96600 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask);
96601 +
96602 +/**
96603 + * fman_rtc_get_event() - Check if specific events occurred
96604 + * @regs: Pointer to RTC register block
96605 + * @ev_mask: a mask of the events to check
96606 + *
96607 + * Returns: 0 if the events did not occur. Non zero if one of the events occurred
96608 + */
96609 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask);
96610 +
96611 +/**
96612 + * fman_rtc_check_and_clear_event() - Clear events which are on
96613 + * @regs: Pointer to RTC register block
96614 + *
96615 + * Returns: A mask of the events which were cleared
96616 + */
96617 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs);
96618 +
96619 +/**
96620 + * fman_rtc_ack_event() - Clear events
96621 + * @regs: Pointer to RTC register block
96622 + * @events: The events to disable
96623 + */
96624 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events);
96625 +
96626 +/**
96627 + * fman_rtc_enable_interupt() - Enable events interrupts
96628 + * @regs: Pointer to RTC register block
96629 + * @mask: The events to disable
96630 + */
96631 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask);
96632 +
96633 +/**
96634 + * fman_rtc_disable_interupt() - Disable events interrupts
96635 + * @regs: Pointer to RTC register block
96636 + * @mask: The events to disable
96637 + */
96638 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask);
96639 +
96640 +/**
96641 + * fman_rtc_get_timer_ctrl() - Get the control register
96642 + * @regs: Pointer to RTC register block
96643 + *
96644 + * Returns: The control register value
96645 + */
96646 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs);
96647 +
96648 +/**
96649 + * fman_rtc_set_timer_ctrl() - Set timer control register
96650 + * @regs: Pointer to RTC register block
96651 + * @val: The value to set
96652 + */
96653 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val);
96654 +
96655 +/**
96656 + * fman_rtc_get_frequency_compensation() - Get the frequency compensation
96657 + * @regs: Pointer to RTC register block
96658 + *
96659 + * Returns: The timer counter
96660 + */
96661 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs);
96662 +
96663 +/**
96664 + * fman_rtc_set_frequency_compensation() - Set frequency compensation
96665 + * @regs: Pointer to RTC register block
96666 + * @val: The value to set
96667 + */
96668 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val);
96669 +
96670 +/**
96671 + * fman_rtc_get_trigger_stamp() - Get a trigger stamp
96672 + * @regs: Pointer to RTC register block
96673 + * @id: The id of the trigger stamp
96674 + *
96675 + * Returns: The time stamp
96676 + */
96677 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id);
96678 +
96679 +/**
96680 + * fman_rtc_set_timer_alarm_l() - Set timer alarm low register
96681 + * @regs: Pointer to RTC register block
96682 + * @index: The index of alarm to set
96683 + * @val: The value to set
96684 + */
96685 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index,
96686 + uint32_t val);
96687 +
96688 +/**
96689 + * fman_rtc_set_timer_alarm() - Set timer alarm
96690 + * @regs: Pointer to RTC register block
96691 + * @index: The index of alarm to set
96692 + * @val: The value to set
96693 + */
96694 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val);
96695 +
96696 +/**
96697 + * fman_rtc_set_timer_fiper() - Set timer fiper
96698 + * @regs: Pointer to RTC register block
96699 + * @index: The index of fiper to set
96700 + * @val: The value to set
96701 + */
96702 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val);
96703 +
96704 +/**
96705 + * fman_rtc_set_timer_offset() - Set timer offset
96706 + * @regs: Pointer to RTC register block
96707 + * @val: The value to set
96708 + */
96709 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val);
96710 +
96711 +/**
96712 + * fman_rtc_get_timer() - Get the timer counter
96713 + * @regs: Pointer to RTC register block
96714 + *
96715 + * Returns: The timer counter
96716 + */
96717 +static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs)
96718 +{
96719 + uint64_t time;
96720 + /* TMR_CNT_L must be read first to get an accurate value */
96721 + time = (uint64_t)ioread32be(&regs->tmr_cnt_l);
96722 + time |= ((uint64_t)ioread32be(&regs->tmr_cnt_h) << 32);
96723 +
96724 + return time;
96725 +}
96726 +
96727 +/**
96728 + * fman_rtc_set_timer() - Set timer counter
96729 + * @regs: Pointer to RTC register block
96730 + * @val: The value to set
96731 + */
96732 +static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)
96733 +{
96734 + iowrite32be((uint32_t)val, &regs->tmr_cnt_l);
96735 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_cnt_h);
96736 +}
96737 +
96738 +/**
96739 + * fman_rtc_timers_soft_reset() - Soft reset
96740 + * @regs: Pointer to RTC register block
96741 + *
96742 + * Resets all the timer registers and state machines for the 1588 IP and
96743 + * the attached client 1588
96744 + */
96745 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs);
96746 +
96747 +/**
96748 + * fman_rtc_clear_external_trigger() - Clear an external trigger
96749 + * @regs: Pointer to RTC register block
96750 + * @id: The id of the trigger to clear
96751 + */
96752 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id);
96753 +
96754 +/**
96755 + * fman_rtc_clear_periodic_pulse() - Clear periodic pulse
96756 + * @regs: Pointer to RTC register block
96757 + * @id: The id of the fiper to clear
96758 + */
96759 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id);
96760 +
96761 +/**
96762 + * fman_rtc_enable() - Enable RTC hardware block
96763 + * @regs: Pointer to RTC register block
96764 + */
96765 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock);
96766 +
96767 +/**
96768 + * fman_rtc_is_enabled() - Is RTC hardware block enabled
96769 + * @regs: Pointer to RTC register block
96770 + *
96771 + * Return: TRUE if enabled
96772 + */
96773 +bool fman_rtc_is_enabled(struct rtc_regs *regs);
96774 +
96775 +/**
96776 + * fman_rtc_disable() - Disable RTC hardware block
96777 + * @regs: Pointer to RTC register block
96778 + */
96779 +void fman_rtc_disable(struct rtc_regs *regs);
96780 +
96781 +/**
96782 + * fman_rtc_init() - Init RTC hardware block
96783 + * @cfg: RTC configuration data
96784 + * @regs: Pointer to RTC register block
96785 + * @num_alarms: Number of alarms in RTC
96786 + * @num_fipers: Number of fipers in RTC
96787 + * @num_ext_triggers: Number of external triggers in RTC
96788 + * @freq_compensation: Frequency compensation
96789 + * @output_clock_divisor: Output clock divisor
96790 + *
96791 + * This function initializes RTC and applies basic configuration.
96792 + */
96793 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
96794 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
96795 + uint32_t freq_compensation, uint32_t output_clock_divisor);
96796 +
96797 +/**
96798 + * fman_rtc_set_alarm() - Set an alarm
96799 + * @regs: Pointer to RTC register block
96800 + * @id: id of alarm
96801 + * @val: value to write
96802 + * @enable: should interrupt be enabled
96803 + */
96804 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable);
96805 +
96806 +/**
96807 + * fman_rtc_set_periodic_pulse() - Set an alarm
96808 + * @regs: Pointer to RTC register block
96809 + * @id: id of fiper
96810 + * @val: value to write
96811 + * @enable: should interrupt be enabled
96812 + */
96813 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
96814 + bool enable);
96815 +
96816 +/**
96817 + * fman_rtc_set_ext_trigger() - Set an external trigger
96818 + * @regs: Pointer to RTC register block
96819 + * @id: id of trigger
96820 + * @enable: should interrupt be enabled
96821 + * @use_pulse_as_input: use the pulse as input
96822 + */
96823 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
96824 + bool use_pulse_as_input);
96825 +
96826 +struct fm_rtc_alarm_params {
96827 + uint8_t alarm_id; /**< 0 or 1 */
96828 + uint64_t alarm_time; /**< In nanoseconds, the time when the
96829 + alarm should go off - must be a
96830 + multiple of the RTC period */
96831 + void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will
96832 + be called when RTC reaches alarmTime */
96833 + bool clear_on_expiration; /**< TRUE to turn off the alarm once
96834 + expired.*/
96835 +};
96836 +
96837 +struct fm_rtc_periodic_pulse_params {
96838 + uint8_t periodic_pulse_id; /**< 0 or 1 */
96839 + uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple
96840 + of the RTC period */
96841 + void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This
96842 + routine will be called every
96843 + periodicPulsePeriod. */
96844 +};
96845 +
96846 +#endif /* __FSL_FMAN_RTC_H */
96847 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
96848 new file mode 100755
96849 index 00000000..f8ef7d56
96850 --- /dev/null
96851 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
96852 @@ -0,0 +1,138 @@
96853 +/*
96854 + * Copyright 2013 Freescale Semiconductor Inc.
96855 + *
96856 + * Redistribution and use in source and binary forms, with or without
96857 + * modification, are permitted provided that the following conditions are met:
96858 + * * Redistributions of source code must retain the above copyright
96859 + * notice, this list of conditions and the following disclaimer.
96860 + * * Redistributions in binary form must reproduce the above copyright
96861 + * notice, this list of conditions and the following disclaimer in the
96862 + * documentation and/or other materials provided with the distribution.
96863 + * * Neither the name of Freescale Semiconductor nor the
96864 + * names of its contributors may be used to endorse or promote products
96865 + * derived from this software without specific prior written permission.
96866 + *
96867 + *
96868 + * ALTERNATIVELY, this software may be distributed under the terms of the
96869 + * GNU General Public License ("GPL") as published by the Free Software
96870 + * Foundation, either version 2 of that License or (at your option) any
96871 + * later version.
96872 + *
96873 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96874 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96875 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96876 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96877 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96878 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96879 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96880 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96881 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96882 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96883 + */
96884 +
96885 +#ifndef __FSL_FMAN_SP_H
96886 +#define __FSL_FMAN_SP_H
96887 +
96888 +#include "common/general.h"
96889 +#include "fsl_fman.h"
96890 +
96891 +
96892 +struct fm_pcd_storage_profile_regs{
96893 + uint32_t fm_sp_ebmpi[8];
96894 + /*offset 0 - 0xc*/
96895 + /**< Buffer Manager pool Information */
96896 +
96897 + uint32_t fm_sp_acnt; /*offset 0x20*/
96898 + uint32_t fm_sp_ebm; /*offset 0x24*/
96899 + uint32_t fm_sp_da; /*offset 0x28*/
96900 + uint32_t fm_sp_icp; /*offset 0x2c*/
96901 + uint32_t fm_sp_mpd; /*offset 0x30*/
96902 + uint32_t res1[2]; /*offset 0x34 - 0x38*/
96903 + uint32_t fm_sp_spliodn; /*offset 0x3c*/
96904 +};
96905 +
96906 +/**************************************************************************//**
96907 + @Description structure for defining internal context copying
96908 +*//***************************************************************************/
96909 +struct fman_sp_int_context_data_copy{
96910 + uint16_t ext_buf_offset; /**< Offset in External buffer to which
96911 + internal context is copied to (Rx)
96912 + or taken from (Tx, Op). */
96913 + uint8_t int_context_offset; /**< Offset within internal context to copy
96914 + from (Rx) or to copy to (Tx, Op).*/
96915 + uint16_t size; /**< Internal offset size to be copied */
96916 +};
96917 +
96918 +/**************************************************************************//**
96919 + @Description struct for defining external buffer margins
96920 +*//***************************************************************************/
96921 +struct fman_sp_buf_margins{
96922 + uint16_t start_margins; /**< Number of bytes to be left at the
96923 + beginning of the external buffer (must be
96924 + divisible by 16) */
96925 + uint16_t end_margins; /**< number of bytes to be left at the end of
96926 + the external buffer(must be divisible by 16)*/
96927 +};
96928 +
96929 +struct fm_storage_profile_params {
96930 + struct fman_ext_pools fm_ext_pools;
96931 + struct fman_backup_bm_pools backup_pools;
96932 + struct fman_sp_int_context_data_copy *int_context;
96933 + struct fman_sp_buf_margins *buf_margins;
96934 + enum fman_dma_swap_option dma_swap_data;
96935 + enum fman_dma_cache_option int_context_cache_attr;
96936 + enum fman_dma_cache_option header_cache_attr;
96937 + enum fman_dma_cache_option scatter_gather_cache_attr;
96938 + bool dma_write_optimize;
96939 + uint16_t liodn_offset;
96940 + bool no_scather_gather;
96941 + struct fman_buf_pool_depletion buf_pool_depletion;
96942 +};
96943 +
96944 +/**************************************************************************//**
96945 + @Description Registers bit fields
96946 +*//***************************************************************************/
96947 +#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000
96948 +#define FMAN_SP_EXT_BUF_POOL_VALID 0x80000000
96949 +#define FMAN_SP_EXT_BUF_POOL_BACKUP 0x20000000
96950 +#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000
96951 +#define FMAN_SP_SG_DISABLE 0x80000000
96952 +
96953 +/* shifts */
96954 +#define FMAN_SP_EXT_BUF_POOL_ID_SHIFT 16
96955 +#define FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16
96956 +#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16
96957 +#define FMAN_SP_EXT_BUF_MARG_END_SHIFT 0
96958 +#define FMAN_SP_DMA_ATTR_SWP_SHIFT 30
96959 +#define FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT 28
96960 +#define FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT 26
96961 +#define FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT 24
96962 +#define FMAN_SP_IC_TO_EXT_SHIFT 16
96963 +#define FMAN_SP_IC_FROM_INT_SHIFT 8
96964 +#define FMAN_SP_IC_SIZE_SHIFT 0
96965 +
96966 +/**************************************************************************//**
96967 + @Description defaults
96968 +*//***************************************************************************/
96969 +#define DEFAULT_FMAN_SP_DMA_SWAP_DATA FMAN_DMA_NO_SWP
96970 +#define DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR FMAN_DMA_NO_STASH
96971 +#define DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR FMAN_DMA_NO_STASH
96972 +#define DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR FMAN_DMA_NO_STASH
96973 +#define DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE TRUE
96974 +#define DEFAULT_FMAN_SP_NO_SCATTER_GATHER FALSE
96975 +
96976 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg);
96977 +
96978 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
96979 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
96980 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
96981 + int max_num_of_pfc_priorities);
96982 +
96983 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
96984 + uint16_t index);
96985 +
96986 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
96987 + uint16_t index, uint32_t value);
96988 +
96989 +
96990 +#endif /* __FSL_FMAN_SP_H */
96991 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
96992 new file mode 100644
96993 index 00000000..a0373141
96994 --- /dev/null
96995 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
96996 @@ -0,0 +1,479 @@
96997 +/*
96998 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96999 + *
97000 + * Redistribution and use in source and binary forms, with or without
97001 + * modification, are permitted provided that the following conditions are met:
97002 + * * Redistributions of source code must retain the above copyright
97003 + * notice, this list of conditions and the following disclaimer.
97004 + * * Redistributions in binary form must reproduce the above copyright
97005 + * notice, this list of conditions and the following disclaimer in the
97006 + * documentation and/or other materials provided with the distribution.
97007 + * * Neither the name of Freescale Semiconductor nor the
97008 + * names of its contributors may be used to endorse or promote products
97009 + * derived from this software without specific prior written permission.
97010 + *
97011 + *
97012 + * ALTERNATIVELY, this software may be distributed under the terms of the
97013 + * GNU General Public License ("GPL") as published by the Free Software
97014 + * Foundation, either version 2 of that License or (at your option) any
97015 + * later version.
97016 + *
97017 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97018 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97019 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97020 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97021 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97022 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97023 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97024 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97025 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97026 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97027 + */
97028 +
97029 +#ifndef __FSL_FMAN_TGEC_H
97030 +#define __FSL_FMAN_TGEC_H
97031 +
97032 +#include "common/general.h"
97033 +#include "fsl_enet.h"
97034 +
97035 +
97036 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
97037 +#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
97038 +
97039 +enum tgec_counters {
97040 + E_TGEC_COUNTER_R64,
97041 + E_TGEC_COUNTER_R127,
97042 + E_TGEC_COUNTER_R255,
97043 + E_TGEC_COUNTER_R511,
97044 + E_TGEC_COUNTER_R1023,
97045 + E_TGEC_COUNTER_R1518,
97046 + E_TGEC_COUNTER_R1519X,
97047 + E_TGEC_COUNTER_TRFRG,
97048 + E_TGEC_COUNTER_TRJBR,
97049 + E_TGEC_COUNTER_RDRP,
97050 + E_TGEC_COUNTER_RALN,
97051 + E_TGEC_COUNTER_TRUND,
97052 + E_TGEC_COUNTER_TROVR,
97053 + E_TGEC_COUNTER_RXPF,
97054 + E_TGEC_COUNTER_TXPF,
97055 + E_TGEC_COUNTER_ROCT,
97056 + E_TGEC_COUNTER_RMCA,
97057 + E_TGEC_COUNTER_RBCA,
97058 + E_TGEC_COUNTER_RPKT,
97059 + E_TGEC_COUNTER_RUCA,
97060 + E_TGEC_COUNTER_RERR,
97061 + E_TGEC_COUNTER_TOCT,
97062 + E_TGEC_COUNTER_TMCA,
97063 + E_TGEC_COUNTER_TBCA,
97064 + E_TGEC_COUNTER_TUCA,
97065 + E_TGEC_COUNTER_TERR
97066 +};
97067 +
97068 +/* Command and Configuration Register (COMMAND_CONFIG) */
97069 +#define CMD_CFG_EN_TIMESTAMP 0x00100000
97070 +#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000
97071 +#define CMD_CFG_NO_LEN_CHK 0x00020000
97072 +#define CMD_CFG_SEND_IDLE 0x00010000
97073 +#define CMD_CFG_RX_ER_DISC 0x00004000
97074 +#define CMD_CFG_CMD_FRM_EN 0x00002000
97075 +#define CMD_CFG_STAT_CLR 0x00001000
97076 +#define CMD_CFG_LOOPBACK_EN 0x00000400
97077 +#define CMD_CFG_TX_ADDR_INS 0x00000200
97078 +#define CMD_CFG_PAUSE_IGNORE 0x00000100
97079 +#define CMD_CFG_PAUSE_FWD 0x00000080
97080 +#define CMD_CFG_PROMIS_EN 0x00000010
97081 +#define CMD_CFG_WAN_MODE 0x00000008
97082 +#define CMD_CFG_RX_EN 0x00000002
97083 +#define CMD_CFG_TX_EN 0x00000001
97084 +
97085 +/* Interrupt Mask Register (IMASK) */
97086 +#define TGEC_IMASK_MDIO_SCAN_EVENT 0x00010000
97087 +#define TGEC_IMASK_MDIO_CMD_CMPL 0x00008000
97088 +#define TGEC_IMASK_REM_FAULT 0x00004000
97089 +#define TGEC_IMASK_LOC_FAULT 0x00002000
97090 +#define TGEC_IMASK_TX_ECC_ER 0x00001000
97091 +#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800
97092 +#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400
97093 +#define TGEC_IMASK_TX_ER 0x00000200
97094 +#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100
97095 +#define TGEC_IMASK_RX_ECC_ER 0x00000080
97096 +#define TGEC_IMASK_RX_JAB_FRM 0x00000040
97097 +#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020
97098 +#define TGEC_IMASK_RX_RUNT_FRM 0x00000010
97099 +#define TGEC_IMASK_RX_FRAG_FRM 0x00000008
97100 +#define TGEC_IMASK_RX_LEN_ER 0x00000004
97101 +#define TGEC_IMASK_RX_CRC_ER 0x00000002
97102 +#define TGEC_IMASK_RX_ALIGN_ER 0x00000001
97103 +
97104 +#define TGEC_EVENTS_MASK \
97105 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
97106 + TGEC_IMASK_MDIO_CMD_CMPL | \
97107 + TGEC_IMASK_REM_FAULT | \
97108 + TGEC_IMASK_LOC_FAULT | \
97109 + TGEC_IMASK_TX_ECC_ER | \
97110 + TGEC_IMASK_TX_FIFO_UNFL | \
97111 + TGEC_IMASK_TX_FIFO_OVFL | \
97112 + TGEC_IMASK_TX_ER | \
97113 + TGEC_IMASK_RX_FIFO_OVFL | \
97114 + TGEC_IMASK_RX_ECC_ER | \
97115 + TGEC_IMASK_RX_JAB_FRM | \
97116 + TGEC_IMASK_RX_OVRSZ_FRM | \
97117 + TGEC_IMASK_RX_RUNT_FRM | \
97118 + TGEC_IMASK_RX_FRAG_FRM | \
97119 + TGEC_IMASK_RX_LEN_ER | \
97120 + TGEC_IMASK_RX_CRC_ER | \
97121 + TGEC_IMASK_RX_ALIGN_ER))
97122 +
97123 +/* Hashtable Control Register (HASHTABLE_CTRL) */
97124 +#define TGEC_HASH_MCAST_SHIFT 23
97125 +#define TGEC_HASH_MCAST_EN 0x00000200
97126 +#define TGEC_HASH_ADR_MSK 0x000001ff
97127 +
97128 +#define DEFAULT_WAN_MODE_ENABLE FALSE
97129 +#define DEFAULT_PROMISCUOUS_MODE_ENABLE FALSE
97130 +#define DEFAULT_PAUSE_FORWARD_ENABLE FALSE
97131 +#define DEFAULT_PAUSE_IGNORE FALSE
97132 +#define DEFAULT_TX_ADDR_INS_ENABLE FALSE
97133 +#define DEFAULT_LOOPBACK_ENABLE FALSE
97134 +#define DEFAULT_CMD_FRAME_ENABLE FALSE
97135 +#define DEFAULT_RX_ERROR_DISCARD FALSE
97136 +#define DEFAULT_SEND_IDLE_ENABLE FALSE
97137 +#define DEFAULT_NO_LENGTH_CHECK_ENABLE TRUE
97138 +#define DEFAULT_LGTH_CHECK_NOSTDR FALSE
97139 +#define DEFAULT_TIME_STAMP_ENABLE FALSE
97140 +#define DEFAULT_TX_IPG_LENGTH 12
97141 +#define DEFAULT_MAX_FRAME_LENGTH 0x600
97142 +#define DEFAULT_PAUSE_QUANT 0xf000
97143 +
97144 +/*
97145 + * 10G memory map
97146 + */
97147 +struct tgec_regs {
97148 + uint32_t tgec_id; /* 0x000 Controller ID */
97149 + uint32_t reserved001[1]; /* 0x004 */
97150 + uint32_t command_config; /* 0x008 Control and configuration */
97151 + uint32_t mac_addr_0; /* 0x00c Lower 32 bits of the MAC adr */
97152 + uint32_t mac_addr_1; /* 0x010 Upper 16 bits of the MAC adr */
97153 + uint32_t maxfrm; /* 0x014 Maximum frame length */
97154 + uint32_t pause_quant; /* 0x018 Pause quanta */
97155 + uint32_t rx_fifo_sections; /* 0x01c */
97156 + uint32_t tx_fifo_sections; /* 0x020 */
97157 + uint32_t rx_fifo_almost_f_e; /* 0x024 */
97158 + uint32_t tx_fifo_almost_f_e; /* 0x028 */
97159 + uint32_t hashtable_ctrl; /* 0x02c Hash table control*/
97160 + uint32_t mdio_cfg_status; /* 0x030 */
97161 + uint32_t mdio_command; /* 0x034 */
97162 + uint32_t mdio_data; /* 0x038 */
97163 + uint32_t mdio_regaddr; /* 0x03c */
97164 + uint32_t status; /* 0x040 */
97165 + uint32_t tx_ipg_len; /* 0x044 Transmitter inter-packet-gap */
97166 + uint32_t mac_addr_2; /* 0x048 Lower 32 bits of 2nd MAC adr */
97167 + uint32_t mac_addr_3; /* 0x04c Upper 16 bits of 2nd MAC adr */
97168 + uint32_t rx_fifo_ptr_rd; /* 0x050 */
97169 + uint32_t rx_fifo_ptr_wr; /* 0x054 */
97170 + uint32_t tx_fifo_ptr_rd; /* 0x058 */
97171 + uint32_t tx_fifo_ptr_wr; /* 0x05c */
97172 + uint32_t imask; /* 0x060 Interrupt mask */
97173 + uint32_t ievent; /* 0x064 Interrupt event */
97174 + uint32_t udp_port; /* 0x068 Defines a UDP Port number */
97175 + uint32_t type_1588v2; /* 0x06c Type field for 1588v2 */
97176 + uint32_t reserved070[4]; /* 0x070 */
97177 + /*10Ge Statistics Counter */
97178 + uint32_t tfrm_u; /* 80 aFramesTransmittedOK */
97179 + uint32_t tfrm_l; /* 84 aFramesTransmittedOK */
97180 + uint32_t rfrm_u; /* 88 aFramesReceivedOK */
97181 + uint32_t rfrm_l; /* 8c aFramesReceivedOK */
97182 + uint32_t rfcs_u; /* 90 aFrameCheckSequenceErrors */
97183 + uint32_t rfcs_l; /* 94 aFrameCheckSequenceErrors */
97184 + uint32_t raln_u; /* 98 aAlignmentErrors */
97185 + uint32_t raln_l; /* 9c aAlignmentErrors */
97186 + uint32_t txpf_u; /* A0 aPAUSEMACCtrlFramesTransmitted */
97187 + uint32_t txpf_l; /* A4 aPAUSEMACCtrlFramesTransmitted */
97188 + uint32_t rxpf_u; /* A8 aPAUSEMACCtrlFramesReceived */
97189 + uint32_t rxpf_l; /* Ac aPAUSEMACCtrlFramesReceived */
97190 + uint32_t rlong_u; /* B0 aFrameTooLongErrors */
97191 + uint32_t rlong_l; /* B4 aFrameTooLongErrors */
97192 + uint32_t rflr_u; /* B8 aInRangeLengthErrors */
97193 + uint32_t rflr_l; /* Bc aInRangeLengthErrors */
97194 + uint32_t tvlan_u; /* C0 VLANTransmittedOK */
97195 + uint32_t tvlan_l; /* C4 VLANTransmittedOK */
97196 + uint32_t rvlan_u; /* C8 VLANReceivedOK */
97197 + uint32_t rvlan_l; /* Cc VLANReceivedOK */
97198 + uint32_t toct_u; /* D0 ifOutOctets */
97199 + uint32_t toct_l; /* D4 ifOutOctets */
97200 + uint32_t roct_u; /* D8 ifInOctets */
97201 + uint32_t roct_l; /* Dc ifInOctets */
97202 + uint32_t ruca_u; /* E0 ifInUcastPkts */
97203 + uint32_t ruca_l; /* E4 ifInUcastPkts */
97204 + uint32_t rmca_u; /* E8 ifInMulticastPkts */
97205 + uint32_t rmca_l; /* Ec ifInMulticastPkts */
97206 + uint32_t rbca_u; /* F0 ifInBroadcastPkts */
97207 + uint32_t rbca_l; /* F4 ifInBroadcastPkts */
97208 + uint32_t terr_u; /* F8 ifOutErrors */
97209 + uint32_t terr_l; /* Fc ifOutErrors */
97210 + uint32_t reserved100[2]; /* 100-108*/
97211 + uint32_t tuca_u; /* 108 ifOutUcastPkts */
97212 + uint32_t tuca_l; /* 10c ifOutUcastPkts */
97213 + uint32_t tmca_u; /* 110 ifOutMulticastPkts */
97214 + uint32_t tmca_l; /* 114 ifOutMulticastPkts */
97215 + uint32_t tbca_u; /* 118 ifOutBroadcastPkts */
97216 + uint32_t tbca_l; /* 11c ifOutBroadcastPkts */
97217 + uint32_t rdrp_u; /* 120 etherStatsDropEvents */
97218 + uint32_t rdrp_l; /* 124 etherStatsDropEvents */
97219 + uint32_t reoct_u; /* 128 etherStatsOctets */
97220 + uint32_t reoct_l; /* 12c etherStatsOctets */
97221 + uint32_t rpkt_u; /* 130 etherStatsPkts */
97222 + uint32_t rpkt_l; /* 134 etherStatsPkts */
97223 + uint32_t trund_u; /* 138 etherStatsUndersizePkts */
97224 + uint32_t trund_l; /* 13c etherStatsUndersizePkts */
97225 + uint32_t r64_u; /* 140 etherStatsPkts64Octets */
97226 + uint32_t r64_l; /* 144 etherStatsPkts64Octets */
97227 + uint32_t r127_u; /* 148 etherStatsPkts65to127Octets */
97228 + uint32_t r127_l; /* 14c etherStatsPkts65to127Octets */
97229 + uint32_t r255_u; /* 150 etherStatsPkts128to255Octets */
97230 + uint32_t r255_l; /* 154 etherStatsPkts128to255Octets */
97231 + uint32_t r511_u; /* 158 etherStatsPkts256to511Octets */
97232 + uint32_t r511_l; /* 15c etherStatsPkts256to511Octets */
97233 + uint32_t r1023_u; /* 160 etherStatsPkts512to1023Octets */
97234 + uint32_t r1023_l; /* 164 etherStatsPkts512to1023Octets */
97235 + uint32_t r1518_u; /* 168 etherStatsPkts1024to1518Octets */
97236 + uint32_t r1518_l; /* 16c etherStatsPkts1024to1518Octets */
97237 + uint32_t r1519x_u; /* 170 etherStatsPkts1519toX */
97238 + uint32_t r1519x_l; /* 174 etherStatsPkts1519toX */
97239 + uint32_t trovr_u; /* 178 etherStatsOversizePkts */
97240 + uint32_t trovr_l; /* 17c etherStatsOversizePkts */
97241 + uint32_t trjbr_u; /* 180 etherStatsJabbers */
97242 + uint32_t trjbr_l; /* 184 etherStatsJabbers */
97243 + uint32_t trfrg_u; /* 188 etherStatsFragments */
97244 + uint32_t trfrg_l; /* 18C etherStatsFragments */
97245 + uint32_t rerr_u; /* 190 ifInErrors */
97246 + uint32_t rerr_l; /* 194 ifInErrors */
97247 +};
97248 +
97249 +/**
97250 + * struct tgec_cfg - TGEC configuration
97251 + *
97252 + * @rx_error_discard: Receive Erroneous Frame Discard Enable. When set to 1
97253 + * any frame received with an error is discarded in the
97254 + * Core and not forwarded to the Client interface.
97255 + * When set to 0 (Reset value), erroneous Frames are
97256 + * forwarded to the Client interface with ff_rx_err
97257 + * asserted.
97258 + * @pause_ignore: Ignore Pause Frame Quanta. If set to 1 received pause
97259 + * frames are ignored by the MAC. When set to 0
97260 + * (Reset value) the transmit process is stopped for the
97261 + * amount of time specified in the pause quanta received
97262 + * within a pause frame.
97263 + * @pause_forward_enable:
97264 + * Terminate / Forward Pause Frames. If set to 1 pause
97265 + * frames are forwarded to the user application. When set
97266 + * to 0 (Reset value) pause frames are terminated and
97267 + * discarded within the MAC.
97268 + * @no_length_check_enable:
97269 + * Payload Length Check Disable. When set to 0
97270 + * (Reset value), the Core checks the frame's payload
97271 + * length with the Frame Length/Type field, when set to 1
97272 + * the payload length check is disabled.
97273 + * @cmd_frame_enable: Enables reception of all command frames. When set to 1
97274 + * all Command Frames are accepted, when set to 0
97275 + * (Reset Value) only Pause Frames are accepted and all
97276 + * other Command Frames are rejected.
97277 + * @send_idle_enable: Force Idle Generation. When set to 1, the MAC
97278 + * permanently sends XGMII Idle sequences even when faults
97279 + * are received.
97280 + * @wan_mode_enable: WAN Mode Enable. Sets WAN mode (1) or LAN mode
97281 + * (0, default) of operation.
97282 + * @promiscuous_mode_enable:
97283 + * Enables MAC promiscuous operation. When set to 1, all
97284 + * frames are received without any MAC address filtering,
97285 + * when set to 0 (Reset value) Unicast Frames with a
97286 + * destination address not matching the Core MAC Address
97287 + * (MAC Address programmed in Registers MAC_ADDR_0 and
97288 + * MAC_ADDR_1 or the MAC address programmed in Registers
97289 + * MAC_ADDR_2 and MAC_ADDR_3) are rejected.
97290 + * @tx_addr_ins_enable: Set Source MAC Address on Transmit. If set to 1 the
97291 + * MAC overwrites the source MAC address received from the
97292 + * Client Interface with one of the MAC addresses. If set
97293 + * to 0 (Reset value), the source MAC address from the
97294 + * Client Interface is transmitted unmodified to the line.
97295 + * @loopback_enable: PHY Interface Loopback. When set to 1, the signal
97296 + * loop_ena is set to '1', when set to 0 (Reset value)
97297 + * the signal loop_ena is set to 0.
97298 + * @lgth_check_nostdr: The Core interprets the Length/Type field differently
97299 + * depending on the value of this Bit
97300 + * @time_stamp_enable: This bit selects between enabling and disabling the
97301 + * IEEE 1588 functionality. 1: IEEE 1588 is enabled
97302 + * 0: IEEE 1588 is disabled
97303 + * @max_frame_length: Maximum supported received frame length.
97304 + * The 10GEC MAC supports reception of any frame size up
97305 + * to 16,352 bytes (0x3FE0). Typical settings are
97306 + * 0x05EE (1,518 bytes) for standard frames.
97307 + * Default setting is 0x0600 (1,536 bytes).
97308 + * Received frames that exceed this stated maximum
97309 + * are truncated.
97310 + * @pause_quant: Pause quanta value used with transmitted pause frames.
97311 + * Each quanta represents a 512 bit-times.
97312 + * @tx_ipg_length: Transmit Inter-Packet-Gap (IPG) value. A 6-bit value:
97313 + * Depending on LAN or WAN mode of operation the value has
97314 + * the following meaning: - LAN Mode: Number of octets in
97315 + * steps of 4. Valid values are 8, 12, 16, ... 100. DIC is
97316 + * fully supported (see 10.6.1 page 49) for any setting. A
97317 + * default of 12 (reset value) must be set to conform to
97318 + * IEEE802.3ae. Warning: When set to 8, PCS layers may not
97319 + * be able to perform clock rate compensation. - WAN Mode:
97320 + * Stretch factor. Valid values are 4..15. The stretch
97321 + * factor is calculated as (value+1)*8. A default of 12
97322 + * (reset value) must be set to conform to IEEE 802.3ae
97323 + * (i.e. 13*8=104). A larger value shrinks the IPG
97324 + * (increasing bandwidth).
97325 + *
97326 + * This structure contains basic TGEC configuration and must be passed to
97327 + * fman_tgec_init() function. A default set of configuration values can be
97328 + * obtained by calling fman_tgec_defconfig().
97329 + */
97330 +struct tgec_cfg {
97331 + bool rx_error_discard;
97332 + bool pause_ignore;
97333 + bool pause_forward_enable;
97334 + bool no_length_check_enable;
97335 + bool cmd_frame_enable;
97336 + bool send_idle_enable;
97337 + bool wan_mode_enable;
97338 + bool promiscuous_mode_enable;
97339 + bool tx_addr_ins_enable;
97340 + bool loopback_enable;
97341 + bool lgth_check_nostdr;
97342 + bool time_stamp_enable;
97343 + uint16_t max_frame_length;
97344 + uint16_t pause_quant;
97345 + uint32_t tx_ipg_length;
97346 + bool skip_fman11_workaround;
97347 +};
97348 +
97349 +
97350 +void fman_tgec_defconfig(struct tgec_cfg *cfg);
97351 +
97352 +/**
97353 + * fman_tgec_init() - Init tgec hardware block
97354 + * @regs: Pointer to tgec register block
97355 + * @cfg: tgec configuration data
97356 + * @exceptions_mask: initial exceptions mask
97357 + *
97358 + * This function initializes the tgec controller and applies its
97359 + * basic configuration.
97360 + *
97361 + * Returns: 0 if successful, an error code otherwise.
97362 + */
97363 +
97364 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
97365 + uint32_t exception_mask);
97366 +
97367 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
97368 +
97369 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
97370 +
97371 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs);
97372 +
97373 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr);
97374 +
97375 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val);
97376 +
97377 +/**
97378 + * fman_tgec_reset_stat() - Completely resets all TGEC HW counters
97379 + * @regs: Pointer to TGEC register block
97380 + */
97381 +void fman_tgec_reset_stat(struct tgec_regs *regs);
97382 +
97383 +/**
97384 + * fman_tgec_get_counter() - Reads TGEC HW counters
97385 + * @regs: Pointer to TGEC register block
97386 + * @reg_name: Counter name according to the appropriate enum
97387 + *
97388 + * Returns: Required counter value
97389 + */
97390 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs,
97391 + enum tgec_counters reg_name);
97392 +
97393 +/**
97394 + * fman_tgec_set_hash_table() - Sets the Hashtable Control Register
97395 + * @regs: Pointer to TGEC register block
97396 + * @value: Value to be written in Hashtable Control Register
97397 + */
97398 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value);
97399 +
97400 +/**
97401 + * fman_tgec_set_tx_pause_frames() - Sets the Pause Quanta Register
97402 + * @regs: Pointer to TGEC register block
97403 + * @pause_time: Pause quanta value used with transmitted pause frames.
97404 + * Each quanta represents a 512 bit-times
97405 + */
97406 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time);
97407 +
97408 +/**
97409 + * fman_tgec_set_rx_ignore_pause_frames() - Changes the policy WRT pause frames
97410 + * @regs: Pointer to TGEC register block
97411 + * @en: Ignore/Respond to pause frame quanta
97412 + *
97413 + * Sets the value of PAUSE_IGNORE field in the COMMAND_CONFIG Register
97414 + * 0 - MAC stops transmit process for the duration specified
97415 + * in the Pause frame quanta of a received Pause frame.
97416 + * 1 - MAC ignores received Pause frames.
97417 + */
97418 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en);
97419 +
97420 +/**
97421 + * fman_tgec_enable_1588_time_stamp() - change timestamp functionality
97422 + * @regs: Pointer to TGEC register block
97423 + * @en: enable/disable timestamp functionality
97424 + *
97425 + * Sets the value of EN_TIMESTAMP field in the COMMAND_CONFIG Register
97426 + * IEEE 1588 timestamp functionality control:
97427 + * 0 disabled, 1 enabled
97428 + */
97429 +
97430 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en);
97431 +
97432 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask);
97433 +
97434 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask);
97435 +
97436 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs);
97437 +
97438 +/**
97439 + * fman_tgec_add_addr_in_paddr() - Sets additional exact match MAC address
97440 + * @regs: Pointer to TGEC register block
97441 + * @addr_ptr: Pointer to 6-byte array containing the MAC address
97442 + *
97443 + * Sets the additional station MAC address
97444 + */
97445 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr);
97446 +
97447 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs);
97448 +
97449 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
97450 +
97451 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
97452 +
97453 +void fman_tgec_reset_filter_table(struct tgec_regs *regs);
97454 +
97455 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc);
97456 +
97457 +
97458 +/**
97459 + * fman_tgec_get_max_frame_len() - Returns the maximum frame length value
97460 + * @regs: Pointer to TGEC register block
97461 + */
97462 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs);
97463 +
97464 +/**
97465 + * fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007() - Initialize the
97466 + * main tgec configuration parameters
97467 + * @regs: Pointer to TGEC register block
97468 + *
97469 + * TODO
97470 + */
97471 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs
97472 + *regs);
97473 +
97474 +
97475 +#endif /* __FSL_FMAN_TGEC_H */
97476 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
97477 new file mode 100644
97478 index 00000000..0346cf60
97479 --- /dev/null
97480 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
97481 @@ -0,0 +1,291 @@
97482 +/*
97483 + * Copyright 2012 Freescale Semiconductor Inc.
97484 + *
97485 + * Redistribution and use in source and binary forms, with or without
97486 + * modification, are permitted provided that the following conditions are met:
97487 + * * Redistributions of source code must retain the above copyright
97488 + * notice, this list of conditions and the following disclaimer.
97489 + * * Redistributions in binary form must reproduce the above copyright
97490 + * notice, this list of conditions and the following disclaimer in the
97491 + * documentation and/or other materials provided with the distribution.
97492 + * * Neither the name of Freescale Semiconductor nor the
97493 + * names of its contributors may be used to endorse or promote products
97494 + * derived from this software without specific prior written permission.
97495 + *
97496 + *
97497 + * ALTERNATIVELY, this software may be distributed under the terms of the
97498 + * GNU General Public License ("GPL") as published by the Free Software
97499 + * Foundation, either version 2 of that License or (at your option) any
97500 + * later version.
97501 + *
97502 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97503 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97504 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97505 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97506 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97507 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97508 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97509 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97510 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97511 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97512 + */
97513 +
97514 +/**
97515 +
97516 + @File dpaa_integration_ext.h
97517 +
97518 + @Description T4240 FM external definitions and structures.
97519 +*//***************************************************************************/
97520 +#ifndef __DPAA_INTEGRATION_EXT_H
97521 +#define __DPAA_INTEGRATION_EXT_H
97522 +
97523 +#include "std_ext.h"
97524 +
97525 +
97526 +#define DPAA_VERSION 11
97527 +
97528 +/**************************************************************************//**
97529 + @Description DPAA SW Portals Enumeration.
97530 +*//***************************************************************************/
97531 +typedef enum
97532 +{
97533 + e_DPAA_SWPORTAL0 = 0,
97534 + e_DPAA_SWPORTAL1,
97535 + e_DPAA_SWPORTAL2,
97536 + e_DPAA_SWPORTAL3,
97537 + e_DPAA_SWPORTAL4,
97538 + e_DPAA_SWPORTAL5,
97539 + e_DPAA_SWPORTAL6,
97540 + e_DPAA_SWPORTAL7,
97541 + e_DPAA_SWPORTAL8,
97542 + e_DPAA_SWPORTAL9,
97543 + e_DPAA_SWPORTAL10,
97544 + e_DPAA_SWPORTAL11,
97545 + e_DPAA_SWPORTAL12,
97546 + e_DPAA_SWPORTAL13,
97547 + e_DPAA_SWPORTAL14,
97548 + e_DPAA_SWPORTAL15,
97549 + e_DPAA_SWPORTAL16,
97550 + e_DPAA_SWPORTAL17,
97551 + e_DPAA_SWPORTAL18,
97552 + e_DPAA_SWPORTAL19,
97553 + e_DPAA_SWPORTAL20,
97554 + e_DPAA_SWPORTAL21,
97555 + e_DPAA_SWPORTAL22,
97556 + e_DPAA_SWPORTAL23,
97557 + e_DPAA_SWPORTAL24,
97558 + e_DPAA_SWPORTAL_DUMMY_LAST
97559 +} e_DpaaSwPortal;
97560 +
97561 +/**************************************************************************//**
97562 + @Description DPAA Direct Connect Portals Enumeration.
97563 +*//***************************************************************************/
97564 +typedef enum
97565 +{
97566 + e_DPAA_DCPORTAL0 = 0,
97567 + e_DPAA_DCPORTAL1,
97568 + e_DPAA_DCPORTAL2,
97569 + e_DPAA_DCPORTAL_DUMMY_LAST
97570 +} e_DpaaDcPortal;
97571 +
97572 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
97573 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
97574 +
97575 +/*****************************************************************************
97576 + QMan INTEGRATION-SPECIFIC DEFINITIONS
97577 +******************************************************************************/
97578 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
97579 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
97580 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
97581 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
97582 + /**< FQIDs range - 24 bits */
97583 +
97584 +/**************************************************************************//**
97585 + @Description Work Queue Channel assignments in QMan.
97586 +*//***************************************************************************/
97587 +typedef enum
97588 +{
97589 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
97590 + e_QM_FQ_CHANNEL_SWPORTAL1,
97591 + e_QM_FQ_CHANNEL_SWPORTAL2,
97592 + e_QM_FQ_CHANNEL_SWPORTAL3,
97593 + e_QM_FQ_CHANNEL_SWPORTAL4,
97594 + e_QM_FQ_CHANNEL_SWPORTAL5,
97595 + e_QM_FQ_CHANNEL_SWPORTAL6,
97596 + e_QM_FQ_CHANNEL_SWPORTAL7,
97597 + e_QM_FQ_CHANNEL_SWPORTAL8,
97598 + e_QM_FQ_CHANNEL_SWPORTAL9,
97599 + e_QM_FQ_CHANNEL_SWPORTAL10,
97600 + e_QM_FQ_CHANNEL_SWPORTAL11,
97601 + e_QM_FQ_CHANNEL_SWPORTAL12,
97602 + e_QM_FQ_CHANNEL_SWPORTAL13,
97603 + e_QM_FQ_CHANNEL_SWPORTAL14,
97604 + e_QM_FQ_CHANNEL_SWPORTAL15,
97605 + e_QM_FQ_CHANNEL_SWPORTAL16,
97606 + e_QM_FQ_CHANNEL_SWPORTAL17,
97607 + e_QM_FQ_CHANNEL_SWPORTAL18,
97608 + e_QM_FQ_CHANNEL_SWPORTAL19,
97609 + e_QM_FQ_CHANNEL_SWPORTAL20,
97610 + e_QM_FQ_CHANNEL_SWPORTAL21,
97611 + e_QM_FQ_CHANNEL_SWPORTAL22,
97612 + e_QM_FQ_CHANNEL_SWPORTAL23,
97613 + e_QM_FQ_CHANNEL_SWPORTAL24,
97614 +
97615 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
97616 + e_QM_FQ_CHANNEL_POOL2,
97617 + e_QM_FQ_CHANNEL_POOL3,
97618 + e_QM_FQ_CHANNEL_POOL4,
97619 + e_QM_FQ_CHANNEL_POOL5,
97620 + e_QM_FQ_CHANNEL_POOL6,
97621 + e_QM_FQ_CHANNEL_POOL7,
97622 + e_QM_FQ_CHANNEL_POOL8,
97623 + e_QM_FQ_CHANNEL_POOL9,
97624 + e_QM_FQ_CHANNEL_POOL10,
97625 + e_QM_FQ_CHANNEL_POOL11,
97626 + e_QM_FQ_CHANNEL_POOL12,
97627 + e_QM_FQ_CHANNEL_POOL13,
97628 + e_QM_FQ_CHANNEL_POOL14,
97629 + e_QM_FQ_CHANNEL_POOL15,
97630 +
97631 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
97632 + connected to FMan 0; assigned in incrementing order to
97633 + each sub-portal (SP) in the portal */
97634 + e_QM_FQ_CHANNEL_FMAN0_SP1,
97635 + e_QM_FQ_CHANNEL_FMAN0_SP2,
97636 + e_QM_FQ_CHANNEL_FMAN0_SP3,
97637 + e_QM_FQ_CHANNEL_FMAN0_SP4,
97638 + e_QM_FQ_CHANNEL_FMAN0_SP5,
97639 + e_QM_FQ_CHANNEL_FMAN0_SP6,
97640 + e_QM_FQ_CHANNEL_FMAN0_SP7,
97641 + e_QM_FQ_CHANNEL_FMAN0_SP8,
97642 + e_QM_FQ_CHANNEL_FMAN0_SP9,
97643 + e_QM_FQ_CHANNEL_FMAN0_SP10,
97644 + e_QM_FQ_CHANNEL_FMAN0_SP11,
97645 + e_QM_FQ_CHANNEL_FMAN0_SP12,
97646 + e_QM_FQ_CHANNEL_FMAN0_SP13,
97647 + e_QM_FQ_CHANNEL_FMAN0_SP14,
97648 + e_QM_FQ_CHANNEL_FMAN0_SP15,
97649 +
97650 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
97651 + e_QM_FQ_CHANNEL_RMAN_SP1,
97652 +
97653 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
97654 + connected to SEC */
97655 +} e_QmFQChannel;
97656 +
97657 +/*****************************************************************************
97658 + BMan INTEGRATION-SPECIFIC DEFINITIONS
97659 +******************************************************************************/
97660 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
97661 +
97662 +/*****************************************************************************
97663 + SEC INTEGRATION-SPECIFIC DEFINITIONS
97664 +******************************************************************************/
97665 +#define SEC_NUM_OF_DECOS 3
97666 +#define SEC_ALL_DECOS_MASK 0x00000003
97667 +
97668 +
97669 +/*****************************************************************************
97670 + FM INTEGRATION-SPECIFIC DEFINITIONS
97671 +******************************************************************************/
97672 +#define INTG_MAX_NUM_OF_FM 2
97673 +/* Ports defines */
97674 +#define FM_MAX_NUM_OF_1G_MACS 6
97675 +#define FM_MAX_NUM_OF_10G_MACS 2
97676 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
97677 +#define FM_MAX_NUM_OF_OH_PORTS 6
97678 +
97679 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
97680 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
97681 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
97682 +
97683 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
97684 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
97685 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
97686 +
97687 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
97688 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
97689 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
97690 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
97691 +
97692 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
97693 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
97694 +
97695 +/* RAMs defines */
97696 +#define FM_MURAM_SIZE (384 * KILOBYTE)
97697 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
97698 +#define FM_NUM_OF_CTRL 4
97699 +
97700 +/* PCD defines */
97701 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
97702 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
97703 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
97704 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
97705 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
97706 +
97707 +/* RTC defines */
97708 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
97709 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
97710 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
97711 +
97712 +/* QMI defines */
97713 +#define QMI_MAX_NUM_OF_TNUMS 64
97714 +#define QMI_DEF_TNUMS_THRESH 32
97715 +/* FPM defines */
97716 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
97717 +
97718 +/* DMA defines */
97719 +#define DMA_THRESH_MAX_COMMQ 83
97720 +#define DMA_THRESH_MAX_BUF 127
97721 +
97722 +/* BMI defines */
97723 +#define BMI_MAX_NUM_OF_TASKS 128
97724 +#define BMI_MAX_NUM_OF_DMAS 84
97725 +
97726 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
97727 +#define PORT_MAX_WEIGHT 16
97728 +
97729 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
97730 +
97731 +/* Unique T4240 */
97732 +#define FM_OP_OPEN_DMA_MIN_LIMIT
97733 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
97734 +#define FM_NO_OP_OBSERVED_POOLS
97735 +#define FM_FRAME_END_PARAMS_FOR_OP
97736 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
97737 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
97738 +
97739 +#define FM_NO_GUARANTEED_RESET_VALUES
97740 +
97741 +/* FM errata */
97742 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
97743 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
97744 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
97745 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
97746 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
97747 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
97748 +
97749 +#define FM_BCB_ERRATA_BMI_SW001
97750 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
97751 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
97752 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
97753 +
97754 +/*****************************************************************************
97755 + RMan INTEGRATION-SPECIFIC DEFINITIONS
97756 +******************************************************************************/
97757 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
97758 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
97759 +
97760 +/* RMan erratas */
97761 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
97762 +
97763 +/*****************************************************************************
97764 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
97765 +******************************************************************************/
97766 +#define NUM_OF_RX_SC 16
97767 +#define NUM_OF_TX_SC 16
97768 +
97769 +#define NUM_OF_SA_PER_RX_SC 2
97770 +#define NUM_OF_SA_PER_TX_SC 2
97771 +
97772 +#endif /* __DPAA_INTEGRATION_EXT_H */
97773 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
97774 new file mode 100644
97775 index 00000000..0d62dd15
97776 --- /dev/null
97777 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
97778 @@ -0,0 +1,71 @@
97779 +/*
97780 + * Copyright 2012 Freescale Semiconductor Inc.
97781 + *
97782 + * Redistribution and use in source and binary forms, with or without
97783 + * modification, are permitted provided that the following conditions are met:
97784 + * * Redistributions of source code must retain the above copyright
97785 + * notice, this list of conditions and the following disclaimer.
97786 + * * Redistributions in binary form must reproduce the above copyright
97787 + * notice, this list of conditions and the following disclaimer in the
97788 + * documentation and/or other materials provided with the distribution.
97789 + * * Neither the name of Freescale Semiconductor nor the
97790 + * names of its contributors may be used to endorse or promote products
97791 + * derived from this software without specific prior written permission.
97792 + *
97793 + *
97794 + * ALTERNATIVELY, this software may be distributed under the terms of the
97795 + * GNU General Public License ("GPL") as published by the Free Software
97796 + * Foundation, either version 2 of that License or (at your option) any
97797 + * later version.
97798 + *
97799 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97800 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97801 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97802 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97803 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97804 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97805 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97806 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97807 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97808 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97809 + */
97810 +
97811 +/**************************************************************************//**
97812 +
97813 + @File part_ext.h
97814 +
97815 + @Description Definitions for the part (integration) module.
97816 +*//***************************************************************************/
97817 +
97818 +#ifndef __PART_EXT_H
97819 +#define __PART_EXT_H
97820 +
97821 +#include "std_ext.h"
97822 +#include "part_integration_ext.h"
97823 +
97824 +#if !(defined(P1023) || \
97825 + defined(P2041) || \
97826 + defined(P3041) || \
97827 + defined(P4080) || \
97828 + defined(P5020) || \
97829 + defined(P5040) || \
97830 + defined(B4860) || \
97831 + defined(T4240))
97832 +#error "unable to proceed without chip-definition"
97833 +#endif
97834 +
97835 +
97836 +/**************************************************************************//*
97837 + @Description Part data structure - must be contained in any integration
97838 + data structure.
97839 +*//***************************************************************************/
97840 +typedef struct t_Part
97841 +{
97842 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
97843 + /**< Returns the address of the module's memory map base. */
97844 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
97845 + /**< Returns the module's ID according to its memory map base. */
97846 +} t_Part;
97847 +
97848 +
97849 +#endif /* __PART_EXT_H */
97850 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
97851 new file mode 100644
97852 index 00000000..3254c766
97853 --- /dev/null
97854 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
97855 @@ -0,0 +1,304 @@
97856 +/*
97857 + * Copyright 2008-2012 Freescale Semiconductor Inc.
97858 + *
97859 + * Redistribution and use in source and binary forms, with or without
97860 + * modification, are permitted provided that the following conditions are met:
97861 + * * Redistributions of source code must retain the above copyright
97862 + * notice, this list of conditions and the following disclaimer.
97863 + * * Redistributions in binary form must reproduce the above copyright
97864 + * notice, this list of conditions and the following disclaimer in the
97865 + * documentation and/or other materials provided with the distribution.
97866 + * * Neither the name of Freescale Semiconductor nor the
97867 + * names of its contributors may be used to endorse or promote products
97868 + * derived from this software without specific prior written permission.
97869 + *
97870 + *
97871 + * ALTERNATIVELY, this software may be distributed under the terms of the
97872 + * GNU General Public License ("GPL") as published by the Free Software
97873 + * Foundation, either version 2 of that License or (at your option) any
97874 + * later version.
97875 + *
97876 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97877 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97878 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97879 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97880 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97881 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97882 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97883 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97884 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97885 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97886 + */
97887 +
97888 +/**
97889 +
97890 + @File part_integration_ext.h
97891 +
97892 + @Description T4240 external definitions and structures.
97893 +*//***************************************************************************/
97894 +#ifndef __PART_INTEGRATION_EXT_H
97895 +#define __PART_INTEGRATION_EXT_H
97896 +
97897 +#include "std_ext.h"
97898 +#include "ddr_std_ext.h"
97899 +#include "enet_ext.h"
97900 +#include "dpaa_integration_ext.h"
97901 +
97902 +
97903 +/**************************************************************************//**
97904 + @Group T4240_chip_id T4240 Application Programming Interface
97905 +
97906 + @Description T4240 Chip functions,definitions and enums.
97907 +
97908 + @{
97909 +*//***************************************************************************/
97910 +
97911 +#define CORE_E6500
97912 +
97913 +#define INTG_MAX_NUM_OF_CORES 24
97914 +
97915 +
97916 +/**************************************************************************//**
97917 + @Description Module types.
97918 +*//***************************************************************************/
97919 +typedef enum e_ModuleId
97920 +{
97921 + e_MODULE_ID_DUART_1 = 0,
97922 + e_MODULE_ID_DUART_2,
97923 + e_MODULE_ID_DUART_3,
97924 + e_MODULE_ID_DUART_4,
97925 + e_MODULE_ID_LAW,
97926 + e_MODULE_ID_IFC,
97927 + e_MODULE_ID_PAMU,
97928 + e_MODULE_ID_QM, /**< Queue manager module */
97929 + e_MODULE_ID_BM, /**< Buffer manager module */
97930 + e_MODULE_ID_QM_CE_PORTAL_0,
97931 + e_MODULE_ID_QM_CI_PORTAL_0,
97932 + e_MODULE_ID_QM_CE_PORTAL_1,
97933 + e_MODULE_ID_QM_CI_PORTAL_1,
97934 + e_MODULE_ID_QM_CE_PORTAL_2,
97935 + e_MODULE_ID_QM_CI_PORTAL_2,
97936 + e_MODULE_ID_QM_CE_PORTAL_3,
97937 + e_MODULE_ID_QM_CI_PORTAL_3,
97938 + e_MODULE_ID_QM_CE_PORTAL_4,
97939 + e_MODULE_ID_QM_CI_PORTAL_4,
97940 + e_MODULE_ID_QM_CE_PORTAL_5,
97941 + e_MODULE_ID_QM_CI_PORTAL_5,
97942 + e_MODULE_ID_QM_CE_PORTAL_6,
97943 + e_MODULE_ID_QM_CI_PORTAL_6,
97944 + e_MODULE_ID_QM_CE_PORTAL_7,
97945 + e_MODULE_ID_QM_CI_PORTAL_7,
97946 + e_MODULE_ID_QM_CE_PORTAL_8,
97947 + e_MODULE_ID_QM_CI_PORTAL_8,
97948 + e_MODULE_ID_QM_CE_PORTAL_9,
97949 + e_MODULE_ID_QM_CI_PORTAL_9,
97950 + e_MODULE_ID_BM_CE_PORTAL_0,
97951 + e_MODULE_ID_BM_CI_PORTAL_0,
97952 + e_MODULE_ID_BM_CE_PORTAL_1,
97953 + e_MODULE_ID_BM_CI_PORTAL_1,
97954 + e_MODULE_ID_BM_CE_PORTAL_2,
97955 + e_MODULE_ID_BM_CI_PORTAL_2,
97956 + e_MODULE_ID_BM_CE_PORTAL_3,
97957 + e_MODULE_ID_BM_CI_PORTAL_3,
97958 + e_MODULE_ID_BM_CE_PORTAL_4,
97959 + e_MODULE_ID_BM_CI_PORTAL_4,
97960 + e_MODULE_ID_BM_CE_PORTAL_5,
97961 + e_MODULE_ID_BM_CI_PORTAL_5,
97962 + e_MODULE_ID_BM_CE_PORTAL_6,
97963 + e_MODULE_ID_BM_CI_PORTAL_6,
97964 + e_MODULE_ID_BM_CE_PORTAL_7,
97965 + e_MODULE_ID_BM_CI_PORTAL_7,
97966 + e_MODULE_ID_BM_CE_PORTAL_8,
97967 + e_MODULE_ID_BM_CI_PORTAL_8,
97968 + e_MODULE_ID_BM_CE_PORTAL_9,
97969 + e_MODULE_ID_BM_CI_PORTAL_9,
97970 + e_MODULE_ID_FM, /**< Frame manager module */
97971 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
97972 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
97973 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
97974 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
97975 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
97976 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
97977 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
97978 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
97979 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
97980 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
97981 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
97982 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
97983 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
97984 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
97985 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
97986 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
97987 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
97988 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
97989 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
97990 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
97991 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
97992 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
97993 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
97994 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
97995 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
97996 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
97997 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
97998 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
97999 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
98000 + e_MODULE_ID_FM_KG, /**< FM Keygen */
98001 + e_MODULE_ID_FM_DMA, /**< FM DMA */
98002 + e_MODULE_ID_FM_FPM, /**< FM FPM */
98003 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
98004 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
98005 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
98006 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
98007 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
98008 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
98009 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
98010 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
98011 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
98012 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
98013 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
98014 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
98015 +
98016 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
98017 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
98018 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
98019 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
98020 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
98021 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
98022 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
98023 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
98024 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
98025 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
98026 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
98027 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
98028 +
98029 + e_MODULE_ID_PIC, /**< PIC */
98030 + e_MODULE_ID_GPIO, /**< GPIO */
98031 + e_MODULE_ID_SERDES, /**< SERDES */
98032 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
98033 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
98034 +
98035 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
98036 +
98037 + e_MODULE_ID_DUMMY_LAST
98038 +} e_ModuleId;
98039 +
98040 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
98041 +
98042 +#if 0 /* using unified values */
98043 +/*****************************************************************************
98044 + INTEGRATION-SPECIFIC MODULE CODES
98045 +******************************************************************************/
98046 +#define MODULE_UNKNOWN 0x00000000
98047 +#define MODULE_MEM 0x00010000
98048 +#define MODULE_MM 0x00020000
98049 +#define MODULE_CORE 0x00030000
98050 +#define MODULE_T4240 0x00040000
98051 +#define MODULE_T4240_PLATFORM 0x00050000
98052 +#define MODULE_PM 0x00060000
98053 +#define MODULE_MMU 0x00070000
98054 +#define MODULE_PIC 0x00080000
98055 +#define MODULE_CPC 0x00090000
98056 +#define MODULE_DUART 0x000a0000
98057 +#define MODULE_SERDES 0x000b0000
98058 +#define MODULE_PIO 0x000c0000
98059 +#define MODULE_QM 0x000d0000
98060 +#define MODULE_BM 0x000e0000
98061 +#define MODULE_SEC 0x000f0000
98062 +#define MODULE_LAW 0x00100000
98063 +#define MODULE_LBC 0x00110000
98064 +#define MODULE_PAMU 0x00120000
98065 +#define MODULE_FM 0x00130000
98066 +#define MODULE_FM_MURAM 0x00140000
98067 +#define MODULE_FM_PCD 0x00150000
98068 +#define MODULE_FM_RTC 0x00160000
98069 +#define MODULE_FM_MAC 0x00170000
98070 +#define MODULE_FM_PORT 0x00180000
98071 +#define MODULE_FM_SP 0x00190000
98072 +#define MODULE_DPA_PORT 0x001a0000
98073 +#define MODULE_MII 0x001b0000
98074 +#define MODULE_I2C 0x001c0000
98075 +#define MODULE_DMA 0x001d0000
98076 +#define MODULE_DDR 0x001e0000
98077 +#define MODULE_ESPI 0x001f0000
98078 +#define MODULE_DPAA_IPSEC 0x00200000
98079 +#endif /* using unified values */
98080 +
98081 +/*****************************************************************************
98082 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
98083 +******************************************************************************/
98084 +#define PAMU_NUM_OF_PARTITIONS 4
98085 +
98086 +/*****************************************************************************
98087 + LAW INTEGRATION-SPECIFIC DEFINITIONS
98088 +******************************************************************************/
98089 +#define LAW_NUM_OF_WINDOWS 32
98090 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
98091 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
98092 +
98093 +
98094 +/*****************************************************************************
98095 + LBC INTEGRATION-SPECIFIC DEFINITIONS
98096 +******************************************************************************/
98097 +/**************************************************************************//**
98098 + @Group lbc_exception_grp LBC Exception Unit
98099 +
98100 + @Description LBC Exception unit API functions, definitions and enums
98101 +
98102 + @{
98103 +*//***************************************************************************/
98104 +
98105 +/**************************************************************************//**
98106 + @Anchor lbc_exbm
98107 +
98108 + @Collection LBC Errors Bit Mask
98109 +
98110 + These errors are reported through the exceptions callback..
98111 + The values can be or'ed in any combination in the errors mask
98112 + parameter of the errors report structure.
98113 +
98114 + These errors can also be passed as a bit-mask to
98115 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
98116 + for enabling or disabling error checking.
98117 + @{
98118 +*//***************************************************************************/
98119 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
98120 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
98121 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
98122 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
98123 +
98124 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
98125 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
98126 + /**< All possible errors */
98127 +/* @} */
98128 +/** @} */ /* end of lbc_exception_grp group */
98129 +
98130 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
98131 +
98132 +#define LBC_NUM_OF_BANKS 8
98133 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
98134 +#define LBC_PARITY_SUPPORT
98135 +#define LBC_ADDRESS_HOLD_TIME_CTRL
98136 +#define LBC_HIGH_CLK_DIVIDERS
98137 +#define LBC_FCM_AVAILABLE
98138 +
98139 +/*****************************************************************************
98140 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
98141 +******************************************************************************/
98142 +#define GPIO_PORT_OFFSET_0x1000
98143 +
98144 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
98145 + Each port contains up to 32 I/O pins. */
98146 +
98147 +#define GPIO_VALID_PIN_MASKS \
98148 + { /* Port A */ 0xFFFFFFFF, \
98149 + /* Port B */ 0xFFFFFFFF, \
98150 + /* Port C */ 0xFFFFFFFF }
98151 +
98152 +#define GPIO_VALID_INTR_MASKS \
98153 + { /* Port A */ 0xFFFFFFFF, \
98154 + /* Port B */ 0xFFFFFFFF, \
98155 + /* Port C */ 0xFFFFFFFF }
98156 +
98157 +
98158 +
98159 +#endif /* __PART_INTEGRATION_EXT_H */
98160 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
98161 new file mode 100644
98162 index 00000000..f7f8eb07
98163 --- /dev/null
98164 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
98165 @@ -0,0 +1,293 @@
98166 +/*
98167 + * Copyright 2012 Freescale Semiconductor Inc.
98168 + *
98169 + * Redistribution and use in source and binary forms, with or without
98170 + * modification, are permitted provided that the following conditions are met:
98171 + * * Redistributions of source code must retain the above copyright
98172 + * notice, this list of conditions and the following disclaimer.
98173 + * * Redistributions in binary form must reproduce the above copyright
98174 + * notice, this list of conditions and the following disclaimer in the
98175 + * documentation and/or other materials provided with the distribution.
98176 + * * Neither the name of Freescale Semiconductor nor the
98177 + * names of its contributors may be used to endorse or promote products
98178 + * derived from this software without specific prior written permission.
98179 + *
98180 + *
98181 + * ALTERNATIVELY, this software may be distributed under the terms of the
98182 + * GNU General Public License ("GPL") as published by the Free Software
98183 + * Foundation, either version 2 of that License or (at your option) any
98184 + * later version.
98185 + *
98186 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98187 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98188 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98189 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98190 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98191 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98192 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98193 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98194 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98195 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98196 + */
98197 +
98198 +/**
98199 +
98200 + @File dpaa_integration_ext.h
98201 +
98202 + @Description T4240 FM external definitions and structures.
98203 +*//***************************************************************************/
98204 +#ifndef __DPAA_INTEGRATION_EXT_H
98205 +#define __DPAA_INTEGRATION_EXT_H
98206 +
98207 +#include "std_ext.h"
98208 +
98209 +
98210 +#define DPAA_VERSION 11
98211 +
98212 +/**************************************************************************//**
98213 + @Description DPAA SW Portals Enumeration.
98214 +*//***************************************************************************/
98215 +typedef enum
98216 +{
98217 + e_DPAA_SWPORTAL0 = 0,
98218 + e_DPAA_SWPORTAL1,
98219 + e_DPAA_SWPORTAL2,
98220 + e_DPAA_SWPORTAL3,
98221 + e_DPAA_SWPORTAL4,
98222 + e_DPAA_SWPORTAL5,
98223 + e_DPAA_SWPORTAL6,
98224 + e_DPAA_SWPORTAL7,
98225 + e_DPAA_SWPORTAL8,
98226 + e_DPAA_SWPORTAL9,
98227 + e_DPAA_SWPORTAL10,
98228 + e_DPAA_SWPORTAL11,
98229 + e_DPAA_SWPORTAL12,
98230 + e_DPAA_SWPORTAL13,
98231 + e_DPAA_SWPORTAL14,
98232 + e_DPAA_SWPORTAL15,
98233 + e_DPAA_SWPORTAL16,
98234 + e_DPAA_SWPORTAL17,
98235 + e_DPAA_SWPORTAL18,
98236 + e_DPAA_SWPORTAL19,
98237 + e_DPAA_SWPORTAL20,
98238 + e_DPAA_SWPORTAL21,
98239 + e_DPAA_SWPORTAL22,
98240 + e_DPAA_SWPORTAL23,
98241 + e_DPAA_SWPORTAL24,
98242 + e_DPAA_SWPORTAL_DUMMY_LAST
98243 +} e_DpaaSwPortal;
98244 +
98245 +/**************************************************************************//**
98246 + @Description DPAA Direct Connect Portals Enumeration.
98247 +*//***************************************************************************/
98248 +typedef enum
98249 +{
98250 + e_DPAA_DCPORTAL0 = 0,
98251 + e_DPAA_DCPORTAL1,
98252 + e_DPAA_DCPORTAL2,
98253 + e_DPAA_DCPORTAL_DUMMY_LAST
98254 +} e_DpaaDcPortal;
98255 +
98256 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98257 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98258 +
98259 +/*****************************************************************************
98260 + QMan INTEGRATION-SPECIFIC DEFINITIONS
98261 +******************************************************************************/
98262 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
98263 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
98264 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
98265 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
98266 + /**< FQIDs range - 24 bits */
98267 +
98268 +/**************************************************************************//**
98269 + @Description Work Queue Channel assignments in QMan.
98270 +*//***************************************************************************/
98271 +typedef enum
98272 +{
98273 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
98274 + e_QM_FQ_CHANNEL_SWPORTAL1,
98275 + e_QM_FQ_CHANNEL_SWPORTAL2,
98276 + e_QM_FQ_CHANNEL_SWPORTAL3,
98277 + e_QM_FQ_CHANNEL_SWPORTAL4,
98278 + e_QM_FQ_CHANNEL_SWPORTAL5,
98279 + e_QM_FQ_CHANNEL_SWPORTAL6,
98280 + e_QM_FQ_CHANNEL_SWPORTAL7,
98281 + e_QM_FQ_CHANNEL_SWPORTAL8,
98282 + e_QM_FQ_CHANNEL_SWPORTAL9,
98283 + e_QM_FQ_CHANNEL_SWPORTAL10,
98284 + e_QM_FQ_CHANNEL_SWPORTAL11,
98285 + e_QM_FQ_CHANNEL_SWPORTAL12,
98286 + e_QM_FQ_CHANNEL_SWPORTAL13,
98287 + e_QM_FQ_CHANNEL_SWPORTAL14,
98288 + e_QM_FQ_CHANNEL_SWPORTAL15,
98289 + e_QM_FQ_CHANNEL_SWPORTAL16,
98290 + e_QM_FQ_CHANNEL_SWPORTAL17,
98291 + e_QM_FQ_CHANNEL_SWPORTAL18,
98292 + e_QM_FQ_CHANNEL_SWPORTAL19,
98293 + e_QM_FQ_CHANNEL_SWPORTAL20,
98294 + e_QM_FQ_CHANNEL_SWPORTAL21,
98295 + e_QM_FQ_CHANNEL_SWPORTAL22,
98296 + e_QM_FQ_CHANNEL_SWPORTAL23,
98297 + e_QM_FQ_CHANNEL_SWPORTAL24,
98298 +
98299 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
98300 + e_QM_FQ_CHANNEL_POOL2,
98301 + e_QM_FQ_CHANNEL_POOL3,
98302 + e_QM_FQ_CHANNEL_POOL4,
98303 + e_QM_FQ_CHANNEL_POOL5,
98304 + e_QM_FQ_CHANNEL_POOL6,
98305 + e_QM_FQ_CHANNEL_POOL7,
98306 + e_QM_FQ_CHANNEL_POOL8,
98307 + e_QM_FQ_CHANNEL_POOL9,
98308 + e_QM_FQ_CHANNEL_POOL10,
98309 + e_QM_FQ_CHANNEL_POOL11,
98310 + e_QM_FQ_CHANNEL_POOL12,
98311 + e_QM_FQ_CHANNEL_POOL13,
98312 + e_QM_FQ_CHANNEL_POOL14,
98313 + e_QM_FQ_CHANNEL_POOL15,
98314 +
98315 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
98316 + connected to FMan 0; assigned in incrementing order to
98317 + each sub-portal (SP) in the portal */
98318 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98319 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98320 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98321 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98322 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98323 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98324 + e_QM_FQ_CHANNEL_FMAN0_SP7,
98325 + e_QM_FQ_CHANNEL_FMAN0_SP8,
98326 + e_QM_FQ_CHANNEL_FMAN0_SP9,
98327 + e_QM_FQ_CHANNEL_FMAN0_SP10,
98328 + e_QM_FQ_CHANNEL_FMAN0_SP11,
98329 + e_QM_FQ_CHANNEL_FMAN0_SP12,
98330 + e_QM_FQ_CHANNEL_FMAN0_SP13,
98331 + e_QM_FQ_CHANNEL_FMAN0_SP14,
98332 + e_QM_FQ_CHANNEL_FMAN0_SP15,
98333 +
98334 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
98335 + e_QM_FQ_CHANNEL_RMAN_SP1,
98336 +
98337 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
98338 + connected to SEC */
98339 +} e_QmFQChannel;
98340 +
98341 +/*****************************************************************************
98342 + BMan INTEGRATION-SPECIFIC DEFINITIONS
98343 +******************************************************************************/
98344 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
98345 +
98346 +/*****************************************************************************
98347 + SEC INTEGRATION-SPECIFIC DEFINITIONS
98348 +******************************************************************************/
98349 +#define SEC_NUM_OF_DECOS 3
98350 +#define SEC_ALL_DECOS_MASK 0x00000003
98351 +
98352 +
98353 +/*****************************************************************************
98354 + FM INTEGRATION-SPECIFIC DEFINITIONS
98355 +******************************************************************************/
98356 +#define INTG_MAX_NUM_OF_FM 1
98357 +/* Ports defines */
98358 +#define FM_MAX_NUM_OF_1G_MACS 5
98359 +#define FM_MAX_NUM_OF_10G_MACS 1
98360 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
98361 +#define FM_MAX_NUM_OF_OH_PORTS 4
98362 +
98363 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
98364 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
98365 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
98366 +
98367 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
98368 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
98369 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
98370 +
98371 +#define FM_MAX_NUM_OF_MACSECS 1 /* Should be updated */
98372 +
98373 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
98374 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
98375 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
98376 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
98377 +
98378 +#define FM_VSP_MAX_NUM_OF_ENTRIES 32
98379 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
98380 +
98381 +/* RAMs defines */
98382 +#define FM_MURAM_SIZE (192 * KILOBYTE)
98383 +#define FM_IRAM_SIZE(major, minor) \
98384 + (((major == 6) && ((minor == 4) )) ? (64 * KILOBYTE) : (32 * KILOBYTE))
98385 +#define FM_NUM_OF_CTRL 2
98386 +
98387 +/* PCD defines */
98388 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
98389 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
98390 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
98391 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
98392 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
98393 +
98394 +/* RTC defines */
98395 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
98396 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
98397 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
98398 +
98399 +/* QMI defines */
98400 +#define QMI_MAX_NUM_OF_TNUMS 64
98401 +#define QMI_DEF_TNUMS_THRESH 32
98402 +/* FPM defines */
98403 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
98404 +
98405 +/* DMA defines */
98406 +#define DMA_THRESH_MAX_COMMQ 83
98407 +#define DMA_THRESH_MAX_BUF 127
98408 +
98409 +/* BMI defines */
98410 +#define BMI_MAX_NUM_OF_TASKS 64
98411 +#define BMI_MAX_NUM_OF_DMAS 32
98412 +
98413 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
98414 +#define PORT_MAX_WEIGHT 16
98415 +
98416 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
98417 +
98418 +/* Unique T4240 */
98419 +#define FM_OP_OPEN_DMA_MIN_LIMIT
98420 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
98421 +#define FM_NO_OP_OBSERVED_POOLS
98422 +#define FM_FRAME_END_PARAMS_FOR_OP
98423 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98424 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
98425 +
98426 +#define FM_NO_GUARANTEED_RESET_VALUES
98427 +
98428 +/* FM errata */
98429 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
98430 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
98431 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
98432 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
98433 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
98434 +
98435 +#define FM_BCB_ERRATA_BMI_SW001
98436 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
98437 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
98438 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
98439 +
98440 +/*****************************************************************************
98441 + RMan INTEGRATION-SPECIFIC DEFINITIONS
98442 +******************************************************************************/
98443 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
98444 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
98445 +
98446 +/* RMan erratas */
98447 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
98448 +
98449 +/*****************************************************************************
98450 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98451 +******************************************************************************/
98452 +#define NUM_OF_RX_SC 16
98453 +#define NUM_OF_TX_SC 16
98454 +
98455 +#define NUM_OF_SA_PER_RX_SC 2
98456 +#define NUM_OF_SA_PER_TX_SC 2
98457 +
98458 +#endif /* __DPAA_INTEGRATION_EXT_H */
98459 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
98460 new file mode 100644
98461 index 00000000..ba9732ee
98462 --- /dev/null
98463 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
98464 @@ -0,0 +1,59 @@
98465 +/*
98466 + * Copyright 2012 Freescale Semiconductor Inc.
98467 + *
98468 + * Redistribution and use in source and binary forms, with or without
98469 + * modification, are permitted provided that the following conditions are met:
98470 + * * Redistributions of source code must retain the above copyright
98471 + * notice, this list of conditions and the following disclaimer.
98472 + * * Redistributions in binary form must reproduce the above copyright
98473 + * notice, this list of conditions and the following disclaimer in the
98474 + * documentation and/or other materials provided with the distribution.
98475 + * * Neither the name of Freescale Semiconductor nor the
98476 + * names of its contributors may be used to endorse or promote products
98477 + * derived from this software without specific prior written permission.
98478 + *
98479 + *
98480 + * ALTERNATIVELY, this software may be distributed under the terms of the
98481 + * GNU General Public License ("GPL") as published by the Free Software
98482 + * Foundation, either version 2 of that License or (at your option) any
98483 + * later version.
98484 + *
98485 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98486 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98487 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98488 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98489 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98490 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98491 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98492 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98493 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98494 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98495 + */
98496 +
98497 +/**************************************************************************//**
98498 +
98499 + @File part_ext.h
98500 +
98501 + @Description Definitions for the part (integration) module.
98502 +*//***************************************************************************/
98503 +
98504 +#ifndef __PART_EXT_H
98505 +#define __PART_EXT_H
98506 +
98507 +#include "std_ext.h"
98508 +#include "part_integration_ext.h"
98509 +
98510 +/**************************************************************************//*
98511 + @Description Part data structure - must be contained in any integration
98512 + data structure.
98513 +*//***************************************************************************/
98514 +typedef struct t_Part
98515 +{
98516 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
98517 + /**< Returns the address of the module's memory map base. */
98518 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
98519 + /**< Returns the module's ID according to its memory map base. */
98520 +} t_Part;
98521 +
98522 +
98523 +#endif /* __PART_EXT_H */
98524 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
98525 new file mode 100644
98526 index 00000000..3254c766
98527 --- /dev/null
98528 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
98529 @@ -0,0 +1,304 @@
98530 +/*
98531 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98532 + *
98533 + * Redistribution and use in source and binary forms, with or without
98534 + * modification, are permitted provided that the following conditions are met:
98535 + * * Redistributions of source code must retain the above copyright
98536 + * notice, this list of conditions and the following disclaimer.
98537 + * * Redistributions in binary form must reproduce the above copyright
98538 + * notice, this list of conditions and the following disclaimer in the
98539 + * documentation and/or other materials provided with the distribution.
98540 + * * Neither the name of Freescale Semiconductor nor the
98541 + * names of its contributors may be used to endorse or promote products
98542 + * derived from this software without specific prior written permission.
98543 + *
98544 + *
98545 + * ALTERNATIVELY, this software may be distributed under the terms of the
98546 + * GNU General Public License ("GPL") as published by the Free Software
98547 + * Foundation, either version 2 of that License or (at your option) any
98548 + * later version.
98549 + *
98550 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98551 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98552 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98553 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98554 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98555 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98556 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98557 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98558 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98559 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98560 + */
98561 +
98562 +/**
98563 +
98564 + @File part_integration_ext.h
98565 +
98566 + @Description T4240 external definitions and structures.
98567 +*//***************************************************************************/
98568 +#ifndef __PART_INTEGRATION_EXT_H
98569 +#define __PART_INTEGRATION_EXT_H
98570 +
98571 +#include "std_ext.h"
98572 +#include "ddr_std_ext.h"
98573 +#include "enet_ext.h"
98574 +#include "dpaa_integration_ext.h"
98575 +
98576 +
98577 +/**************************************************************************//**
98578 + @Group T4240_chip_id T4240 Application Programming Interface
98579 +
98580 + @Description T4240 Chip functions,definitions and enums.
98581 +
98582 + @{
98583 +*//***************************************************************************/
98584 +
98585 +#define CORE_E6500
98586 +
98587 +#define INTG_MAX_NUM_OF_CORES 24
98588 +
98589 +
98590 +/**************************************************************************//**
98591 + @Description Module types.
98592 +*//***************************************************************************/
98593 +typedef enum e_ModuleId
98594 +{
98595 + e_MODULE_ID_DUART_1 = 0,
98596 + e_MODULE_ID_DUART_2,
98597 + e_MODULE_ID_DUART_3,
98598 + e_MODULE_ID_DUART_4,
98599 + e_MODULE_ID_LAW,
98600 + e_MODULE_ID_IFC,
98601 + e_MODULE_ID_PAMU,
98602 + e_MODULE_ID_QM, /**< Queue manager module */
98603 + e_MODULE_ID_BM, /**< Buffer manager module */
98604 + e_MODULE_ID_QM_CE_PORTAL_0,
98605 + e_MODULE_ID_QM_CI_PORTAL_0,
98606 + e_MODULE_ID_QM_CE_PORTAL_1,
98607 + e_MODULE_ID_QM_CI_PORTAL_1,
98608 + e_MODULE_ID_QM_CE_PORTAL_2,
98609 + e_MODULE_ID_QM_CI_PORTAL_2,
98610 + e_MODULE_ID_QM_CE_PORTAL_3,
98611 + e_MODULE_ID_QM_CI_PORTAL_3,
98612 + e_MODULE_ID_QM_CE_PORTAL_4,
98613 + e_MODULE_ID_QM_CI_PORTAL_4,
98614 + e_MODULE_ID_QM_CE_PORTAL_5,
98615 + e_MODULE_ID_QM_CI_PORTAL_5,
98616 + e_MODULE_ID_QM_CE_PORTAL_6,
98617 + e_MODULE_ID_QM_CI_PORTAL_6,
98618 + e_MODULE_ID_QM_CE_PORTAL_7,
98619 + e_MODULE_ID_QM_CI_PORTAL_7,
98620 + e_MODULE_ID_QM_CE_PORTAL_8,
98621 + e_MODULE_ID_QM_CI_PORTAL_8,
98622 + e_MODULE_ID_QM_CE_PORTAL_9,
98623 + e_MODULE_ID_QM_CI_PORTAL_9,
98624 + e_MODULE_ID_BM_CE_PORTAL_0,
98625 + e_MODULE_ID_BM_CI_PORTAL_0,
98626 + e_MODULE_ID_BM_CE_PORTAL_1,
98627 + e_MODULE_ID_BM_CI_PORTAL_1,
98628 + e_MODULE_ID_BM_CE_PORTAL_2,
98629 + e_MODULE_ID_BM_CI_PORTAL_2,
98630 + e_MODULE_ID_BM_CE_PORTAL_3,
98631 + e_MODULE_ID_BM_CI_PORTAL_3,
98632 + e_MODULE_ID_BM_CE_PORTAL_4,
98633 + e_MODULE_ID_BM_CI_PORTAL_4,
98634 + e_MODULE_ID_BM_CE_PORTAL_5,
98635 + e_MODULE_ID_BM_CI_PORTAL_5,
98636 + e_MODULE_ID_BM_CE_PORTAL_6,
98637 + e_MODULE_ID_BM_CI_PORTAL_6,
98638 + e_MODULE_ID_BM_CE_PORTAL_7,
98639 + e_MODULE_ID_BM_CI_PORTAL_7,
98640 + e_MODULE_ID_BM_CE_PORTAL_8,
98641 + e_MODULE_ID_BM_CI_PORTAL_8,
98642 + e_MODULE_ID_BM_CE_PORTAL_9,
98643 + e_MODULE_ID_BM_CI_PORTAL_9,
98644 + e_MODULE_ID_FM, /**< Frame manager module */
98645 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
98646 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
98647 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
98648 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
98649 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
98650 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
98651 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
98652 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
98653 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
98654 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
98655 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
98656 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
98657 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
98658 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
98659 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
98660 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
98661 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
98662 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
98663 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
98664 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
98665 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
98666 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
98667 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
98668 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
98669 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
98670 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
98671 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
98672 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
98673 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
98674 + e_MODULE_ID_FM_KG, /**< FM Keygen */
98675 + e_MODULE_ID_FM_DMA, /**< FM DMA */
98676 + e_MODULE_ID_FM_FPM, /**< FM FPM */
98677 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
98678 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
98679 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
98680 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
98681 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
98682 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
98683 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
98684 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
98685 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
98686 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
98687 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
98688 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
98689 +
98690 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
98691 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
98692 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
98693 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
98694 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
98695 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
98696 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
98697 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
98698 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
98699 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
98700 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
98701 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
98702 +
98703 + e_MODULE_ID_PIC, /**< PIC */
98704 + e_MODULE_ID_GPIO, /**< GPIO */
98705 + e_MODULE_ID_SERDES, /**< SERDES */
98706 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
98707 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
98708 +
98709 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
98710 +
98711 + e_MODULE_ID_DUMMY_LAST
98712 +} e_ModuleId;
98713 +
98714 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
98715 +
98716 +#if 0 /* using unified values */
98717 +/*****************************************************************************
98718 + INTEGRATION-SPECIFIC MODULE CODES
98719 +******************************************************************************/
98720 +#define MODULE_UNKNOWN 0x00000000
98721 +#define MODULE_MEM 0x00010000
98722 +#define MODULE_MM 0x00020000
98723 +#define MODULE_CORE 0x00030000
98724 +#define MODULE_T4240 0x00040000
98725 +#define MODULE_T4240_PLATFORM 0x00050000
98726 +#define MODULE_PM 0x00060000
98727 +#define MODULE_MMU 0x00070000
98728 +#define MODULE_PIC 0x00080000
98729 +#define MODULE_CPC 0x00090000
98730 +#define MODULE_DUART 0x000a0000
98731 +#define MODULE_SERDES 0x000b0000
98732 +#define MODULE_PIO 0x000c0000
98733 +#define MODULE_QM 0x000d0000
98734 +#define MODULE_BM 0x000e0000
98735 +#define MODULE_SEC 0x000f0000
98736 +#define MODULE_LAW 0x00100000
98737 +#define MODULE_LBC 0x00110000
98738 +#define MODULE_PAMU 0x00120000
98739 +#define MODULE_FM 0x00130000
98740 +#define MODULE_FM_MURAM 0x00140000
98741 +#define MODULE_FM_PCD 0x00150000
98742 +#define MODULE_FM_RTC 0x00160000
98743 +#define MODULE_FM_MAC 0x00170000
98744 +#define MODULE_FM_PORT 0x00180000
98745 +#define MODULE_FM_SP 0x00190000
98746 +#define MODULE_DPA_PORT 0x001a0000
98747 +#define MODULE_MII 0x001b0000
98748 +#define MODULE_I2C 0x001c0000
98749 +#define MODULE_DMA 0x001d0000
98750 +#define MODULE_DDR 0x001e0000
98751 +#define MODULE_ESPI 0x001f0000
98752 +#define MODULE_DPAA_IPSEC 0x00200000
98753 +#endif /* using unified values */
98754 +
98755 +/*****************************************************************************
98756 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
98757 +******************************************************************************/
98758 +#define PAMU_NUM_OF_PARTITIONS 4
98759 +
98760 +/*****************************************************************************
98761 + LAW INTEGRATION-SPECIFIC DEFINITIONS
98762 +******************************************************************************/
98763 +#define LAW_NUM_OF_WINDOWS 32
98764 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
98765 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
98766 +
98767 +
98768 +/*****************************************************************************
98769 + LBC INTEGRATION-SPECIFIC DEFINITIONS
98770 +******************************************************************************/
98771 +/**************************************************************************//**
98772 + @Group lbc_exception_grp LBC Exception Unit
98773 +
98774 + @Description LBC Exception unit API functions, definitions and enums
98775 +
98776 + @{
98777 +*//***************************************************************************/
98778 +
98779 +/**************************************************************************//**
98780 + @Anchor lbc_exbm
98781 +
98782 + @Collection LBC Errors Bit Mask
98783 +
98784 + These errors are reported through the exceptions callback..
98785 + The values can be or'ed in any combination in the errors mask
98786 + parameter of the errors report structure.
98787 +
98788 + These errors can also be passed as a bit-mask to
98789 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
98790 + for enabling or disabling error checking.
98791 + @{
98792 +*//***************************************************************************/
98793 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
98794 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
98795 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
98796 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
98797 +
98798 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
98799 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
98800 + /**< All possible errors */
98801 +/* @} */
98802 +/** @} */ /* end of lbc_exception_grp group */
98803 +
98804 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
98805 +
98806 +#define LBC_NUM_OF_BANKS 8
98807 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
98808 +#define LBC_PARITY_SUPPORT
98809 +#define LBC_ADDRESS_HOLD_TIME_CTRL
98810 +#define LBC_HIGH_CLK_DIVIDERS
98811 +#define LBC_FCM_AVAILABLE
98812 +
98813 +/*****************************************************************************
98814 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
98815 +******************************************************************************/
98816 +#define GPIO_PORT_OFFSET_0x1000
98817 +
98818 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
98819 + Each port contains up to 32 I/O pins. */
98820 +
98821 +#define GPIO_VALID_PIN_MASKS \
98822 + { /* Port A */ 0xFFFFFFFF, \
98823 + /* Port B */ 0xFFFFFFFF, \
98824 + /* Port C */ 0xFFFFFFFF }
98825 +
98826 +#define GPIO_VALID_INTR_MASKS \
98827 + { /* Port A */ 0xFFFFFFFF, \
98828 + /* Port B */ 0xFFFFFFFF, \
98829 + /* Port C */ 0xFFFFFFFF }
98830 +
98831 +
98832 +
98833 +#endif /* __PART_INTEGRATION_EXT_H */
98834 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
98835 new file mode 100644
98836 index 00000000..5a8f3583
98837 --- /dev/null
98838 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
98839 @@ -0,0 +1,291 @@
98840 +/*
98841 + * Copyright 2012 Freescale Semiconductor Inc.
98842 + *
98843 + * Redistribution and use in source and binary forms, with or without
98844 + * modification, are permitted provided that the following conditions are met:
98845 + * * Redistributions of source code must retain the above copyright
98846 + * notice, this list of conditions and the following disclaimer.
98847 + * * Redistributions in binary form must reproduce the above copyright
98848 + * notice, this list of conditions and the following disclaimer in the
98849 + * documentation and/or other materials provided with the distribution.
98850 + * * Neither the name of Freescale Semiconductor nor the
98851 + * names of its contributors may be used to endorse or promote products
98852 + * derived from this software without specific prior written permission.
98853 + *
98854 + *
98855 + * ALTERNATIVELY, this software may be distributed under the terms of the
98856 + * GNU General Public License ("GPL") as published by the Free Software
98857 + * Foundation, either version 2 of that License or (at your option) any
98858 + * later version.
98859 + *
98860 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98861 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98862 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98863 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98864 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98865 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98866 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98867 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98868 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98869 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98870 + */
98871 +
98872 +/**
98873 +
98874 + @File dpaa_integration_ext.h
98875 +
98876 + @Description T4240 FM external definitions and structures.
98877 +*//***************************************************************************/
98878 +#ifndef __DPAA_INTEGRATION_EXT_H
98879 +#define __DPAA_INTEGRATION_EXT_H
98880 +
98881 +#include "std_ext.h"
98882 +
98883 +
98884 +#define DPAA_VERSION 11
98885 +
98886 +/**************************************************************************//**
98887 + @Description DPAA SW Portals Enumeration.
98888 +*//***************************************************************************/
98889 +typedef enum
98890 +{
98891 + e_DPAA_SWPORTAL0 = 0,
98892 + e_DPAA_SWPORTAL1,
98893 + e_DPAA_SWPORTAL2,
98894 + e_DPAA_SWPORTAL3,
98895 + e_DPAA_SWPORTAL4,
98896 + e_DPAA_SWPORTAL5,
98897 + e_DPAA_SWPORTAL6,
98898 + e_DPAA_SWPORTAL7,
98899 + e_DPAA_SWPORTAL8,
98900 + e_DPAA_SWPORTAL9,
98901 + e_DPAA_SWPORTAL10,
98902 + e_DPAA_SWPORTAL11,
98903 + e_DPAA_SWPORTAL12,
98904 + e_DPAA_SWPORTAL13,
98905 + e_DPAA_SWPORTAL14,
98906 + e_DPAA_SWPORTAL15,
98907 + e_DPAA_SWPORTAL16,
98908 + e_DPAA_SWPORTAL17,
98909 + e_DPAA_SWPORTAL18,
98910 + e_DPAA_SWPORTAL19,
98911 + e_DPAA_SWPORTAL20,
98912 + e_DPAA_SWPORTAL21,
98913 + e_DPAA_SWPORTAL22,
98914 + e_DPAA_SWPORTAL23,
98915 + e_DPAA_SWPORTAL24,
98916 + e_DPAA_SWPORTAL_DUMMY_LAST
98917 +} e_DpaaSwPortal;
98918 +
98919 +/**************************************************************************//**
98920 + @Description DPAA Direct Connect Portals Enumeration.
98921 +*//***************************************************************************/
98922 +typedef enum
98923 +{
98924 + e_DPAA_DCPORTAL0 = 0,
98925 + e_DPAA_DCPORTAL1,
98926 + e_DPAA_DCPORTAL2,
98927 + e_DPAA_DCPORTAL_DUMMY_LAST
98928 +} e_DpaaDcPortal;
98929 +
98930 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98931 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98932 +
98933 +/*****************************************************************************
98934 + QMan INTEGRATION-SPECIFIC DEFINITIONS
98935 +******************************************************************************/
98936 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
98937 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
98938 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
98939 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
98940 + /**< FQIDs range - 24 bits */
98941 +
98942 +/**************************************************************************//**
98943 + @Description Work Queue Channel assignments in QMan.
98944 +*//***************************************************************************/
98945 +typedef enum
98946 +{
98947 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
98948 + e_QM_FQ_CHANNEL_SWPORTAL1,
98949 + e_QM_FQ_CHANNEL_SWPORTAL2,
98950 + e_QM_FQ_CHANNEL_SWPORTAL3,
98951 + e_QM_FQ_CHANNEL_SWPORTAL4,
98952 + e_QM_FQ_CHANNEL_SWPORTAL5,
98953 + e_QM_FQ_CHANNEL_SWPORTAL6,
98954 + e_QM_FQ_CHANNEL_SWPORTAL7,
98955 + e_QM_FQ_CHANNEL_SWPORTAL8,
98956 + e_QM_FQ_CHANNEL_SWPORTAL9,
98957 + e_QM_FQ_CHANNEL_SWPORTAL10,
98958 + e_QM_FQ_CHANNEL_SWPORTAL11,
98959 + e_QM_FQ_CHANNEL_SWPORTAL12,
98960 + e_QM_FQ_CHANNEL_SWPORTAL13,
98961 + e_QM_FQ_CHANNEL_SWPORTAL14,
98962 + e_QM_FQ_CHANNEL_SWPORTAL15,
98963 + e_QM_FQ_CHANNEL_SWPORTAL16,
98964 + e_QM_FQ_CHANNEL_SWPORTAL17,
98965 + e_QM_FQ_CHANNEL_SWPORTAL18,
98966 + e_QM_FQ_CHANNEL_SWPORTAL19,
98967 + e_QM_FQ_CHANNEL_SWPORTAL20,
98968 + e_QM_FQ_CHANNEL_SWPORTAL21,
98969 + e_QM_FQ_CHANNEL_SWPORTAL22,
98970 + e_QM_FQ_CHANNEL_SWPORTAL23,
98971 + e_QM_FQ_CHANNEL_SWPORTAL24,
98972 +
98973 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
98974 + e_QM_FQ_CHANNEL_POOL2,
98975 + e_QM_FQ_CHANNEL_POOL3,
98976 + e_QM_FQ_CHANNEL_POOL4,
98977 + e_QM_FQ_CHANNEL_POOL5,
98978 + e_QM_FQ_CHANNEL_POOL6,
98979 + e_QM_FQ_CHANNEL_POOL7,
98980 + e_QM_FQ_CHANNEL_POOL8,
98981 + e_QM_FQ_CHANNEL_POOL9,
98982 + e_QM_FQ_CHANNEL_POOL10,
98983 + e_QM_FQ_CHANNEL_POOL11,
98984 + e_QM_FQ_CHANNEL_POOL12,
98985 + e_QM_FQ_CHANNEL_POOL13,
98986 + e_QM_FQ_CHANNEL_POOL14,
98987 + e_QM_FQ_CHANNEL_POOL15,
98988 +
98989 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
98990 + connected to FMan 0; assigned in incrementing order to
98991 + each sub-portal (SP) in the portal */
98992 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98993 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98994 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98995 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98996 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98997 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98998 + e_QM_FQ_CHANNEL_FMAN0_SP7,
98999 + e_QM_FQ_CHANNEL_FMAN0_SP8,
99000 + e_QM_FQ_CHANNEL_FMAN0_SP9,
99001 + e_QM_FQ_CHANNEL_FMAN0_SP10,
99002 + e_QM_FQ_CHANNEL_FMAN0_SP11,
99003 + e_QM_FQ_CHANNEL_FMAN0_SP12,
99004 + e_QM_FQ_CHANNEL_FMAN0_SP13,
99005 + e_QM_FQ_CHANNEL_FMAN0_SP14,
99006 + e_QM_FQ_CHANNEL_FMAN0_SP15,
99007 +
99008 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
99009 + e_QM_FQ_CHANNEL_RMAN_SP1,
99010 +
99011 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
99012 + connected to SEC */
99013 +} e_QmFQChannel;
99014 +
99015 +/*****************************************************************************
99016 + BMan INTEGRATION-SPECIFIC DEFINITIONS
99017 +******************************************************************************/
99018 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
99019 +
99020 +/*****************************************************************************
99021 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99022 +******************************************************************************/
99023 +#define SEC_NUM_OF_DECOS 3
99024 +#define SEC_ALL_DECOS_MASK 0x00000003
99025 +
99026 +
99027 +/*****************************************************************************
99028 + FM INTEGRATION-SPECIFIC DEFINITIONS
99029 +******************************************************************************/
99030 +#define INTG_MAX_NUM_OF_FM 2
99031 +
99032 +/* Ports defines */
99033 +#define FM_MAX_NUM_OF_1G_MACS 6
99034 +#define FM_MAX_NUM_OF_10G_MACS 2
99035 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
99036 +#define FM_MAX_NUM_OF_OH_PORTS 6
99037 +
99038 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
99039 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
99040 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
99041 +
99042 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
99043 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
99044 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
99045 +
99046 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
99047 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
99048 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
99049 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
99050 +
99051 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
99052 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
99053 +
99054 +/* RAMs defines */
99055 +#define FM_MURAM_SIZE (384 * KILOBYTE)
99056 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
99057 +#define FM_NUM_OF_CTRL 4
99058 +
99059 +/* PCD defines */
99060 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
99061 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
99062 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
99063 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
99064 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
99065 +
99066 +/* RTC defines */
99067 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
99068 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
99069 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
99070 +
99071 +/* QMI defines */
99072 +#define QMI_MAX_NUM_OF_TNUMS 64
99073 +#define QMI_DEF_TNUMS_THRESH 32
99074 +/* FPM defines */
99075 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
99076 +
99077 +/* DMA defines */
99078 +#define DMA_THRESH_MAX_COMMQ 83
99079 +#define DMA_THRESH_MAX_BUF 127
99080 +
99081 +/* BMI defines */
99082 +#define BMI_MAX_NUM_OF_TASKS 128
99083 +#define BMI_MAX_NUM_OF_DMAS 84
99084 +
99085 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
99086 +#define PORT_MAX_WEIGHT 16
99087 +
99088 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
99089 +
99090 +/* Unique T4240 */
99091 +#define FM_OP_OPEN_DMA_MIN_LIMIT
99092 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
99093 +#define FM_NO_OP_OBSERVED_POOLS
99094 +#define FM_FRAME_END_PARAMS_FOR_OP
99095 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
99096 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
99097 +
99098 +#define FM_NO_GUARANTEED_RESET_VALUES
99099 +
99100 +/* FM errata */
99101 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
99102 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
99103 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
99104 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
99105 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
99106 +
99107 +#define FM_BCB_ERRATA_BMI_SW001
99108 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
99109 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
99110 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
99111 +
99112 +/*****************************************************************************
99113 + RMan INTEGRATION-SPECIFIC DEFINITIONS
99114 +******************************************************************************/
99115 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
99116 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
99117 +
99118 +/* RMan erratas */
99119 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
99120 +
99121 +/*****************************************************************************
99122 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
99123 +******************************************************************************/
99124 +#define NUM_OF_RX_SC 16
99125 +#define NUM_OF_TX_SC 16
99126 +
99127 +#define NUM_OF_SA_PER_RX_SC 2
99128 +#define NUM_OF_SA_PER_TX_SC 2
99129 +
99130 +#endif /* __DPAA_INTEGRATION_EXT_H */
99131 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
99132 new file mode 100644
99133 index 00000000..4787e19c
99134 --- /dev/null
99135 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
99136 @@ -0,0 +1,64 @@
99137 +/*
99138 + * Copyright 2012 Freescale Semiconductor Inc.
99139 + *
99140 + * Redistribution and use in source and binary forms, with or without
99141 + * modification, are permitted provided that the following conditions are met:
99142 + * * Redistributions of source code must retain the above copyright
99143 + * notice, this list of conditions and the following disclaimer.
99144 + * * Redistributions in binary form must reproduce the above copyright
99145 + * notice, this list of conditions and the following disclaimer in the
99146 + * documentation and/or other materials provided with the distribution.
99147 + * * Neither the name of Freescale Semiconductor nor the
99148 + * names of its contributors may be used to endorse or promote products
99149 + * derived from this software without specific prior written permission.
99150 + *
99151 + *
99152 + * ALTERNATIVELY, this software may be distributed under the terms of the
99153 + * GNU General Public License ("GPL") as published by the Free Software
99154 + * Foundation, either version 2 of that License or (at your option) any
99155 + * later version.
99156 + *
99157 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99158 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99159 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99160 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99161 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99162 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99163 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99164 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99165 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99166 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99167 + */
99168 +
99169 +/**************************************************************************//**
99170 +
99171 + @File part_ext.h
99172 +
99173 + @Description Definitions for the part (integration) module.
99174 +*//***************************************************************************/
99175 +
99176 +#ifndef __PART_EXT_H
99177 +#define __PART_EXT_H
99178 +
99179 +#include "std_ext.h"
99180 +#include "part_integration_ext.h"
99181 +
99182 +#if !(defined(LS1043))
99183 +#error "unable to proceed without chip-definition"
99184 +#endif
99185 +
99186 +
99187 +/**************************************************************************//*
99188 + @Description Part data structure - must be contained in any integration
99189 + data structure.
99190 +*//***************************************************************************/
99191 +typedef struct t_Part
99192 +{
99193 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99194 + /**< Returns the address of the module's memory map base. */
99195 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
99196 + /**< Returns the module's ID according to its memory map base. */
99197 +} t_Part;
99198 +
99199 +
99200 +#endif /* __PART_EXT_H */
99201 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
99202 new file mode 100644
99203 index 00000000..85ba2a47
99204 --- /dev/null
99205 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
99206 @@ -0,0 +1,185 @@
99207 +/*
99208 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99209 + *
99210 + * Redistribution and use in source and binary forms, with or without
99211 + * modification, are permitted provided that the following conditions are met:
99212 + * * Redistributions of source code must retain the above copyright
99213 + * notice, this list of conditions and the following disclaimer.
99214 + * * Redistributions in binary form must reproduce the above copyright
99215 + * notice, this list of conditions and the following disclaimer in the
99216 + * documentation and/or other materials provided with the distribution.
99217 + * * Neither the name of Freescale Semiconductor nor the
99218 + * names of its contributors may be used to endorse or promote products
99219 + * derived from this software without specific prior written permission.
99220 + *
99221 + *
99222 + * ALTERNATIVELY, this software may be distributed under the terms of the
99223 + * GNU General Public License ("GPL") as published by the Free Software
99224 + * Foundation, either version 2 of that License or (at your option) any
99225 + * later version.
99226 + *
99227 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99228 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99229 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99230 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99231 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99232 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99233 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99234 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99235 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99236 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99237 + */
99238 +
99239 +/**
99240 +
99241 + @File part_integration_ext.h
99242 +
99243 + @Description T4240 external definitions and structures.
99244 +*//***************************************************************************/
99245 +#ifndef __PART_INTEGRATION_EXT_H
99246 +#define __PART_INTEGRATION_EXT_H
99247 +
99248 +#include "std_ext.h"
99249 +#include "ddr_std_ext.h"
99250 +#include "enet_ext.h"
99251 +#include "dpaa_integration_ext.h"
99252 +
99253 +
99254 +/**************************************************************************//**
99255 + @Group T4240_chip_id T4240 Application Programming Interface
99256 +
99257 + @Description T4240 Chip functions,definitions and enums.
99258 +
99259 + @{
99260 +*//***************************************************************************/
99261 +
99262 +#define INTG_MAX_NUM_OF_CORES 4
99263 +
99264 +/**************************************************************************//**
99265 + @Description Module types.
99266 +*//***************************************************************************/
99267 +typedef enum e_ModuleId
99268 +{
99269 + e_MODULE_ID_DUART_1 = 0,
99270 + e_MODULE_ID_DUART_2,
99271 + e_MODULE_ID_DUART_3,
99272 + e_MODULE_ID_DUART_4,
99273 + e_MODULE_ID_LAW,
99274 + e_MODULE_ID_IFC,
99275 + e_MODULE_ID_PAMU,
99276 + e_MODULE_ID_QM, /**< Queue manager module */
99277 + e_MODULE_ID_BM, /**< Buffer manager module */
99278 + e_MODULE_ID_QM_CE_PORTAL_0,
99279 + e_MODULE_ID_QM_CI_PORTAL_0,
99280 + e_MODULE_ID_QM_CE_PORTAL_1,
99281 + e_MODULE_ID_QM_CI_PORTAL_1,
99282 + e_MODULE_ID_QM_CE_PORTAL_2,
99283 + e_MODULE_ID_QM_CI_PORTAL_2,
99284 + e_MODULE_ID_QM_CE_PORTAL_3,
99285 + e_MODULE_ID_QM_CI_PORTAL_3,
99286 + e_MODULE_ID_QM_CE_PORTAL_4,
99287 + e_MODULE_ID_QM_CI_PORTAL_4,
99288 + e_MODULE_ID_QM_CE_PORTAL_5,
99289 + e_MODULE_ID_QM_CI_PORTAL_5,
99290 + e_MODULE_ID_QM_CE_PORTAL_6,
99291 + e_MODULE_ID_QM_CI_PORTAL_6,
99292 + e_MODULE_ID_QM_CE_PORTAL_7,
99293 + e_MODULE_ID_QM_CI_PORTAL_7,
99294 + e_MODULE_ID_QM_CE_PORTAL_8,
99295 + e_MODULE_ID_QM_CI_PORTAL_8,
99296 + e_MODULE_ID_QM_CE_PORTAL_9,
99297 + e_MODULE_ID_QM_CI_PORTAL_9,
99298 + e_MODULE_ID_BM_CE_PORTAL_0,
99299 + e_MODULE_ID_BM_CI_PORTAL_0,
99300 + e_MODULE_ID_BM_CE_PORTAL_1,
99301 + e_MODULE_ID_BM_CI_PORTAL_1,
99302 + e_MODULE_ID_BM_CE_PORTAL_2,
99303 + e_MODULE_ID_BM_CI_PORTAL_2,
99304 + e_MODULE_ID_BM_CE_PORTAL_3,
99305 + e_MODULE_ID_BM_CI_PORTAL_3,
99306 + e_MODULE_ID_BM_CE_PORTAL_4,
99307 + e_MODULE_ID_BM_CI_PORTAL_4,
99308 + e_MODULE_ID_BM_CE_PORTAL_5,
99309 + e_MODULE_ID_BM_CI_PORTAL_5,
99310 + e_MODULE_ID_BM_CE_PORTAL_6,
99311 + e_MODULE_ID_BM_CI_PORTAL_6,
99312 + e_MODULE_ID_BM_CE_PORTAL_7,
99313 + e_MODULE_ID_BM_CI_PORTAL_7,
99314 + e_MODULE_ID_BM_CE_PORTAL_8,
99315 + e_MODULE_ID_BM_CI_PORTAL_8,
99316 + e_MODULE_ID_BM_CE_PORTAL_9,
99317 + e_MODULE_ID_BM_CI_PORTAL_9,
99318 + e_MODULE_ID_FM, /**< Frame manager module */
99319 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99320 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99321 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99322 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99323 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
99324 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99325 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99326 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99327 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99328 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
99329 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
99330 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
99331 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99332 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
99333 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
99334 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
99335 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
99336 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
99337 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
99338 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
99339 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99340 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
99341 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
99342 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
99343 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
99344 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
99345 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
99346 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
99347 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99348 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99349 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99350 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99351 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99352 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
99353 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
99354 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99355 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99356 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
99357 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
99358 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
99359 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
99360 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
99361 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
99362 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
99363 +
99364 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99365 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99366 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99367 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99368 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99369 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99370 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99371 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99372 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99373 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99374 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99375 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99376 +
99377 + e_MODULE_ID_PIC, /**< PIC */
99378 + e_MODULE_ID_GPIO, /**< GPIO */
99379 + e_MODULE_ID_SERDES, /**< SERDES */
99380 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
99381 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
99382 +
99383 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
99384 +
99385 + e_MODULE_ID_DUMMY_LAST
99386 +} e_ModuleId;
99387 +
99388 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99389 +
99390 +
99391 +#endif /* __PART_INTEGRATION_EXT_H */
99392 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
99393 new file mode 100644
99394 index 00000000..7b5390de
99395 --- /dev/null
99396 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
99397 @@ -0,0 +1,213 @@
99398 +/*
99399 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99400 + *
99401 + * Redistribution and use in source and binary forms, with or without
99402 + * modification, are permitted provided that the following conditions are met:
99403 + * * Redistributions of source code must retain the above copyright
99404 + * notice, this list of conditions and the following disclaimer.
99405 + * * Redistributions in binary form must reproduce the above copyright
99406 + * notice, this list of conditions and the following disclaimer in the
99407 + * documentation and/or other materials provided with the distribution.
99408 + * * Neither the name of Freescale Semiconductor nor the
99409 + * names of its contributors may be used to endorse or promote products
99410 + * derived from this software without specific prior written permission.
99411 + *
99412 + *
99413 + * ALTERNATIVELY, this software may be distributed under the terms of the
99414 + * GNU General Public License ("GPL") as published by the Free Software
99415 + * Foundation, either version 2 of that License or (at your option) any
99416 + * later version.
99417 + *
99418 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99419 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99420 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99421 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99422 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99423 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99424 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99425 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99426 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99427 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99428 + */
99429 +
99430 +
99431 +/**
99432 +
99433 + @File dpaa_integration_ext.h
99434 +
99435 + @Description P1023 FM external definitions and structures.
99436 +*//***************************************************************************/
99437 +#ifndef __DPAA_INTEGRATION_EXT_H
99438 +#define __DPAA_INTEGRATION_EXT_H
99439 +
99440 +#include "std_ext.h"
99441 +
99442 +
99443 +#define DPAA_VERSION 10
99444 +
99445 +typedef enum e_DpaaSwPortal {
99446 + e_DPAA_SWPORTAL0 = 0,
99447 + e_DPAA_SWPORTAL1,
99448 + e_DPAA_SWPORTAL2,
99449 + e_DPAA_SWPORTAL_DUMMY_LAST
99450 +} e_DpaaSwPortal;
99451 +
99452 +typedef enum {
99453 + e_DPAA_DCPORTAL0 = 0,
99454 + e_DPAA_DCPORTAL2,
99455 + e_DPAA_DCPORTAL_DUMMY_LAST
99456 +} e_DpaaDcPortal;
99457 +
99458 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
99459 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
99460 +
99461 +/*****************************************************************************
99462 + QMAN INTEGRATION-SPECIFIC DEFINITIONS
99463 +******************************************************************************/
99464 +#define QM_MAX_NUM_OF_POOL_CHANNELS 3
99465 +#define QM_MAX_NUM_OF_WQ 8
99466 +#define QM_MAX_NUM_OF_SWP_AS 2
99467 +#define QM_MAX_NUM_OF_CGS 64
99468 +#define QM_MAX_NUM_OF_FQIDS (16*MEGABYTE)
99469 +
99470 +typedef enum {
99471 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0,
99472 + e_QM_FQ_CHANNEL_SWPORTAL1,
99473 + e_QM_FQ_CHANNEL_SWPORTAL2,
99474 +
99475 + e_QM_FQ_CHANNEL_POOL1 = 0x21,
99476 + e_QM_FQ_CHANNEL_POOL2,
99477 + e_QM_FQ_CHANNEL_POOL3,
99478 +
99479 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40,
99480 + e_QM_FQ_CHANNEL_FMAN0_SP1,
99481 + e_QM_FQ_CHANNEL_FMAN0_SP2,
99482 + e_QM_FQ_CHANNEL_FMAN0_SP3,
99483 + e_QM_FQ_CHANNEL_FMAN0_SP4,
99484 + e_QM_FQ_CHANNEL_FMAN0_SP5,
99485 + e_QM_FQ_CHANNEL_FMAN0_SP6,
99486 +
99487 +
99488 + e_QM_FQ_CHANNEL_CAAM = 0x80
99489 +} e_QmFQChannel;
99490 +
99491 +/*****************************************************************************
99492 + BMAN INTEGRATION-SPECIFIC DEFINITIONS
99493 +******************************************************************************/
99494 +#define BM_MAX_NUM_OF_POOLS 8
99495 +
99496 +/*****************************************************************************
99497 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99498 +******************************************************************************/
99499 +#define SEC_NUM_OF_DECOS 2
99500 +#define SEC_ALL_DECOS_MASK 0x00000003
99501 +#define SEC_RNGB
99502 +#define SEC_NO_ESP_TRAILER_REMOVAL
99503 +
99504 +/*****************************************************************************
99505 + FM INTEGRATION-SPECIFIC DEFINITIONS
99506 +******************************************************************************/
99507 +#define INTG_MAX_NUM_OF_FM 1
99508 +
99509 +/* Ports defines */
99510 +#define FM_MAX_NUM_OF_1G_MACS 2
99511 +#define FM_MAX_NUM_OF_10G_MACS 0
99512 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
99513 +#define FM_MAX_NUM_OF_OH_PORTS 5
99514 +
99515 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
99516 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
99517 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
99518 +
99519 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
99520 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
99521 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
99522 +
99523 +#define FM_MAX_NUM_OF_MACSECS 1
99524 +
99525 +#define FM_MACSEC_SUPPORT
99526 +
99527 +#define FM_LOW_END_RESTRICTION /* prevents the use of TX port 1 with OP port 0 */
99528 +
99529 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
99530 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 2 /**< Number of Offline parsing port external BM pools per Rx port */
99531 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 32 /**< Total number of congestion groups in QM */
99532 +#define FM_MAX_NUM_OF_SUB_PORTALS 7
99533 +
99534 +/* Rams defines */
99535 +#define FM_MURAM_SIZE (64*KILOBYTE)
99536 +#define FM_IRAM_SIZE(major, minor) (32 * KILOBYTE)
99537 +#define FM_NUM_OF_CTRL 2
99538 +
99539 +/* PCD defines */
99540 +#define FM_PCD_PLCR_NUM_ENTRIES 32 /**< Total number of policer profiles */
99541 +#define FM_PCD_KG_NUM_OF_SCHEMES 16 /**< Total number of KG schemes */
99542 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 128 /**< Number of classification plan entries. */
99543 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< Number of bytes saved for patches */
99544 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
99545 +
99546 +/* RTC defines */
99547 +#define FM_RTC_NUM_OF_ALARMS 2
99548 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2
99549 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2
99550 +
99551 +/* QMI defines */
99552 +#define QMI_MAX_NUM_OF_TNUMS 15
99553 +
99554 +/* FPM defines */
99555 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
99556 +
99557 +/* DMA defines */
99558 +#define DMA_THRESH_MAX_COMMQ 15
99559 +#define DMA_THRESH_MAX_BUF 7
99560 +
99561 +/* BMI defines */
99562 +#define BMI_MAX_NUM_OF_TASKS 64
99563 +#define BMI_MAX_NUM_OF_DMAS 16
99564 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
99565 +#define PORT_MAX_WEIGHT 4
99566 +
99567 +/*****************************************************************************
99568 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
99569 +******************************************************************************/
99570 +#define NUM_OF_RX_SC 16
99571 +#define NUM_OF_TX_SC 16
99572 +
99573 +#define NUM_OF_SA_PER_RX_SC 2
99574 +#define NUM_OF_SA_PER_TX_SC 2
99575 +
99576 +/**************************************************************************//**
99577 + @Description Enum for inter-module interrupts registration
99578 +*//***************************************************************************/
99579 +
99580 +/* 1023 unique features */
99581 +#define FM_QMI_NO_ECC_EXCEPTIONS
99582 +#define FM_CSI_CFED_LIMIT
99583 +#define FM_PEDANTIC_DMA
99584 +#define FM_QMI_NO_DEQ_OPTIONS_SUPPORT
99585 +#define FM_FIFO_ALLOCATION_ALG
99586 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
99587 +#define FM_HAS_TOTAL_DMAS
99588 +#define FM_KG_NO_IPPID_SUPPORT
99589 +#define FM_NO_GUARANTEED_RESET_VALUES
99590 +#define FM_MAC_RESET
99591 +
99592 +/* FM erratas */
99593 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
99594 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
99595 +
99596 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
99597 +#define FM_INT_BUF_LEAK_FMAN_A005 /* No implementation, Out of LLD scope. App must avoid S/G */
99598 +
99599 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
99600 +
99601 +/* #define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
99602 +
99603 +/*
99604 +TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle
99605 +TKT038900 - FM dma lockup occur due to AXI slave protocol violation
99606 +*/
99607 +#define FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
99608 +
99609 +
99610 +#endif /* __DPAA_INTEGRATION_EXT_H */
99611 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
99612 new file mode 100644
99613 index 00000000..6814d5fb
99614 --- /dev/null
99615 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
99616 @@ -0,0 +1,82 @@
99617 +/*
99618 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99619 + *
99620 + * Redistribution and use in source and binary forms, with or without
99621 + * modification, are permitted provided that the following conditions are met:
99622 + * * Redistributions of source code must retain the above copyright
99623 + * notice, this list of conditions and the following disclaimer.
99624 + * * Redistributions in binary form must reproduce the above copyright
99625 + * notice, this list of conditions and the following disclaimer in the
99626 + * documentation and/or other materials provided with the distribution.
99627 + * * Neither the name of Freescale Semiconductor nor the
99628 + * names of its contributors may be used to endorse or promote products
99629 + * derived from this software without specific prior written permission.
99630 + *
99631 + *
99632 + * ALTERNATIVELY, this software may be distributed under the terms of the
99633 + * GNU General Public License ("GPL") as published by the Free Software
99634 + * Foundation, either version 2 of that License or (at your option) any
99635 + * later version.
99636 + *
99637 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99638 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99639 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99640 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99641 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99642 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99643 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99644 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99645 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99646 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99647 + */
99648 +
99649 +
99650 +/**************************************************************************//**
99651 +
99652 + @File part_ext.h
99653 +
99654 + @Description Definitions for the part (integration) module.
99655 +*//***************************************************************************/
99656 +
99657 +#ifndef __PART_EXT_H
99658 +#define __PART_EXT_H
99659 +
99660 +#include "std_ext.h"
99661 +#include "part_integration_ext.h"
99662 +
99663 +
99664 +#if !(defined(MPC8306) || \
99665 + defined(MPC8309) || \
99666 + defined(MPC834x) || \
99667 + defined(MPC836x) || \
99668 + defined(MPC832x) || \
99669 + defined(MPC837x) || \
99670 + defined(MPC8568) || \
99671 + defined(MPC8569) || \
99672 + defined(P1020) || \
99673 + defined(P1021) || \
99674 + defined(P1022) || \
99675 + defined(P1023) || \
99676 + defined(P2020) || \
99677 + defined(P3041) || \
99678 + defined(P4080) || \
99679 + defined(P5020) || \
99680 + defined(MSC814x))
99681 +#error "unable to proceed without chip-definition"
99682 +#endif
99683 +
99684 +
99685 +/**************************************************************************//*
99686 + @Description Part data structure - must be contained in any integration
99687 + data structure.
99688 +*//***************************************************************************/
99689 +typedef struct t_Part
99690 +{
99691 + uint64_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99692 + /**< Returns the address of the module's memory map base. */
99693 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uint64_t baseAddress);
99694 + /**< Returns the module's ID according to its memory map base. */
99695 +} t_Part;
99696 +
99697 +
99698 +#endif /* __PART_EXT_H */
99699 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
99700 new file mode 100644
99701 index 00000000..e838283d
99702 --- /dev/null
99703 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
99704 @@ -0,0 +1,635 @@
99705 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
99706 + * All rights reserved.
99707 + *
99708 + * Redistribution and use in source and binary forms, with or without
99709 + * modification, are permitted provided that the following conditions are met:
99710 + * * Redistributions of source code must retain the above copyright
99711 + * notice, this list of conditions and the following disclaimer.
99712 + * * Redistributions in binary form must reproduce the above copyright
99713 + * notice, this list of conditions and the following disclaimer in the
99714 + * documentation and/or other materials provided with the distribution.
99715 + * * Neither the name of Freescale Semiconductor nor the
99716 + * names of its contributors may be used to endorse or promote products
99717 + * derived from this software without specific prior written permission.
99718 + *
99719 + *
99720 + * ALTERNATIVELY, this software may be distributed under the terms of the
99721 + * GNU General Public License ("GPL") as published by the Free Software
99722 + * Foundation, either version 2 of that License or (at your option) any
99723 + * later version.
99724 + *
99725 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99726 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99727 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99728 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99729 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99730 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99731 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99732 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99733 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99734 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99735 + */
99736 +
99737 +/**************************************************************************//**
99738 + @File part_integration_ext.h
99739 +
99740 + @Description P1023 external definitions and structures.
99741 +*//***************************************************************************/
99742 +#ifndef __PART_INTEGRATION_EXT_H
99743 +#define __PART_INTEGRATION_EXT_H
99744 +
99745 +#include "std_ext.h"
99746 +#include "dpaa_integration_ext.h"
99747 +
99748 +
99749 +/**************************************************************************//**
99750 + @Group 1023_chip_id P1023 Application Programming Interface
99751 +
99752 + @Description P1023 Chip functions,definitions and enums.
99753 +
99754 + @{
99755 +*//***************************************************************************/
99756 +
99757 +#define INTG_MAX_NUM_OF_CORES 2
99758 +
99759 +
99760 +/**************************************************************************//**
99761 + @Description Module types.
99762 +*//***************************************************************************/
99763 +typedef enum e_ModuleId
99764 +{
99765 + e_MODULE_ID_LAW, /**< Local Access module */
99766 + e_MODULE_ID_ECM, /**< e500 Coherency Module */
99767 + e_MODULE_ID_DDR, /**< DDR memory controller */
99768 + e_MODULE_ID_I2C_1, /**< I2C 1 */
99769 + e_MODULE_ID_I2C_2, /**< I2C 1 */
99770 + e_MODULE_ID_DUART_1, /**< DUART module 1 */
99771 + e_MODULE_ID_DUART_2, /**< DUART module 2 */
99772 + e_MODULE_ID_LBC, /**< Local bus memory controller module */
99773 + e_MODULE_ID_PCIE_1, /**< PCI Express 1 controller module */
99774 + e_MODULE_ID_PCIE_ATMU_1, /**< PCI 1 ATMU Window */
99775 + e_MODULE_ID_PCIE_2, /**< PCI Express 2 controller module */
99776 + e_MODULE_ID_PCIE_ATMU_2, /**< PCI 2 ATMU Window */
99777 + e_MODULE_ID_PCIE_3, /**< PCI Express 3 controller module */
99778 + e_MODULE_ID_PCIE_ATMU_3, /**< PCI 3 ATMU Window */
99779 + e_MODULE_ID_MSI, /**< MSI registers */
99780 + e_MODULE_ID_L2_SRAM, /**< L2/SRAM Memory-Mapped controller module */
99781 + e_MODULE_ID_DMA_1, /**< DMA controller 1 */
99782 + e_MODULE_ID_DMA_2, /**< DMA controller 2 */
99783 + e_MODULE_ID_EPIC, /**< Programmable interrupt controller */
99784 + e_MODULE_ID_ESPI, /**< ESPI module */
99785 + e_MODULE_ID_GPIO, /**< General Purpose I/O */
99786 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99787 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99788 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99789 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99790 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99791 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99792 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99793 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99794 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99795 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99796 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99797 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99798 + e_MODULE_ID_USB_DR_1, /**< USB 2.0 module 1 */
99799 + e_MODULE_ID_USB_DR_2, /**< USB 2.0 module 2 */
99800 + e_MODULE_ID_ETSEC_MII_MNG, /**< MII MNG registers */
99801 + e_MODULE_ID_ETSEC_1, /**< ETSEC module 1 */
99802 + e_MODULE_ID_ETSEC_2, /**< ETSEC module 2 */
99803 + e_MODULE_ID_GUTS, /**< Serial DMA */
99804 + e_MODULE_ID_PM, /**< Performance Monitor module */
99805 + e_MODULE_ID_QM, /**< Queue manager module */
99806 + e_MODULE_ID_BM, /**< Buffer manager module */
99807 + e_MODULE_ID_QM_CE_PORTAL,
99808 + e_MODULE_ID_QM_CI_PORTAL,
99809 + e_MODULE_ID_BM_CE_PORTAL,
99810 + e_MODULE_ID_BM_CI_PORTAL,
99811 + e_MODULE_ID_FM, /**< Frame manager #1 module */
99812 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99813 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99814 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99815 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99816 + e_MODULE_ID_FM_PRS, /**< FM parser block */
99817 + e_MODULE_ID_FM_PORT_HO0, /**< FM Host-command/offline-parsing port block */
99818 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99819 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99820 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99821 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99822 + e_MODULE_ID_FM_PORT_1GRx0, /**< FM Rx 1G MAC port block */
99823 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99824 + e_MODULE_ID_FM_PORT_1GTx0, /**< FM Tx 1G MAC port block */
99825 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99826 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99827 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99828 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99829 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99830 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99831 + e_MODULE_ID_FM_1GMDIO0, /**< FM 1G MDIO MAC 0*/
99832 + e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
99833 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99834 + e_MODULE_ID_FM_RISC0, /**< FM risc #0 */
99835 + e_MODULE_ID_FM_RISC1, /**< FM risc #1 */
99836 + e_MODULE_ID_FM_1GMAC0, /**< FM 1G MAC #0 */
99837 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99838 + e_MODULE_ID_FM_MACSEC, /**< FM MACSEC */
99839 +
99840 + e_MODULE_ID_DUMMY_LAST
99841 +} e_ModuleId;
99842 +
99843 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99844 +
99845 +
99846 +#define P1023_OFFSET_LAW 0x00000C08
99847 +#define P1023_OFFSET_ECM 0x00001000
99848 +#define P1023_OFFSET_DDR 0x00002000
99849 +#define P1023_OFFSET_I2C1 0x00003000
99850 +#define P1023_OFFSET_I2C2 0x00003100
99851 +#define P1023_OFFSET_DUART1 0x00004500
99852 +#define P1023_OFFSET_DUART2 0x00004600
99853 +#define P1023_OFFSET_LBC 0x00005000
99854 +#define P1023_OFFSET_ESPI 0x00007000
99855 +#define P1023_OFFSET_PCIE2 0x00009000
99856 +#define P1023_OFFSET_PCIE2_ATMU 0x00009C00
99857 +#define P1023_OFFSET_PCIE1 0x0000A000
99858 +#define P1023_OFFSET_PCIE1_ATMU 0x0000AC00
99859 +#define P1023_OFFSET_PCIE3 0x0000B000
99860 +#define P1023_OFFSET_PCIE3_ATMU 0x0000BC00
99861 +#define P1023_OFFSET_DMA2 0x0000C100
99862 +#define P1023_OFFSET_GPIO 0x0000F000
99863 +#define P1023_OFFSET_L2_SRAM 0x00020000
99864 +#define P1023_OFFSET_DMA1 0x00021100
99865 +#define P1023_OFFSET_USB1 0x00022000
99866 +#define P1023_OFFSET_SEC_GEN 0x00030000
99867 +#define P1023_OFFSET_SEC_JQ0 0x00031000
99868 +#define P1023_OFFSET_SEC_JQ1 0x00032000
99869 +#define P1023_OFFSET_SEC_JQ2 0x00033000
99870 +#define P1023_OFFSET_SEC_JQ3 0x00034000
99871 +#define P1023_OFFSET_SEC_RTIC 0x00036000
99872 +#define P1023_OFFSET_SEC_QI 0x00037000
99873 +#define P1023_OFFSET_SEC_DECO0_CCB0 0x00038000
99874 +#define P1023_OFFSET_SEC_DECO1_CCB1 0x00039000
99875 +#define P1023_OFFSET_SEC_DECO2_CCB2 0x0003a000
99876 +#define P1023_OFFSET_SEC_DECO3_CCB3 0x0003b000
99877 +#define P1023_OFFSET_SEC_DECO4_CCB4 0x0003c000
99878 +#define P1023_OFFSET_PIC 0x00040000
99879 +#define P1023_OFFSET_MSI 0x00041600
99880 +#define P1023_OFFSET_AXI 0x00081000
99881 +#define P1023_OFFSET_QM 0x00088000
99882 +#define P1023_OFFSET_BM 0x0008A000
99883 +#define P1022_OFFSET_PM 0x000E1000
99884 +
99885 +#define P1023_OFFSET_GUTIL 0x000E0000
99886 +#define P1023_OFFSET_PM 0x000E1000
99887 +#define P1023_OFFSET_DEBUG 0x000E2000
99888 +#define P1023_OFFSET_SERDES 0x000E3000
99889 +#define P1023_OFFSET_ROM 0x000F0000
99890 +#define P1023_OFFSET_FM 0x00100000
99891 +
99892 +#define P1023_OFFSET_FM_MURAM (P1023_OFFSET_FM + 0x00000000)
99893 +#define P1023_OFFSET_FM_BMI (P1023_OFFSET_FM + 0x00080000)
99894 +#define P1023_OFFSET_FM_QMI (P1023_OFFSET_FM + 0x00080400)
99895 +#define P1023_OFFSET_FM_PRS (P1023_OFFSET_FM + 0x00080800)
99896 +#define P1023_OFFSET_FM_PORT_HO0 (P1023_OFFSET_FM + 0x00081000)
99897 +#define P1023_OFFSET_FM_PORT_HO1 (P1023_OFFSET_FM + 0x00082000)
99898 +#define P1023_OFFSET_FM_PORT_HO2 (P1023_OFFSET_FM + 0x00083000)
99899 +#define P1023_OFFSET_FM_PORT_HO3 (P1023_OFFSET_FM + 0x00084000)
99900 +#define P1023_OFFSET_FM_PORT_HO4 (P1023_OFFSET_FM + 0x00085000)
99901 +#define P1023_OFFSET_FM_PORT_1GRX0 (P1023_OFFSET_FM + 0x00088000)
99902 +#define P1023_OFFSET_FM_PORT_1GRX1 (P1023_OFFSET_FM + 0x00089000)
99903 +#define P1023_OFFSET_FM_PORT_1GTX0 (P1023_OFFSET_FM + 0x000A8000)
99904 +#define P1023_OFFSET_FM_PORT_1GTX1 (P1023_OFFSET_FM + 0x000A9000)
99905 +#define P1023_OFFSET_FM_PLCR (P1023_OFFSET_FM + 0x000C0000)
99906 +#define P1023_OFFSET_FM_KG (P1023_OFFSET_FM + 0x000C1000)
99907 +#define P1023_OFFSET_FM_DMA (P1023_OFFSET_FM + 0x000C2000)
99908 +#define P1023_OFFSET_FM_FPM (P1023_OFFSET_FM + 0x000C3000)
99909 +#define P1023_OFFSET_FM_IRAM (P1023_OFFSET_FM + 0x000C4000)
99910 +#define P1023_OFFSET_FM_PRS_IRAM (P1023_OFFSET_FM + 0x000C7000)
99911 +#define P1023_OFFSET_FM_RISC0 (P1023_OFFSET_FM + 0x000D0000)
99912 +#define P1023_OFFSET_FM_RISC1 (P1023_OFFSET_FM + 0x000D0400)
99913 +#define P1023_OFFSET_FM_MACSEC (P1023_OFFSET_FM + 0x000D8000)
99914 +#define P1023_OFFSET_FM_1GMAC0 (P1023_OFFSET_FM + 0x000E0000)
99915 +#define P1023_OFFSET_FM_1GMDIO0 (P1023_OFFSET_FM + 0x000E1120)
99916 +#define P1023_OFFSET_FM_1GMAC1 (P1023_OFFSET_FM + 0x000E2000)
99917 +#define P1023_OFFSET_FM_1GMDIO1 (P1023_OFFSET_FM + 0x000E3000)
99918 +#define P1023_OFFSET_FM_RTC (P1023_OFFSET_FM + 0x000FE000)
99919 +
99920 +/* Offsets relative to QM or BM portals base */
99921 +#define P1023_OFFSET_PORTALS_CE_AREA 0x00000000 /* cache enabled area */
99922 +#define P1023_OFFSET_PORTALS_CI_AREA 0x00100000 /* cache inhibited area */
99923 +
99924 +#define P1023_OFFSET_PORTALS_CE(portal) (P1023_OFFSET_PORTALS_CE_AREA + 0x4000 * (portal))
99925 +#define P1023_OFFSET_PORTALS_CI(portal) (P1023_OFFSET_PORTALS_CI_AREA + 0x1000 * (portal))
99926 +
99927 +/**************************************************************************//**
99928 + @Description Transaction source ID (for memory controllers error reporting).
99929 +*//***************************************************************************/
99930 +typedef enum e_TransSrc
99931 +{
99932 + e_TRANS_SRC_PCIE_2 = 0x01, /**< PCIe port 2 */
99933 + e_TRANS_SRC_PCIE_1 = 0x02, /**< PCIe port 1 */
99934 + e_TRANS_SRC_PCIE_3 = 0x03, /**< PCIe port 3 */
99935 + e_TRANS_SRC_LBC = 0x04, /**< Enhanced local bus */
99936 + e_TRANS_SRC_DPAA_SW_PORTALS = 0x0E, /**< DPAA software portals or SRAM */
99937 + e_TRANS_SRC_DDR = 0x0F, /**< DDR controller */
99938 + e_TRANS_SRC_CORE_INS_FETCH = 0x10, /**< Processor (instruction) */
99939 + e_TRANS_SRC_CORE_DATA = 0x11, /**< Processor (data) */
99940 + e_TRANS_SRC_DMA = 0x15 /**< DMA */
99941 +} e_TransSrc;
99942 +
99943 +/**************************************************************************//**
99944 + @Description Local Access Window Target interface ID
99945 +*//***************************************************************************/
99946 +typedef enum e_P1023LawTargetId
99947 +{
99948 + e_P1023_LAW_TARGET_PCIE_2 = 0x01, /**< PCI Express 2 target interface */
99949 + e_P1023_LAW_TARGET_PCIE_1 = 0x02, /**< PCI Express 1 target interface */
99950 + e_P1023_LAW_TARGET_PCIE_3 = 0x03, /**< PCI Express 3 target interface */
99951 + e_P1023_LAW_TARGET_LBC = 0x04, /**< Local bus target interface */
99952 + e_P1023_LAW_TARGET_QM_PORTALS = 0x0E, /**< Queue Manager Portals */
99953 + e_P1023_LAW_TARGET_BM_PORTALS = 0x0E, /**< Buffer Manager Portals */
99954 + e_P1023_LAW_TARGET_SRAM = 0x0E, /**< SRAM scratchpad */
99955 + e_P1023_LAW_TARGET_DDR = 0x0F, /**< DDR target interface */
99956 + e_P1023_LAW_TARGET_NONE = 0xFF /**< Invalid target interface */
99957 +} e_P1023LawTargetId;
99958 +
99959 +
99960 +/**************************************************************************//**
99961 + @Group 1023_init_grp P1023 Initialization Unit
99962 +
99963 + @Description P1023 initialization unit API functions, definitions and enums
99964 +
99965 + @{
99966 +*//***************************************************************************/
99967 +
99968 +/**************************************************************************//**
99969 + @Description Part ID and revision number
99970 +*//***************************************************************************/
99971 +typedef enum e_P1023DeviceName
99972 +{
99973 + e_P1023_REV_INVALID = 0x00000000, /**< Invalid revision */
99974 + e_SC1023_REV_1_0 = (int)0x80FC0010, /**< SC1023 rev 1.0 */
99975 + e_SC1023_REV_1_1 = (int)0x80FC0011, /**< SC1023 rev 1.1 */
99976 + e_P1023_REV_1_0 = (int)0x80FE0010, /**< P1023 rev 1.0 with security */
99977 + e_P1023_REV_1_1 = (int)0x80FE0011, /**< P1023 rev 1.1 with security */
99978 + e_P1017_REV_1_1 = (int)0x80FF0011, /**< P1017 rev 1.1 with security */
99979 + e_P1023_REV_1_0_NO_SEC = (int)0x80F60010, /**< P1023 rev 1.0 without security */
99980 + e_P1023_REV_1_1_NO_SEC = (int)0x80F60011, /**< P1023 rev 1.1 without security */
99981 + e_P1017_REV_1_1_NO_SEC = (int)0x80F70011 /**< P1017 rev 1.1 without security */
99982 +} e_P1023DeviceName;
99983 +
99984 +/**************************************************************************//**
99985 + @Description structure representing P1023 initialization parameters
99986 +*//***************************************************************************/
99987 +typedef struct t_P1023Params
99988 +{
99989 + uintptr_t ccsrBaseAddress; /**< CCSR base address (virtual) */
99990 + uintptr_t bmPortalsBaseAddress; /**< Portals base address (virtual) */
99991 + uintptr_t qmPortalsBaseAddress; /**< Portals base address (virtual) */
99992 +} t_P1023Params;
99993 +
99994 +/**************************************************************************//**
99995 + @Function P1023_ConfigAndInit
99996 +
99997 + @Description General initiation of the chip registers.
99998 +
99999 + @Param[in] p_P1023Params - A pointer to data structure of parameters
100000 +
100001 + @Return A handle to the P1023 data structure.
100002 +*//***************************************************************************/
100003 +t_Handle P1023_ConfigAndInit(t_P1023Params *p_P1023Params);
100004 +
100005 +/**************************************************************************//**
100006 + @Function P1023_Free
100007 +
100008 + @Description Free all resources.
100009 +
100010 + @Param h_P1023 - (In) The handle of the initialized P1023 object.
100011 +
100012 + @Return E_OK on success; Other value otherwise.
100013 +*//***************************************************************************/
100014 +t_Error P1023_Free(t_Handle h_P1023);
100015 +
100016 +/**************************************************************************//**
100017 + @Function P1023_GetRevInfo
100018 +
100019 + @Description This routine enables access to chip and revision information.
100020 +
100021 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100022 +
100023 + @Return Part ID and revision.
100024 +*//***************************************************************************/
100025 +e_P1023DeviceName P1023_GetRevInfo(uintptr_t gutilBase);
100026 +
100027 +/**************************************************************************//**
100028 + @Function P1023_GetE500Factor
100029 +
100030 + @Description Returns E500 core clock multiplication factor.
100031 +
100032 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100033 + @Param[in] coreId - Id of the requested core.
100034 + @Param[out] p_E500MulFactor - Returns E500 to CCB multification factor.
100035 + @Param[out] p_E500DivFactor - Returns E500 to CCB division factor.
100036 +
100037 + @Return E_OK on success; Other value otherwise.
100038 +*
100039 +*//***************************************************************************/
100040 +t_Error P1023_GetE500Factor(uintptr_t gutilBase,
100041 + uint32_t coreId,
100042 + uint32_t *p_E500MulFactor,
100043 + uint32_t *p_E500DivFactor);
100044 +
100045 +/**************************************************************************//**
100046 + @Function P1023_GetFmFactor
100047 +
100048 + @Description returns FM multiplication factors. (This value is returned using
100049 + two parameters to avoid using float parameter).
100050 +
100051 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100052 + @Param[out] p_FmMulFactor - returns E500 to CCB multification factor.
100053 + @Param[out] p_FmDivFactor - returns E500 to CCB division factor.
100054 +
100055 + @Return E_OK on success; Other value otherwise.
100056 +*//***************************************************************************/
100057 +t_Error P1023_GetFmFactor(uintptr_t gutilBase, uint32_t *p_FmMulFactor, uint32_t *p_FmDivFactor);
100058 +
100059 +/**************************************************************************//**
100060 + @Function P1023_GetCcbFactor
100061 +
100062 + @Description returns system multiplication factor.
100063 +
100064 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100065 +
100066 + @Return System multiplication factor.
100067 +*//***************************************************************************/
100068 +uint32_t P1023_GetCcbFactor(uintptr_t gutilBase);
100069 +
100070 +#if 0
100071 +/**************************************************************************//**
100072 + @Function P1023_GetDdrFactor
100073 +
100074 + @Description returns the multiplication factor of the clock in for the DDR clock .
100075 + Note: assumes the ddr_in_clk is identical to the sys_in_clk
100076 +
100077 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100078 + @Param p_DdrMulFactor - returns DDR in clk multification factor.
100079 + @Param p_DdrDivFactor - returns DDR division factor.
100080 +
100081 + @Return E_OK on success; Other value otherwise..
100082 +*//***************************************************************************/
100083 +t_Error P1023_GetDdrFactor( uintptr_t gutilBase,
100084 + uint32_t *p_DdrMulFactor,
100085 + uint32_t *p_DdrDivFactor);
100086 +
100087 +/**************************************************************************//**
100088 + @Function P1023_GetDdrType
100089 +
100090 + @Description returns the multiplication factor of the clock in for the DDR clock .
100091 +
100092 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100093 + @Param p_DdrType - (Out) returns DDR type DDR1/DDR2/DDR3.
100094 +
100095 + @Return E_OK on success; Other value otherwise.
100096 +*//***************************************************************************/
100097 +t_Error P1023_GetDdrType(uintptr_t gutilBase, e_DdrType *p_DdrType );
100098 +#endif
100099 +
100100 +/** @} */ /* end of 1023_init_grp group */
100101 +/** @} */ /* end of 1023_grp group */
100102 +
100103 +#define CORE_E500V2
100104 +
100105 +#if 0 /* using unified values */
100106 +/*****************************************************************************
100107 + INTEGRATION-SPECIFIC MODULE CODES
100108 +******************************************************************************/
100109 +#define MODULE_UNKNOWN 0x00000000
100110 +#define MODULE_MEM 0x00010000
100111 +#define MODULE_MM 0x00020000
100112 +#define MODULE_CORE 0x00030000
100113 +#define MODULE_P1023 0x00040000
100114 +#define MODULE_MII 0x00050000
100115 +#define MODULE_PM 0x00060000
100116 +#define MODULE_MMU 0x00070000
100117 +#define MODULE_PIC 0x00080000
100118 +#define MODULE_L2_CACHE 0x00090000
100119 +#define MODULE_DUART 0x000a0000
100120 +#define MODULE_SERDES 0x000b0000
100121 +#define MODULE_PIO 0x000c0000
100122 +#define MODULE_QM 0x000d0000
100123 +#define MODULE_BM 0x000e0000
100124 +#define MODULE_SEC 0x000f0000
100125 +#define MODULE_FM 0x00100000
100126 +#define MODULE_FM_MURAM 0x00110000
100127 +#define MODULE_FM_PCD 0x00120000
100128 +#define MODULE_FM_RTC 0x00130000
100129 +#define MODULE_FM_MAC 0x00140000
100130 +#define MODULE_FM_PORT 0x00150000
100131 +#define MODULE_FM_MACSEC 0x00160000
100132 +#define MODULE_FM_MACSEC_SECY 0x00170000
100133 +#define MODULE_FM_SP 0x00280000
100134 +#define MODULE_ECM 0x00190000
100135 +#define MODULE_DMA 0x001a0000
100136 +#define MODULE_DDR 0x001b0000
100137 +#define MODULE_LAW 0x001c0000
100138 +#define MODULE_LBC 0x001d0000
100139 +#define MODULE_I2C 0x001e0000
100140 +#define MODULE_ESPI 0x001f0000
100141 +#define MODULE_PCI 0x00200000
100142 +#define MODULE_DPA_PORT 0x00210000
100143 +#define MODULE_USB 0x00220000
100144 +#endif /* using unified values */
100145 +
100146 +/*****************************************************************************
100147 + LBC INTEGRATION-SPECIFIC DEFINITIONS
100148 +******************************************************************************/
100149 +/**************************************************************************//**
100150 + @Group lbc_exception_grp LBC Exception Unit
100151 +
100152 + @Description LBC Exception unit API functions, definitions and enums
100153 +
100154 + @{
100155 +*//***************************************************************************/
100156 +
100157 +/**************************************************************************//**
100158 + @Anchor lbc_exbm
100159 +
100160 + @Collection LBC Errors Bit Mask
100161 +
100162 + These errors are reported through the exceptions callback..
100163 + The values can be or'ed in any combination in the errors mask
100164 + parameter of the errors report structure.
100165 +
100166 + These errors can also be passed as a bit-mask to
100167 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
100168 + for enabling or disabling error checking.
100169 + @{
100170 +*//***************************************************************************/
100171 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
100172 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
100173 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
100174 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
100175 +
100176 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
100177 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
100178 + /**< All possible errors */
100179 +/* @} */
100180 +/** @} */ /* end of lbc_exception_grp group */
100181 +
100182 +#define LBC_NUM_OF_BANKS 2
100183 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
100184 +#define LBC_ATOMIC_OPERATION_SUPPORT
100185 +#define LBC_PARITY_SUPPORT
100186 +#define LBC_ADDRESS_SHIFT_SUPPORT
100187 +#define LBC_ADDRESS_HOLD_TIME_CTRL
100188 +#define LBC_HIGH_CLK_DIVIDERS
100189 +#define LBC_FCM_AVAILABLE
100190 +
100191 +
100192 +/*****************************************************************************
100193 + LAW INTEGRATION-SPECIFIC DEFINITIONS
100194 +******************************************************************************/
100195 +#define LAW_ARCH_CCB
100196 +#define LAW_NUM_OF_WINDOWS 12
100197 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
100198 +#define LAW_MAX_WINDOW_SIZE 0x0000001000000000LL /**< 32GB */
100199 +
100200 +
100201 +/*****************************************************************************
100202 + SPI INTEGRATION-SPECIFIC DEFINITIONS
100203 +******************************************************************************/
100204 +#define SPI_NUM_OF_CONTROLLERS 1
100205 +
100206 +/*****************************************************************************
100207 + PCI/PCIe INTEGRATION-SPECIFIC DEFINITIONS
100208 +******************************************************************************/
100209 +
100210 +#define PCI_MAX_INBOUND_WINDOWS_NUM 4
100211 +#define PCI_MAX_OUTBOUND_WINDOWS_NUM 5
100212 +
100213 +/**************************************************************************//**
100214 + @Description Target interface of an inbound window
100215 +*//***************************************************************************/
100216 +typedef enum e_PciTargetInterface
100217 +{
100218 + e_PCI_TARGET_PCIE_2 = 0x1, /**< PCI Express target interface 2 */
100219 + e_PCI_TARGET_PCIE_1 = 0x2, /**< PCI Express target interface 1 */
100220 + e_PCI_TARGET_PCIE_3 = 0x3, /**< PCI Express target interface 3 */
100221 + e_PCI_TARGET_LOCAL_MEMORY = 0xF /**< Local Memory (DDR SDRAM, Local Bus, SRAM) target interface */
100222 +
100223 +} e_PciTargetInterface;
100224 +
100225 +/*****************************************************************************
100226 + DDR INTEGRATION-SPECIFIC DEFINITIONS
100227 +******************************************************************************/
100228 +#define DDR_NUM_OF_VALID_CS 2
100229 +
100230 +/*****************************************************************************
100231 + SEC INTEGRATION-SPECIFIC DEFINITIONS
100232 +******************************************************************************/
100233 +#define SEC_ERRATA_STAT_REGS_UNUSABLE
100234 +
100235 +/*****************************************************************************
100236 + DMA INTEGRATION-SPECIFIC DEFINITIONS
100237 +******************************************************************************/
100238 +#define DMA_NUM_OF_CONTROLLERS 2
100239 +
100240 +
100241 +
100242 +
100243 +/*****************************************************************************
100244 + 1588 INTEGRATION-SPECIFIC DEFINITIONS
100245 +******************************************************************************/
100246 +#define PTP_V2
100247 +
100248 +/**************************************************************************//**
100249 + @Function P1023_GetMuxControlReg
100250 +
100251 + @Description Returns the value of PMUXCR (Alternate Function Signal Multiplex
100252 + Control Register)
100253 +
100254 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100255 +
100256 + @Return Value of PMUXCR
100257 +*//***************************************************************************/
100258 +uint32_t P1023_GetMuxControlReg(uintptr_t gutilBase);
100259 +
100260 +/**************************************************************************//**
100261 + @Function P1023_SetMuxControlReg
100262 +
100263 + @Description Sets the value of PMUXCR (Alternate Function Signal Multiplex
100264 + Control Register)
100265 +
100266 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100267 + @Param[in] val - the new value for PMUXCR.
100268 +
100269 + @Return None
100270 +*//***************************************************************************/
100271 +void P1023_SetMuxControlReg(uintptr_t gutilBase, uint32_t val);
100272 +
100273 +/**************************************************************************//**
100274 + @Function P1023_GetDeviceDisableStatusRegister
100275 +
100276 + @Description Returns the value of DEVDISR (Device Disable Register)
100277 +
100278 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100279 +
100280 + @Return Value of DEVDISR
100281 +*//***************************************************************************/
100282 +uint32_t P1023_GetDeviceDisableStatusRegister(uintptr_t gutilBase);
100283 +
100284 +/**************************************************************************//**
100285 + @Function P1023_GetPorDeviceStatusRegister
100286 +
100287 + @Description Returns the value of POR Device Status Register
100288 +
100289 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100290 +
100291 + @Return POR Device Status Register
100292 +*//***************************************************************************/
100293 +uint32_t P1023_GetPorDeviceStatusRegister(uintptr_t gutilBase);
100294 +
100295 +/**************************************************************************//**
100296 + @Function P1023_GetPorBootModeStatusRegister
100297 +
100298 + @Description Returns the value of POR Boot Mode Status Register
100299 +
100300 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100301 +
100302 + @Return POR Boot Mode Status Register value
100303 +*//***************************************************************************/
100304 +uint32_t P1023_GetPorBootModeStatusRegister(uintptr_t gutilBase);
100305 +
100306 +
100307 +#define PORDEVSR_SGMII1_DIS 0x10000000
100308 +#define PORDEVSR_SGMII2_DIS 0x08000000
100309 +#define PORDEVSR_ECP1 0x02000000
100310 +#define PORDEVSR_IO_SEL 0x00780000
100311 +#define PORDEVSR_IO_SEL_SHIFT 19
100312 +#define PORBMSR_HA 0x00070000
100313 +#define PORBMSR_HA_SHIFT 16
100314 +
100315 +#define DEVDISR_QM_BM 0x80000000
100316 +#define DEVDISR_FM 0x40000000
100317 +#define DEVDISR_PCIE1 0x20000000
100318 +#define DEVDISR_MAC_SEC 0x10000000
100319 +#define DEVDISR_ELBC 0x08000000
100320 +#define DEVDISR_PCIE2 0x04000000
100321 +#define DEVDISR_PCIE3 0x02000000
100322 +#define DEVDISR_CAAM 0x01000000
100323 +#define DEVDISR_USB0 0x00800000
100324 +#define DEVDISR_1588 0x00020000
100325 +#define DEVDISR_CORE0 0x00008000
100326 +#define DEVDISR_TB0 0x00004000
100327 +#define DEVDISR_CORE1 0x00002000
100328 +#define DEVDISR_TB1 0x00001000
100329 +#define DEVDISR_DMA1 0x00000400
100330 +#define DEVDISR_DMA2 0x00000200
100331 +#define DEVDISR_DDR 0x00000010
100332 +#define DEVDISR_TSEC1 0x00000080
100333 +#define DEVDISR_TSEC2 0x00000040
100334 +#define DEVDISR_SPI 0x00000008
100335 +#define DEVDISR_I2C 0x00000004
100336 +#define DEVDISR_DUART 0x00000002
100337 +
100338 +
100339 +#endif /* __PART_INTEGRATION_EXT_H */
100340 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
100341 new file mode 100644
100342 index 00000000..6e2b925f
100343 --- /dev/null
100344 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
100345 @@ -0,0 +1,276 @@
100346 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc
100347 + * All rights reserved.
100348 + *
100349 + * Redistribution and use in source and binary forms, with or without
100350 + * modification, are permitted provided that the following conditions are met:
100351 + * * Redistributions of source code must retain the above copyright
100352 + * notice, this list of conditions and the following disclaimer.
100353 + * * Redistributions in binary form must reproduce the above copyright
100354 + * notice, this list of conditions and the following disclaimer in the
100355 + * documentation and/or other materials provided with the distribution.
100356 + * * Neither the name of Freescale Semiconductor nor the
100357 + * names of its contributors may be used to endorse or promote products
100358 + * derived from this software without specific prior written permission.
100359 + *
100360 + *
100361 + * ALTERNATIVELY, this software may be distributed under the terms of the
100362 + * GNU General Public License ("GPL") as published by the Free Software
100363 + * Foundation, either version 2 of that License or (at your option) any
100364 + * later version.
100365 + *
100366 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100367 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100368 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100369 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100370 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100371 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100372 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100373 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100374 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100375 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100376 + */
100377 +
100378 +/**************************************************************************//**
100379 + @File dpaa_integration_ext.h
100380 +
100381 + @Description P3040/P4080/P5020 FM external definitions and structures.
100382 +*//***************************************************************************/
100383 +#ifndef __DPAA_INTEGRATION_EXT_H
100384 +#define __DPAA_INTEGRATION_EXT_H
100385 +
100386 +#include "std_ext.h"
100387 +
100388 +
100389 +#define DPAA_VERSION 10
100390 +
100391 +typedef enum {
100392 + e_DPAA_SWPORTAL0 = 0,
100393 + e_DPAA_SWPORTAL1,
100394 + e_DPAA_SWPORTAL2,
100395 + e_DPAA_SWPORTAL3,
100396 + e_DPAA_SWPORTAL4,
100397 + e_DPAA_SWPORTAL5,
100398 + e_DPAA_SWPORTAL6,
100399 + e_DPAA_SWPORTAL7,
100400 + e_DPAA_SWPORTAL8,
100401 + e_DPAA_SWPORTAL9,
100402 + e_DPAA_SWPORTAL_DUMMY_LAST
100403 +} e_DpaaSwPortal;
100404 +
100405 +typedef enum {
100406 + e_DPAA_DCPORTAL0 = 0,
100407 + e_DPAA_DCPORTAL1,
100408 + e_DPAA_DCPORTAL2,
100409 + e_DPAA_DCPORTAL3,
100410 + e_DPAA_DCPORTAL4,
100411 + e_DPAA_DCPORTAL_DUMMY_LAST
100412 +} e_DpaaDcPortal;
100413 +
100414 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
100415 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
100416 +
100417 +/*****************************************************************************
100418 + QMan INTEGRATION-SPECIFIC DEFINITIONS
100419 +******************************************************************************/
100420 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
100421 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
100422 +#define QM_MAX_NUM_OF_SWP_AS 4
100423 +#define QM_MAX_NUM_OF_CGS 256 /**< Number of congestion groups */
100424 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) /**< FQIDs range - 24 bits */
100425 +
100426 +/**************************************************************************//**
100427 + @Description Work Queue Channel assignments in QMan.
100428 +*//***************************************************************************/
100429 +typedef enum
100430 +{
100431 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
100432 + e_QM_FQ_CHANNEL_SWPORTAL1,
100433 + e_QM_FQ_CHANNEL_SWPORTAL2,
100434 + e_QM_FQ_CHANNEL_SWPORTAL3,
100435 + e_QM_FQ_CHANNEL_SWPORTAL4,
100436 + e_QM_FQ_CHANNEL_SWPORTAL5,
100437 + e_QM_FQ_CHANNEL_SWPORTAL6,
100438 + e_QM_FQ_CHANNEL_SWPORTAL7,
100439 + e_QM_FQ_CHANNEL_SWPORTAL8,
100440 + e_QM_FQ_CHANNEL_SWPORTAL9,
100441 +
100442 + e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
100443 + e_QM_FQ_CHANNEL_POOL2,
100444 + e_QM_FQ_CHANNEL_POOL3,
100445 + e_QM_FQ_CHANNEL_POOL4,
100446 + e_QM_FQ_CHANNEL_POOL5,
100447 + e_QM_FQ_CHANNEL_POOL6,
100448 + e_QM_FQ_CHANNEL_POOL7,
100449 + e_QM_FQ_CHANNEL_POOL8,
100450 + e_QM_FQ_CHANNEL_POOL9,
100451 + e_QM_FQ_CHANNEL_POOL10,
100452 + e_QM_FQ_CHANNEL_POOL11,
100453 + e_QM_FQ_CHANNEL_POOL12,
100454 + e_QM_FQ_CHANNEL_POOL13,
100455 + e_QM_FQ_CHANNEL_POOL14,
100456 + e_QM_FQ_CHANNEL_POOL15,
100457 +
100458 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
100459 + connected to FMan 0; assigned in incrementing order to
100460 + each sub-portal (SP) in the portal */
100461 + e_QM_FQ_CHANNEL_FMAN0_SP1,
100462 + e_QM_FQ_CHANNEL_FMAN0_SP2,
100463 + e_QM_FQ_CHANNEL_FMAN0_SP3,
100464 + e_QM_FQ_CHANNEL_FMAN0_SP4,
100465 + e_QM_FQ_CHANNEL_FMAN0_SP5,
100466 + e_QM_FQ_CHANNEL_FMAN0_SP6,
100467 + e_QM_FQ_CHANNEL_FMAN0_SP7,
100468 + e_QM_FQ_CHANNEL_FMAN0_SP8,
100469 + e_QM_FQ_CHANNEL_FMAN0_SP9,
100470 + e_QM_FQ_CHANNEL_FMAN0_SP10,
100471 + e_QM_FQ_CHANNEL_FMAN0_SP11,
100472 +/* difference between 5020 and 4080 :) */
100473 + e_QM_FQ_CHANNEL_FMAN1_SP0 = 0x60,
100474 + e_QM_FQ_CHANNEL_FMAN1_SP1,
100475 + e_QM_FQ_CHANNEL_FMAN1_SP2,
100476 + e_QM_FQ_CHANNEL_FMAN1_SP3,
100477 + e_QM_FQ_CHANNEL_FMAN1_SP4,
100478 + e_QM_FQ_CHANNEL_FMAN1_SP5,
100479 + e_QM_FQ_CHANNEL_FMAN1_SP6,
100480 + e_QM_FQ_CHANNEL_FMAN1_SP7,
100481 + e_QM_FQ_CHANNEL_FMAN1_SP8,
100482 + e_QM_FQ_CHANNEL_FMAN1_SP9,
100483 + e_QM_FQ_CHANNEL_FMAN1_SP10,
100484 + e_QM_FQ_CHANNEL_FMAN1_SP11,
100485 +
100486 + e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
100487 + connected to SEC 4.x */
100488 +
100489 + e_QM_FQ_CHANNEL_PME = 0xA0, /**< Dedicated channel serviced by Direct Connect Portal 3:
100490 + connected to PME */
100491 + e_QM_FQ_CHANNEL_RAID = 0xC0 /**< Dedicated channel serviced by Direct Connect Portal 4:
100492 + connected to RAID */
100493 +} e_QmFQChannel;
100494 +
100495 +/*****************************************************************************
100496 + BMan INTEGRATION-SPECIFIC DEFINITIONS
100497 +******************************************************************************/
100498 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
100499 +
100500 +
100501 +/*****************************************************************************
100502 + FM INTEGRATION-SPECIFIC DEFINITIONS
100503 +******************************************************************************/
100504 +#define INTG_MAX_NUM_OF_FM 2
100505 +
100506 +/* Ports defines */
100507 +#define FM_MAX_NUM_OF_1G_MACS 5
100508 +#define FM_MAX_NUM_OF_10G_MACS 1
100509 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
100510 +#define FM_MAX_NUM_OF_OH_PORTS 7
100511 +
100512 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
100513 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
100514 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
100515 +
100516 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
100517 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
100518 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
100519 +
100520 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
100521 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
100522 +#define FM_MAX_NUM_OF_SUB_PORTALS 12
100523 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
100524 +
100525 +/* Rams defines */
100526 +#define FM_MURAM_SIZE (160*KILOBYTE)
100527 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
100528 +#define FM_NUM_OF_CTRL 2
100529 +
100530 +/* PCD defines */
100531 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
100532 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
100533 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
100534 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */
100535 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
100536 +
100537 +/* RTC defines */
100538 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
100539 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
100540 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
100541 +
100542 +/* QMI defines */
100543 +#define QMI_MAX_NUM_OF_TNUMS 64
100544 +#define QMI_DEF_TNUMS_THRESH 48
100545 +
100546 +/* FPM defines */
100547 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
100548 +
100549 +/* DMA defines */
100550 +#define DMA_THRESH_MAX_COMMQ 31
100551 +#define DMA_THRESH_MAX_BUF 127
100552 +
100553 +/* BMI defines */
100554 +#define BMI_MAX_NUM_OF_TASKS 128
100555 +#define BMI_MAX_NUM_OF_DMAS 32
100556 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
100557 +#define PORT_MAX_WEIGHT 16
100558 +
100559 +
100560 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
100561 +
100562 +/* p4080-rev1 unique features */
100563 +#define QM_CGS_NO_FRAME_MODE
100564 +
100565 +/* p4080 unique features */
100566 +#define FM_NO_DISPATCH_RAM_ECC
100567 +#define FM_NO_WATCHDOG
100568 +#define FM_NO_TNUM_AGING
100569 +#define FM_KG_NO_BYPASS_FQID_GEN
100570 +#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
100571 +#define FM_NO_BACKUP_POOLS
100572 +#define FM_NO_OP_OBSERVED_POOLS
100573 +#define FM_NO_ADVANCED_RATE_LIMITER
100574 +#define FM_NO_OP_OBSERVED_CGS
100575 +#define FM_HAS_TOTAL_DMAS
100576 +#define FM_KG_NO_IPPID_SUPPORT
100577 +#define FM_NO_GUARANTEED_RESET_VALUES
100578 +#define FM_MAC_RESET
100579 +
100580 +/* FM erratas */
100581 +#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
100582 +#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */
100583 +#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
100584 +#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
100585 +#define FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 /* Out of LLD scope, user may disable ECC exceptions using FM_DisableRamsEcc */
100586 +#define FM_BAD_VLAN_DETECT_ERRATA_10GMAC_A010
100587 +
100588 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
100589 +#define FM_GRS_ERRATA_DTSEC_A002
100590 +#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
100591 +#define FM_GTS_ERRATA_DTSEC_A004
100592 +#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012
100593 +#define FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
100594 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
100595 +
100596 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
100597 +#define FM_TX_LOCKUP_ERRATA_DTSEC6
100598 +
100599 +#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */
100600 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
100601 +
100602 +#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
100603 +
100604 +#define FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
100605 +
100606 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
100607 +
100608 +#define FM_NO_CTXA_COPY_ERRATA_FMAN_SW001
100609 +#define FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
100610 +
100611 +/*****************************************************************************
100612 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
100613 +******************************************************************************/
100614 +#define NUM_OF_RX_SC 16
100615 +#define NUM_OF_TX_SC 16
100616 +
100617 +#define NUM_OF_SA_PER_RX_SC 2
100618 +#define NUM_OF_SA_PER_TX_SC 2
100619 +
100620 +
100621 +#endif /* __DPAA_INTEGRATION_EXT_H */
100622 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
100623 new file mode 100644
100624 index 00000000..512f0baf
100625 --- /dev/null
100626 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
100627 @@ -0,0 +1,83 @@
100628 +/*
100629 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100630 + *
100631 + * Redistribution and use in source and binary forms, with or without
100632 + * modification, are permitted provided that the following conditions are met:
100633 + * * Redistributions of source code must retain the above copyright
100634 + * notice, this list of conditions and the following disclaimer.
100635 + * * Redistributions in binary form must reproduce the above copyright
100636 + * notice, this list of conditions and the following disclaimer in the
100637 + * documentation and/or other materials provided with the distribution.
100638 + * * Neither the name of Freescale Semiconductor nor the
100639 + * names of its contributors may be used to endorse or promote products
100640 + * derived from this software without specific prior written permission.
100641 + *
100642 + *
100643 + * ALTERNATIVELY, this software may be distributed under the terms of the
100644 + * GNU General Public License ("GPL") as published by the Free Software
100645 + * Foundation, either version 2 of that License or (at your option) any
100646 + * later version.
100647 + *
100648 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100649 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100650 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100651 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100652 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100653 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100654 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100655 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100656 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100657 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100658 + */
100659 +
100660 +/**************************************************************************//**
100661 +
100662 + @File part_ext.h
100663 +
100664 + @Description Definitions for the part (integration) module.
100665 +*//***************************************************************************/
100666 +
100667 +#ifndef __PART_EXT_H
100668 +#define __PART_EXT_H
100669 +
100670 +#include "std_ext.h"
100671 +#include "part_integration_ext.h"
100672 +
100673 +
100674 +#if !(defined(MPC8306) || \
100675 + defined(MPC8309) || \
100676 + defined(MPC834x) || \
100677 + defined(MPC836x) || \
100678 + defined(MPC832x) || \
100679 + defined(MPC837x) || \
100680 + defined(MPC8568) || \
100681 + defined(MPC8569) || \
100682 + defined(P1020) || \
100683 + defined(P1021) || \
100684 + defined(P1022) || \
100685 + defined(P1023) || \
100686 + defined(P2020) || \
100687 + defined(P2040) || \
100688 + defined(P3041) || \
100689 + defined(P4080) || \
100690 + defined(SC4080) || \
100691 + defined(P5020) || \
100692 + defined(MSC814x))
100693 +#error "unable to proceed without chip-definition"
100694 +#endif /* !(defined(MPC834x) || ... */
100695 +
100696 +
100697 +/**************************************************************************//*
100698 + @Description Part data structure - must be contained in any integration
100699 + data structure.
100700 +*//***************************************************************************/
100701 +typedef struct t_Part
100702 +{
100703 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
100704 + /**< Returns the address of the module's memory map base. */
100705 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
100706 + /**< Returns the module's ID according to its memory map base. */
100707 +} t_Part;
100708 +
100709 +
100710 +#endif /* __PART_EXT_H */
100711 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
100712 new file mode 100644
100713 index 00000000..03c59b8b
100714 --- /dev/null
100715 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
100716 @@ -0,0 +1,336 @@
100717 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100718 + * All rights reserved.
100719 + *
100720 + * Redistribution and use in source and binary forms, with or without
100721 + * modification, are permitted provided that the following conditions are met:
100722 + * * Redistributions of source code must retain the above copyright
100723 + * notice, this list of conditions and the following disclaimer.
100724 + * * Redistributions in binary form must reproduce the above copyright
100725 + * notice, this list of conditions and the following disclaimer in the
100726 + * documentation and/or other materials provided with the distribution.
100727 + * * Neither the name of Freescale Semiconductor nor the
100728 + * names of its contributors may be used to endorse or promote products
100729 + * derived from this software without specific prior written permission.
100730 + *
100731 + *
100732 + * ALTERNATIVELY, this software may be distributed under the terms of the
100733 + * GNU General Public License ("GPL") as published by the Free Software
100734 + * Foundation, either version 2 of that License or (at your option) any
100735 + * later version.
100736 + *
100737 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100738 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100739 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100740 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100741 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100742 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100743 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100744 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100745 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100746 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100747 + */
100748 +
100749 +/**************************************************************************//**
100750 + @File part_integration_ext.h
100751 +
100752 + @Description P3040/P4080/P5020 external definitions and structures.
100753 +*//***************************************************************************/
100754 +#ifndef __PART_INTEGRATION_EXT_H
100755 +#define __PART_INTEGRATION_EXT_H
100756 +
100757 +#include "std_ext.h"
100758 +#include "dpaa_integration_ext.h"
100759 +
100760 +
100761 +/**************************************************************************//**
100762 + @Group P3040/P4080/P5020_chip_id P5020 Application Programming Interface
100763 +
100764 + @Description P3040/P4080/P5020 Chip functions,definitions and enums.
100765 +
100766 + @{
100767 +*//***************************************************************************/
100768 +
100769 +#define CORE_E500MC
100770 +
100771 +#define INTG_MAX_NUM_OF_CORES 1
100772 +
100773 +
100774 +/**************************************************************************//**
100775 + @Description Module types.
100776 +*//***************************************************************************/
100777 +typedef enum e_ModuleId
100778 +{
100779 + e_MODULE_ID_DUART_1 = 0,
100780 + e_MODULE_ID_DUART_2,
100781 + e_MODULE_ID_DUART_3,
100782 + e_MODULE_ID_DUART_4,
100783 + e_MODULE_ID_LAW,
100784 + e_MODULE_ID_LBC,
100785 + e_MODULE_ID_PAMU,
100786 + e_MODULE_ID_QM, /**< Queue manager module */
100787 + e_MODULE_ID_BM, /**< Buffer manager module */
100788 + e_MODULE_ID_QM_CE_PORTAL_0,
100789 + e_MODULE_ID_QM_CI_PORTAL_0,
100790 + e_MODULE_ID_QM_CE_PORTAL_1,
100791 + e_MODULE_ID_QM_CI_PORTAL_1,
100792 + e_MODULE_ID_QM_CE_PORTAL_2,
100793 + e_MODULE_ID_QM_CI_PORTAL_2,
100794 + e_MODULE_ID_QM_CE_PORTAL_3,
100795 + e_MODULE_ID_QM_CI_PORTAL_3,
100796 + e_MODULE_ID_QM_CE_PORTAL_4,
100797 + e_MODULE_ID_QM_CI_PORTAL_4,
100798 + e_MODULE_ID_QM_CE_PORTAL_5,
100799 + e_MODULE_ID_QM_CI_PORTAL_5,
100800 + e_MODULE_ID_QM_CE_PORTAL_6,
100801 + e_MODULE_ID_QM_CI_PORTAL_6,
100802 + e_MODULE_ID_QM_CE_PORTAL_7,
100803 + e_MODULE_ID_QM_CI_PORTAL_7,
100804 + e_MODULE_ID_QM_CE_PORTAL_8,
100805 + e_MODULE_ID_QM_CI_PORTAL_8,
100806 + e_MODULE_ID_QM_CE_PORTAL_9,
100807 + e_MODULE_ID_QM_CI_PORTAL_9,
100808 + e_MODULE_ID_BM_CE_PORTAL_0,
100809 + e_MODULE_ID_BM_CI_PORTAL_0,
100810 + e_MODULE_ID_BM_CE_PORTAL_1,
100811 + e_MODULE_ID_BM_CI_PORTAL_1,
100812 + e_MODULE_ID_BM_CE_PORTAL_2,
100813 + e_MODULE_ID_BM_CI_PORTAL_2,
100814 + e_MODULE_ID_BM_CE_PORTAL_3,
100815 + e_MODULE_ID_BM_CI_PORTAL_3,
100816 + e_MODULE_ID_BM_CE_PORTAL_4,
100817 + e_MODULE_ID_BM_CI_PORTAL_4,
100818 + e_MODULE_ID_BM_CE_PORTAL_5,
100819 + e_MODULE_ID_BM_CI_PORTAL_5,
100820 + e_MODULE_ID_BM_CE_PORTAL_6,
100821 + e_MODULE_ID_BM_CI_PORTAL_6,
100822 + e_MODULE_ID_BM_CE_PORTAL_7,
100823 + e_MODULE_ID_BM_CI_PORTAL_7,
100824 + e_MODULE_ID_BM_CE_PORTAL_8,
100825 + e_MODULE_ID_BM_CI_PORTAL_8,
100826 + e_MODULE_ID_BM_CE_PORTAL_9,
100827 + e_MODULE_ID_BM_CI_PORTAL_9,
100828 + e_MODULE_ID_FM1, /**< Frame manager #1 module */
100829 + e_MODULE_ID_FM1_RTC, /**< FM Real-Time-Clock */
100830 + e_MODULE_ID_FM1_MURAM, /**< FM Multi-User-RAM */
100831 + e_MODULE_ID_FM1_BMI, /**< FM BMI block */
100832 + e_MODULE_ID_FM1_QMI, /**< FM QMI block */
100833 + e_MODULE_ID_FM1_PRS, /**< FM parser block */
100834 + e_MODULE_ID_FM1_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100835 + e_MODULE_ID_FM1_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100836 + e_MODULE_ID_FM1_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100837 + e_MODULE_ID_FM1_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100838 + e_MODULE_ID_FM1_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100839 + e_MODULE_ID_FM1_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100840 + e_MODULE_ID_FM1_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100841 + e_MODULE_ID_FM1_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100842 + e_MODULE_ID_FM1_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100843 + e_MODULE_ID_FM1_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100844 + e_MODULE_ID_FM1_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100845 + e_MODULE_ID_FM1_PORT_1GRx4, /**< FM Rx 1G MAC port block */
100846 + e_MODULE_ID_FM1_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100847 + e_MODULE_ID_FM1_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100848 + e_MODULE_ID_FM1_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100849 + e_MODULE_ID_FM1_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100850 + e_MODULE_ID_FM1_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100851 + e_MODULE_ID_FM1_PORT_1GTx4, /**< FM Tx 1G MAC port block */
100852 + e_MODULE_ID_FM1_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100853 + e_MODULE_ID_FM1_PLCR, /**< FM Policer */
100854 + e_MODULE_ID_FM1_KG, /**< FM Keygen */
100855 + e_MODULE_ID_FM1_DMA, /**< FM DMA */
100856 + e_MODULE_ID_FM1_FPM, /**< FM FPM */
100857 + e_MODULE_ID_FM1_IRAM, /**< FM Instruction-RAM */
100858 + e_MODULE_ID_FM1_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100859 + e_MODULE_ID_FM1_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100860 + e_MODULE_ID_FM1_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100861 + e_MODULE_ID_FM1_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100862 + e_MODULE_ID_FM1_10GMDIO, /**< FM 10G MDIO */
100863 + e_MODULE_ID_FM1_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100864 + e_MODULE_ID_FM1_1GMAC0, /**< FM 1G MAC #0 */
100865 + e_MODULE_ID_FM1_1GMAC1, /**< FM 1G MAC #1 */
100866 + e_MODULE_ID_FM1_1GMAC2, /**< FM 1G MAC #2 */
100867 + e_MODULE_ID_FM1_1GMAC3, /**< FM 1G MAC #3 */
100868 + e_MODULE_ID_FM1_10GMAC0, /**< FM 10G MAC #0 */
100869 +
100870 + e_MODULE_ID_FM2, /**< Frame manager #2 module */
100871 + e_MODULE_ID_FM2_RTC, /**< FM Real-Time-Clock */
100872 + e_MODULE_ID_FM2_MURAM, /**< FM Multi-User-RAM */
100873 + e_MODULE_ID_FM2_BMI, /**< FM BMI block */
100874 + e_MODULE_ID_FM2_QMI, /**< FM QMI block */
100875 + e_MODULE_ID_FM2_PRS, /**< FM parser block */
100876 + e_MODULE_ID_FM2_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100877 + e_MODULE_ID_FM2_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100878 + e_MODULE_ID_FM2_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100879 + e_MODULE_ID_FM2_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100880 + e_MODULE_ID_FM2_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100881 + e_MODULE_ID_FM2_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100882 + e_MODULE_ID_FM2_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100883 + e_MODULE_ID_FM2_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100884 + e_MODULE_ID_FM2_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100885 + e_MODULE_ID_FM2_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100886 + e_MODULE_ID_FM2_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100887 + e_MODULE_ID_FM2_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100888 + e_MODULE_ID_FM2_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100889 + e_MODULE_ID_FM2_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100890 + e_MODULE_ID_FM2_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100891 + e_MODULE_ID_FM2_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100892 + e_MODULE_ID_FM2_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100893 + e_MODULE_ID_FM2_PLCR, /**< FM Policer */
100894 + e_MODULE_ID_FM2_KG, /**< FM Keygen */
100895 + e_MODULE_ID_FM2_DMA, /**< FM DMA */
100896 + e_MODULE_ID_FM2_FPM, /**< FM FPM */
100897 + e_MODULE_ID_FM2_IRAM, /**< FM Instruction-RAM */
100898 + e_MODULE_ID_FM2_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100899 + e_MODULE_ID_FM2_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100900 + e_MODULE_ID_FM2_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100901 + e_MODULE_ID_FM2_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100902 + e_MODULE_ID_FM2_10GMDIO, /**< FM 10G MDIO */
100903 + e_MODULE_ID_FM2_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100904 + e_MODULE_ID_FM2_1GMAC0, /**< FM 1G MAC #0 */
100905 + e_MODULE_ID_FM2_1GMAC1, /**< FM 1G MAC #1 */
100906 + e_MODULE_ID_FM2_1GMAC2, /**< FM 1G MAC #2 */
100907 + e_MODULE_ID_FM2_1GMAC3, /**< FM 1G MAC #3 */
100908 + e_MODULE_ID_FM2_10GMAC0, /**< FM 10G MAC #0 */
100909 +
100910 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
100911 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
100912 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
100913 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
100914 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
100915 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
100916 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
100917 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
100918 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
100919 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
100920 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
100921 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
100922 +
100923 + e_MODULE_ID_MPIC, /**< MPIC */
100924 + e_MODULE_ID_GPIO, /**< GPIO */
100925 + e_MODULE_ID_SERDES, /**< SERDES */
100926 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
100927 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
100928 +
100929 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
100930 + e_MODULE_ID_SRIO_MU, /**< RapidIO messaging unit module */
100931 +
100932 + e_MODULE_ID_DUMMY_LAST
100933 +} e_ModuleId;
100934 +
100935 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
100936 +
100937 +#if 0 /* using unified values */
100938 +/*****************************************************************************
100939 + INTEGRATION-SPECIFIC MODULE CODES
100940 +******************************************************************************/
100941 +#define MODULE_UNKNOWN 0x00000000
100942 +#define MODULE_MEM 0x00010000
100943 +#define MODULE_MM 0x00020000
100944 +#define MODULE_CORE 0x00030000
100945 +#define MODULE_CHIP 0x00040000
100946 +#define MODULE_PLTFRM 0x00050000
100947 +#define MODULE_PM 0x00060000
100948 +#define MODULE_MMU 0x00070000
100949 +#define MODULE_PIC 0x00080000
100950 +#define MODULE_CPC 0x00090000
100951 +#define MODULE_DUART 0x000a0000
100952 +#define MODULE_SERDES 0x000b0000
100953 +#define MODULE_PIO 0x000c0000
100954 +#define MODULE_QM 0x000d0000
100955 +#define MODULE_BM 0x000e0000
100956 +#define MODULE_SEC 0x000f0000
100957 +#define MODULE_LAW 0x00100000
100958 +#define MODULE_LBC 0x00110000
100959 +#define MODULE_PAMU 0x00120000
100960 +#define MODULE_FM 0x00130000
100961 +#define MODULE_FM_MURAM 0x00140000
100962 +#define MODULE_FM_PCD 0x00150000
100963 +#define MODULE_FM_RTC 0x00160000
100964 +#define MODULE_FM_MAC 0x00170000
100965 +#define MODULE_FM_PORT 0x00180000
100966 +#define MODULE_FM_SP 0x00190000
100967 +#define MODULE_DPA_PORT 0x001a0000
100968 +#define MODULE_MII 0x001b0000
100969 +#define MODULE_I2C 0x001c0000
100970 +#define MODULE_DMA 0x001d0000
100971 +#define MODULE_DDR 0x001e0000
100972 +#define MODULE_ESPI 0x001f0000
100973 +#define MODULE_DPAA_IPSEC 0x00200000
100974 +#endif /* using unified values */
100975 +
100976 +/*****************************************************************************
100977 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
100978 +******************************************************************************/
100979 +#define PAMU_NUM_OF_PARTITIONS 5
100980 +
100981 +#define PAMU_PICS_AVICS_ERRATA_PAMU3
100982 +
100983 +/*****************************************************************************
100984 + LAW INTEGRATION-SPECIFIC DEFINITIONS
100985 +******************************************************************************/
100986 +#define LAW_NUM_OF_WINDOWS 32
100987 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
100988 +#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
100989 +
100990 +
100991 +/*****************************************************************************
100992 + LBC INTEGRATION-SPECIFIC DEFINITIONS
100993 +******************************************************************************/
100994 +/**************************************************************************//**
100995 + @Group lbc_exception_grp LBC Exception Unit
100996 +
100997 + @Description LBC Exception unit API functions, definitions and enums
100998 +
100999 + @{
101000 +*//***************************************************************************/
101001 +
101002 +/**************************************************************************//**
101003 + @Anchor lbc_exbm
101004 +
101005 + @Collection LBC Errors Bit Mask
101006 +
101007 + These errors are reported through the exceptions callback..
101008 + The values can be or'ed in any combination in the errors mask
101009 + parameter of the errors report structure.
101010 +
101011 + These errors can also be passed as a bit-mask to
101012 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
101013 + for enabling or disabling error checking.
101014 + @{
101015 +*//***************************************************************************/
101016 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
101017 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
101018 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
101019 +#define LBC_ERR_ATOMIC_WRITE 0x00800000 /**< Atomic write error */
101020 +#define LBC_ERR_ATOMIC_READ 0x00400000 /**< Atomic read error */
101021 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
101022 +
101023 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
101024 + LBC_ERR_WRITE_PROTECT | LBC_ERR_ATOMIC_WRITE | \
101025 + LBC_ERR_ATOMIC_READ | LBC_ERR_CHIP_SELECT)
101026 + /**< All possible errors */
101027 +/* @} */
101028 +/** @} */ /* end of lbc_exception_grp group */
101029 +
101030 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
101031 +
101032 +#define LBC_NUM_OF_BANKS 8
101033 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
101034 +#define LBC_ATOMIC_OPERATION_SUPPORT
101035 +#define LBC_PARITY_SUPPORT
101036 +#define LBC_ADDRESS_HOLD_TIME_CTRL
101037 +#define LBC_HIGH_CLK_DIVIDERS
101038 +#define LBC_FCM_AVAILABLE
101039 +
101040 +/*****************************************************************************
101041 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
101042 +******************************************************************************/
101043 +#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
101044 + Each port contains up to 32 i/O pins. */
101045 +
101046 +#define GPIO_VALID_PIN_MASKS \
101047 + { /* Port A */ 0xFFFFFFFF }
101048 +
101049 +#define GPIO_VALID_INTR_MASKS \
101050 + { /* Port A */ 0xFFFFFFFF }
101051 +
101052 +#endif /* __PART_INTEGRATION_EXT_H */
101053 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
101054 new file mode 100644
101055 index 00000000..4ecfc6ed
101056 --- /dev/null
101057 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
101058 @@ -0,0 +1,100 @@
101059 +/*
101060 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101061 + *
101062 + * Redistribution and use in source and binary forms, with or without
101063 + * modification, are permitted provided that the following conditions are met:
101064 + * * Redistributions of source code must retain the above copyright
101065 + * notice, this list of conditions and the following disclaimer.
101066 + * * Redistributions in binary form must reproduce the above copyright
101067 + * notice, this list of conditions and the following disclaimer in the
101068 + * documentation and/or other materials provided with the distribution.
101069 + * * Neither the name of Freescale Semiconductor nor the
101070 + * names of its contributors may be used to endorse or promote products
101071 + * derived from this software without specific prior written permission.
101072 + *
101073 + *
101074 + * ALTERNATIVELY, this software may be distributed under the terms of the
101075 + * GNU General Public License ("GPL") as published by the Free Software
101076 + * Foundation, either version 2 of that License or (at your option) any
101077 + * later version.
101078 + *
101079 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101080 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101081 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101082 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101083 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101084 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101085 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101086 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101087 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101088 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101089 + */
101090 +
101091 +
101092 +#ifndef __MATH_EXT_H
101093 +#define __MATH_EXT_H
101094 +
101095 +
101096 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
101097 +#include <linux/math.h>
101098 +#include <linux/math64.h>
101099 +
101100 +#elif defined(__MWERKS__)
101101 +#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x))
101102 +#define HIGH(x) (*(int32_t*)&x)
101103 +#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x))
101104 +#define UHIGH(x) (*(uint32_t*)&x)
101105 +
101106 +static const double big = 1.0e300;
101107 +
101108 +/* Macro for checking if a number is a power of 2 */
101109 +static __inline__ double ceil(double x)
101110 +{
101111 + int32_t i0,i1,j0; /*- cc 020130 -*/
101112 + uint32_t i,j; /*- cc 020130 -*/
101113 + i0 = HIGH(x);
101114 + i1 = LOW(x);
101115 + j0 = ((i0>>20)&0x7ff)-0x3ff;
101116 + if(j0<20) {
101117 + if(j0<0) { /* raise inexact if x != 0 */
101118 + if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */
101119 + if(i0<0) {i0=0x80000000;i1=0;}
101120 + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
101121 + }
101122 + } else {
101123 + i = (uint32_t)(0x000fffff)>>j0;
101124 + if(((i0&i)|i1)==0) return x; /* x is integral */
101125 + if(big+x>0.0) { /* raise inexact flag */
101126 + if(i0>0) i0 += (0x00100000)>>j0;
101127 + i0 &= (~i); i1=0;
101128 + }
101129 + }
101130 + } else if (j0>51) {
101131 + if(j0==0x400) return x+x; /* inf or NaN */
101132 + else return x; /* x is integral */
101133 + } else {
101134 + i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/
101135 + if((i1&i)==0) return x; /* x is integral */
101136 + if(big+x>0.0) { /* raise inexact flag */
101137 + if(i0>0) {
101138 + if(j0==20) i0+=1;
101139 + else {
101140 + j = (uint32_t)(i1 + (1<<(52-j0)));
101141 + if(j<i1) i0+=1; /* got a carry */
101142 + i1 = (int32_t)j;
101143 + }
101144 + }
101145 + i1 &= (~i);
101146 + }
101147 + }
101148 + HIGH(x) = i0;
101149 + LOW(x) = i1;
101150 + return x;
101151 +}
101152 +
101153 +#else
101154 +#include <math.h>
101155 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101156 +
101157 +
101158 +#endif /* __MATH_EXT_H */
101159 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
101160 new file mode 100644
101161 index 00000000..dc32e249
101162 --- /dev/null
101163 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
101164 @@ -0,0 +1,435 @@
101165 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101166 + * All rights reserved.
101167 + *
101168 + * Redistribution and use in source and binary forms, with or without
101169 + * modification, are permitted provided that the following conditions are met:
101170 + * * Redistributions of source code must retain the above copyright
101171 + * notice, this list of conditions and the following disclaimer.
101172 + * * Redistributions in binary form must reproduce the above copyright
101173 + * notice, this list of conditions and the following disclaimer in the
101174 + * documentation and/or other materials provided with the distribution.
101175 + * * Neither the name of Freescale Semiconductor nor the
101176 + * names of its contributors may be used to endorse or promote products
101177 + * derived from this software without specific prior written permission.
101178 + *
101179 + *
101180 + * ALTERNATIVELY, this software may be distributed under the terms of the
101181 + * GNU General Public License ("GPL") as published by the Free Software
101182 + * Foundation, either version 2 of that License or (at your option) any
101183 + * later version.
101184 + *
101185 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101186 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101187 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101188 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101189 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101190 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101191 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101192 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101193 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101194 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101195 + */
101196 +
101197 +
101198 +/**************************************************************************//**
101199 + @File ncsw_ext.h
101200 +
101201 + @Description General NetCommSw Standard Definitions
101202 +*//***************************************************************************/
101203 +
101204 +#ifndef __NCSW_EXT_H
101205 +#define __NCSW_EXT_H
101206 +
101207 +
101208 +#include "memcpy_ext.h"
101209 +
101210 +#define WRITE_BLOCK IOMemSet32 /* include memcpy_ext.h */
101211 +#define COPY_BLOCK Mem2IOCpy32 /* include memcpy_ext.h */
101212 +
101213 +#define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr))
101214 +#define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val))
101215 +
101216 +#define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset))
101217 +
101218 +
101219 +#define WRITE_UINT8_UINT24(arg, data08, data24) \
101220 + WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF))
101221 +#define WRITE_UINT24_UINT8(arg, data24, data08) \
101222 + WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF))
101223 +
101224 +/* Little-Endian access macros */
101225 +
101226 +#define WRITE_UINT16_LE(arg, data) \
101227 + WRITE_UINT16((arg), SwapUint16(data))
101228 +
101229 +#define WRITE_UINT32_LE(arg, data) \
101230 + WRITE_UINT32((arg), SwapUint32(data))
101231 +
101232 +#define WRITE_UINT64_LE(arg, data) \
101233 + WRITE_UINT64((arg), SwapUint64(data))
101234 +
101235 +#define GET_UINT16_LE(arg) \
101236 + SwapUint16(GET_UINT16(arg))
101237 +
101238 +#define GET_UINT32_LE(arg) \
101239 + SwapUint32(GET_UINT32(arg))
101240 +
101241 +#define GET_UINT64_LE(arg) \
101242 + SwapUint64(GET_UINT64(arg))
101243 +
101244 +/* Write and Read again macros */
101245 +#define WRITE_UINT_SYNC(size, arg, data) \
101246 + do { \
101247 + WRITE_UINT##size((arg), (data)); \
101248 + CORE_MemoryBarrier(); \
101249 + } while (0)
101250 +
101251 +#define WRITE_UINT8_SYNC(arg, data) WRITE_UINT_SYNC(8, (arg), (data))
101252 +
101253 +#define WRITE_UINT16_SYNC(arg, data) WRITE_UINT_SYNC(16, (arg), (data))
101254 +#define WRITE_UINT32_SYNC(arg, data) WRITE_UINT_SYNC(32, (arg), (data))
101255 +
101256 +#define MAKE_UINT64(high32, low32) (((uint64_t)high32 << 32) | (low32))
101257 +
101258 +
101259 +/*----------------------*/
101260 +/* Miscellaneous macros */
101261 +/*----------------------*/
101262 +
101263 +#define UNUSED(_x) ((void)(_x))
101264 +
101265 +#define KILOBYTE 0x400UL /* 1024 */
101266 +#define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */
101267 +#define GIGABYTE ((uint64_t)(KILOBYTE * MEGABYTE)) /* 1024*1024*1024 */
101268 +#define TERABYTE ((uint64_t)(KILOBYTE * GIGABYTE)) /* 1024*1024*1024*1024 */
101269 +
101270 +#ifndef NO_IRQ
101271 +#define NO_IRQ (0)
101272 +#endif
101273 +#define NCSW_MASTER_ID (0)
101274 +
101275 +/* Macro for checking if a number is a power of 2 */
101276 +#define POWER_OF_2(n) (!((n) & ((n)-1)))
101277 +
101278 +/* Macro for calculating log of base 2 */
101279 +#define LOG2(num, log2Num) \
101280 + do \
101281 + { \
101282 + uint64_t tmp = (num); \
101283 + log2Num = 0; \
101284 + while (tmp > 1) \
101285 + { \
101286 + log2Num++; \
101287 + tmp >>= 1; \
101288 + } \
101289 + } while (0)
101290 +
101291 +#define NEXT_POWER_OF_2(_num, _nextPow) \
101292 +do \
101293 +{ \
101294 + if (POWER_OF_2(_num)) \
101295 + _nextPow = (_num); \
101296 + else \
101297 + { \
101298 + uint64_t tmp = (_num); \
101299 + _nextPow = 1; \
101300 + while (tmp) \
101301 + { \
101302 + _nextPow <<= 1; \
101303 + tmp >>= 1; \
101304 + } \
101305 + } \
101306 +} while (0)
101307 +
101308 +/* Ceiling division - not the fastest way, but safer in terms of overflow */
101309 +#define DIV_CEIL(x,y) (div64_u64((x),(y)) + (((div64_u64((x),(y))*(y)) == (x)) ? 0 : 1))
101310 +
101311 +/* Round up a number to be a multiple of a second number */
101312 +#define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y))
101313 +
101314 +/* Timing macro for converting usec units to number of ticks. */
101315 +/* (number of usec * clock_Hz) / 1,000,000) - since */
101316 +/* clk is in MHz units, no division needed. */
101317 +#define USEC_TO_CLK(usec,clk) ((usec) * (clk))
101318 +#define CYCLES_TO_USEC(cycles,clk) ((cycles) / (clk))
101319 +
101320 +/* Timing macros for converting between nsec units and number of clocks. */
101321 +#define NSEC_TO_CLK(nsec,clk) DIV_CEIL(((nsec) * (clk)), 1000)
101322 +#define CYCLES_TO_NSEC(cycles,clk) (((cycles) * 1000) / (clk))
101323 +
101324 +/* Timing macros for converting between psec units and number of clocks. */
101325 +#define PSEC_TO_CLK(psec,clk) DIV_CEIL(((psec) * (clk)), 1000000)
101326 +#define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk))
101327 +
101328 +/* Min, Max macros */
101329 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
101330 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
101331 +#define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max))
101332 +
101333 +#define ABS(a) ((a<0)?(a*-1):a)
101334 +
101335 +#if !(defined(ARRAY_SIZE))
101336 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
101337 +#endif /* !defined(ARRAY_SIZE) */
101338 +
101339 +
101340 +/* possible alignments */
101341 +#define HALF_WORD_ALIGNMENT 2
101342 +#define WORD_ALIGNMENT 4
101343 +#define DOUBLE_WORD_ALIGNMENT 8
101344 +#define BURST_ALIGNMENT 32
101345 +
101346 +#define HALF_WORD_ALIGNED 0x00000001
101347 +#define WORD_ALIGNED 0x00000003
101348 +#define DOUBLE_WORD_ALIGNED 0x00000007
101349 +#define BURST_ALIGNED 0x0000001f
101350 +#ifndef IS_ALIGNED
101351 +#define IS_ALIGNED(n,align) (!((uint32_t)(n) & (align - 1)))
101352 +#endif /* IS_ALIGNED */
101353 +
101354 +
101355 +#define LAST_BUF 1
101356 +#define FIRST_BUF 2
101357 +#define SINGLE_BUF (LAST_BUF | FIRST_BUF)
101358 +#define MIDDLE_BUF 4
101359 +
101360 +#define ARRAY_END -1
101361 +
101362 +#define ILLEGAL_BASE (~0)
101363 +
101364 +#define BUF_POSITION(first, last) state[(!!(last))<<1 | !!(first)]
101365 +#define DECLARE_POSITION static uint8_t state[4] = { (uint8_t)MIDDLE_BUF, (uint8_t)FIRST_BUF, (uint8_t)LAST_BUF, (uint8_t)SINGLE_BUF };
101366 +
101367 +
101368 +/**************************************************************************//**
101369 + @Description Timers operation mode
101370 +*//***************************************************************************/
101371 +typedef enum e_TimerMode
101372 +{
101373 + e_TIMER_MODE_INVALID = 0,
101374 + e_TIMER_MODE_FREE_RUN, /**< Free run - counter continues to increase
101375 + after reaching the reference value. */
101376 + e_TIMER_MODE_PERIODIC, /**< Periodic - counter restarts counting from 0
101377 + after reaching the reference value. */
101378 + e_TIMER_MODE_SINGLE /**< Single (one-shot) - counter stops counting
101379 + after reaching the reference value. */
101380 +} e_TimerMode;
101381 +
101382 +
101383 +/**************************************************************************//**
101384 + @Description Enumeration (bit flags) of communication modes (Transmit,
101385 + receive or both).
101386 +*//***************************************************************************/
101387 +typedef enum e_CommMode
101388 +{
101389 + e_COMM_MODE_NONE = 0, /**< No transmit/receive communication */
101390 + e_COMM_MODE_RX = 1, /**< Only receive communication */
101391 + e_COMM_MODE_TX = 2, /**< Only transmit communication */
101392 + e_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
101393 +} e_CommMode;
101394 +
101395 +/**************************************************************************//**
101396 + @Description General Diagnostic Mode
101397 +*//***************************************************************************/
101398 +typedef enum e_DiagMode
101399 +{
101400 + e_DIAG_MODE_NONE = 0, /**< Normal operation; no diagnostic mode */
101401 + e_DIAG_MODE_CTRL_LOOPBACK, /**< Loopback in the controller */
101402 + e_DIAG_MODE_CHIP_LOOPBACK, /**< Loopback in the chip but not in the
101403 + controller; e.g. IO-pins, SerDes, etc. */
101404 + e_DIAG_MODE_PHY_LOOPBACK, /**< Loopback in the external PHY */
101405 + e_DIAG_MODE_EXT_LOOPBACK, /**< Loopback in the external line (beyond the PHY) */
101406 + e_DIAG_MODE_CTRL_ECHO, /**< Echo incoming data by the controller */
101407 + e_DIAG_MODE_PHY_ECHO /**< Echo incoming data by the PHY */
101408 +} e_DiagMode;
101409 +
101410 +/**************************************************************************//**
101411 + @Description Possible RxStore callback responses.
101412 +*//***************************************************************************/
101413 +typedef enum e_RxStoreResponse
101414 +{
101415 + e_RX_STORE_RESPONSE_PAUSE /**< Pause invoking callback with received data;
101416 + in polling mode, start again invoking callback
101417 + only next time user invokes the receive routine;
101418 + in interrupt mode, start again invoking callback
101419 + only next time a receive event triggers an interrupt;
101420 + in all cases, received data that are pending are not
101421 + lost, rather, their processing is temporarily deferred;
101422 + in all cases, received data are processed in the order
101423 + in which they were received. */
101424 + , e_RX_STORE_RESPONSE_CONTINUE /**< Continue invoking callback with received data. */
101425 +} e_RxStoreResponse;
101426 +
101427 +
101428 +/**************************************************************************//**
101429 + @Description General Handle
101430 +*//***************************************************************************/
101431 +typedef void * t_Handle; /**< handle, used as object's descriptor */
101432 +
101433 +/**************************************************************************//**
101434 + @Description MUTEX type
101435 +*//***************************************************************************/
101436 +typedef uint32_t t_Mutex;
101437 +
101438 +/**************************************************************************//**
101439 + @Description Error Code.
101440 +
101441 + The high word of the error code is the code of the software
101442 + module (driver). The low word is the error type (e_ErrorType).
101443 + To get the values from the error code, use GET_ERROR_TYPE()
101444 + and GET_ERROR_MODULE().
101445 +*//***************************************************************************/
101446 +typedef uint32_t t_Error;
101447 +
101448 +/**************************************************************************//**
101449 + @Description General prototype of interrupt service routine (ISR).
101450 +
101451 + @Param[in] handle - Optional handle of the module handling the interrupt.
101452 +
101453 + @Return None
101454 + *//***************************************************************************/
101455 +typedef void (t_Isr)(t_Handle handle);
101456 +
101457 +/**************************************************************************//**
101458 + @Anchor mem_attr
101459 +
101460 + @Collection Memory Attributes
101461 +
101462 + Various attributes of memory partitions. These values may be
101463 + or'ed together to create a mask of all memory attributes.
101464 + @{
101465 +*//***************************************************************************/
101466 +#define MEMORY_ATTR_CACHEABLE 0x00000001
101467 + /**< Memory is cacheable */
101468 +#define MEMORY_ATTR_QE_2ND_BUS_ACCESS 0x00000002
101469 + /**< Memory can be accessed by QUICC Engine
101470 + through its secondary bus interface */
101471 +
101472 +/* @} */
101473 +
101474 +
101475 +/**************************************************************************//**
101476 + @Function t_GetBufFunction
101477 +
101478 + @Description User callback function called by driver to get data buffer.
101479 +
101480 + User provides this function. Driver invokes it.
101481 +
101482 + @Param[in] h_BufferPool - A handle to buffer pool manager
101483 + @Param[out] p_BufContextHandle - Returns the user's private context that
101484 + should be associated with the buffer
101485 +
101486 + @Return Pointer to data buffer, NULL if error
101487 + *//***************************************************************************/
101488 +typedef uint8_t * (t_GetBufFunction)(t_Handle h_BufferPool,
101489 + t_Handle *p_BufContextHandle);
101490 +
101491 +/**************************************************************************//**
101492 + @Function t_PutBufFunction
101493 +
101494 + @Description User callback function called by driver to return data buffer.
101495 +
101496 + User provides this function. Driver invokes it.
101497 +
101498 + @Param[in] h_BufferPool - A handle to buffer pool manager
101499 + @Param[in] p_Buffer - A pointer to buffer to return
101500 + @Param[in] h_BufContext - The user's private context associated with
101501 + the returned buffer
101502 +
101503 + @Return E_OK on success; Error code otherwise
101504 + *//***************************************************************************/
101505 +typedef t_Error (t_PutBufFunction)(t_Handle h_BufferPool,
101506 + uint8_t *p_Buffer,
101507 + t_Handle h_BufContext);
101508 +
101509 +/**************************************************************************//**
101510 + @Function t_PhysToVirt
101511 +
101512 + @Description Translates a physical address to the matching virtual address.
101513 +
101514 + @Param[in] addr - The physical address to translate.
101515 +
101516 + @Return Virtual address.
101517 +*//***************************************************************************/
101518 +typedef void * t_PhysToVirt(physAddress_t addr);
101519 +
101520 +/**************************************************************************//**
101521 + @Function t_VirtToPhys
101522 +
101523 + @Description Translates a virtual address to the matching physical address.
101524 +
101525 + @Param[in] addr - The virtual address to translate.
101526 +
101527 + @Return Physical address.
101528 +*//***************************************************************************/
101529 +typedef physAddress_t t_VirtToPhys(void *addr);
101530 +
101531 +/**************************************************************************//**
101532 + @Description Buffer Pool Information Structure.
101533 +*//***************************************************************************/
101534 +typedef struct t_BufferPoolInfo
101535 +{
101536 + t_Handle h_BufferPool; /**< A handle to the buffer pool manager */
101537 + t_GetBufFunction *f_GetBuf; /**< User callback to get a free buffer */
101538 + t_PutBufFunction *f_PutBuf; /**< User callback to return a buffer */
101539 + uint16_t bufferSize; /**< Buffer size (in bytes) */
101540 +
101541 + t_PhysToVirt *f_PhysToVirt; /**< User callback to translate pool buffers
101542 + physical addresses to virtual addresses */
101543 + t_VirtToPhys *f_VirtToPhys; /**< User callback to translate pool buffers
101544 + virtual addresses to physical addresses */
101545 +} t_BufferPoolInfo;
101546 +
101547 +
101548 +/**************************************************************************//**
101549 + @Description User callback function called by driver when transmit completed.
101550 +
101551 + User provides this function. Driver invokes it.
101552 +
101553 + @Param[in] h_App - Application's handle, as was provided to the
101554 + driver by the user
101555 + @Param[in] queueId - Transmit queue ID
101556 + @Param[in] p_Data - Pointer to the data buffer
101557 + @Param[in] h_BufContext - The user's private context associated with
101558 + the given data buffer
101559 + @Param[in] status - Transmit status and errors
101560 + @Param[in] flags - Driver-dependent information
101561 + *//***************************************************************************/
101562 +typedef void (t_TxConfFunction)(t_Handle h_App,
101563 + uint32_t queueId,
101564 + uint8_t *p_Data,
101565 + t_Handle h_BufContext,
101566 + uint16_t status,
101567 + uint32_t flags);
101568 +
101569 +/**************************************************************************//**
101570 + @Description User callback function called by driver with receive data.
101571 +
101572 + User provides this function. Driver invokes it.
101573 +
101574 + @Param[in] h_App - Application's handle, as was provided to the
101575 + driver by the user
101576 + @Param[in] queueId - Receive queue ID
101577 + @Param[in] p_Data - Pointer to the buffer with received data
101578 + @Param[in] h_BufContext - The user's private context associated with
101579 + the given data buffer
101580 + @Param[in] length - Length of received data
101581 + @Param[in] status - Receive status and errors
101582 + @Param[in] position - Position of buffer in frame
101583 + @Param[in] flags - Driver-dependent information
101584 +
101585 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
101586 + operation for all ready data.
101587 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
101588 + *//***************************************************************************/
101589 +typedef e_RxStoreResponse (t_RxStoreFunction)(t_Handle h_App,
101590 + uint32_t queueId,
101591 + uint8_t *p_Data,
101592 + t_Handle h_BufContext,
101593 + uint32_t length,
101594 + uint16_t status,
101595 + uint8_t position,
101596 + uint32_t flags);
101597 +
101598 +
101599 +#endif /* __NCSW_EXT_H */
101600 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
101601 new file mode 100644
101602 index 00000000..8f3bc369
101603 --- /dev/null
101604 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
101605 @@ -0,0 +1,430 @@
101606 +/*
101607 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101608 + *
101609 + * Redistribution and use in source and binary forms, with or without
101610 + * modification, are permitted provided that the following conditions are met:
101611 + * * Redistributions of source code must retain the above copyright
101612 + * notice, this list of conditions and the following disclaimer.
101613 + * * Redistributions in binary form must reproduce the above copyright
101614 + * notice, this list of conditions and the following disclaimer in the
101615 + * documentation and/or other materials provided with the distribution.
101616 + * * Neither the name of Freescale Semiconductor nor the
101617 + * names of its contributors may be used to endorse or promote products
101618 + * derived from this software without specific prior written permission.
101619 + *
101620 + *
101621 + * ALTERNATIVELY, this software may be distributed under the terms of the
101622 + * GNU General Public License ("GPL") as published by the Free Software
101623 + * Foundation, either version 2 of that License or (at your option) any
101624 + * later version.
101625 + *
101626 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101627 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101628 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101629 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101630 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101631 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101632 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101633 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101634 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101635 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101636 + */
101637 +
101638 +
101639 +/**************************************************************************//**
101640 + @File net_ext.h
101641 +
101642 + @Description This file contains common and general netcomm headers definitions.
101643 +*//***************************************************************************/
101644 +#ifndef __NET_EXT_H
101645 +#define __NET_EXT_H
101646 +
101647 +#include "std_ext.h"
101648 +
101649 +
101650 +typedef uint8_t headerFieldPpp_t;
101651 +
101652 +#define NET_HEADER_FIELD_PPP_PID (1)
101653 +#define NET_HEADER_FIELD_PPP_COMPRESSED (NET_HEADER_FIELD_PPP_PID << 1)
101654 +#define NET_HEADER_FIELD_PPP_ALL_FIELDS ((NET_HEADER_FIELD_PPP_PID << 2) - 1)
101655 +
101656 +
101657 +typedef uint8_t headerFieldPppoe_t;
101658 +
101659 +#define NET_HEADER_FIELD_PPPoE_VER (1)
101660 +#define NET_HEADER_FIELD_PPPoE_TYPE (NET_HEADER_FIELD_PPPoE_VER << 1)
101661 +#define NET_HEADER_FIELD_PPPoE_CODE (NET_HEADER_FIELD_PPPoE_VER << 2)
101662 +#define NET_HEADER_FIELD_PPPoE_SID (NET_HEADER_FIELD_PPPoE_VER << 3)
101663 +#define NET_HEADER_FIELD_PPPoE_LEN (NET_HEADER_FIELD_PPPoE_VER << 4)
101664 +#define NET_HEADER_FIELD_PPPoE_SESSION (NET_HEADER_FIELD_PPPoE_VER << 5)
101665 +#define NET_HEADER_FIELD_PPPoE_PID (NET_HEADER_FIELD_PPPoE_VER << 6)
101666 +#define NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
101667 +
101668 +#define NET_HEADER_FIELD_PPPMUX_PID (1)
101669 +#define NET_HEADER_FIELD_PPPMUX_CKSUM (NET_HEADER_FIELD_PPPMUX_PID << 1)
101670 +#define NET_HEADER_FIELD_PPPMUX_COMPRESSED (NET_HEADER_FIELD_PPPMUX_PID << 2)
101671 +#define NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
101672 +
101673 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
101674 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
101675 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
101676 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
101677 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
101678 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
101679 +
101680 +
101681 +typedef uint8_t headerFieldEth_t;
101682 +
101683 +#define NET_HEADER_FIELD_ETH_DA (1)
101684 +#define NET_HEADER_FIELD_ETH_SA (NET_HEADER_FIELD_ETH_DA << 1)
101685 +#define NET_HEADER_FIELD_ETH_LENGTH (NET_HEADER_FIELD_ETH_DA << 2)
101686 +#define NET_HEADER_FIELD_ETH_TYPE (NET_HEADER_FIELD_ETH_DA << 3)
101687 +#define NET_HEADER_FIELD_ETH_FINAL_CKSUM (NET_HEADER_FIELD_ETH_DA << 4)
101688 +#define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5)
101689 +#define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1)
101690 +
101691 +#define NET_HEADER_FIELD_ETH_ADDR_SIZE 6
101692 +
101693 +typedef uint16_t headerFieldIp_t;
101694 +
101695 +#define NET_HEADER_FIELD_IP_VER (1)
101696 +#define NET_HEADER_FIELD_IP_DSCP (NET_HEADER_FIELD_IP_VER << 2)
101697 +#define NET_HEADER_FIELD_IP_ECN (NET_HEADER_FIELD_IP_VER << 3)
101698 +#define NET_HEADER_FIELD_IP_PROTO (NET_HEADER_FIELD_IP_VER << 4)
101699 +
101700 +#define NET_HEADER_FIELD_IP_PROTO_SIZE 1
101701 +
101702 +typedef uint16_t headerFieldIpv4_t;
101703 +
101704 +#define NET_HEADER_FIELD_IPv4_VER (1)
101705 +#define NET_HEADER_FIELD_IPv4_HDR_LEN (NET_HEADER_FIELD_IPv4_VER << 1)
101706 +#define NET_HEADER_FIELD_IPv4_TOS (NET_HEADER_FIELD_IPv4_VER << 2)
101707 +#define NET_HEADER_FIELD_IPv4_TOTAL_LEN (NET_HEADER_FIELD_IPv4_VER << 3)
101708 +#define NET_HEADER_FIELD_IPv4_ID (NET_HEADER_FIELD_IPv4_VER << 4)
101709 +#define NET_HEADER_FIELD_IPv4_FLAG_D (NET_HEADER_FIELD_IPv4_VER << 5)
101710 +#define NET_HEADER_FIELD_IPv4_FLAG_M (NET_HEADER_FIELD_IPv4_VER << 6)
101711 +#define NET_HEADER_FIELD_IPv4_OFFSET (NET_HEADER_FIELD_IPv4_VER << 7)
101712 +#define NET_HEADER_FIELD_IPv4_TTL (NET_HEADER_FIELD_IPv4_VER << 8)
101713 +#define NET_HEADER_FIELD_IPv4_PROTO (NET_HEADER_FIELD_IPv4_VER << 9)
101714 +#define NET_HEADER_FIELD_IPv4_CKSUM (NET_HEADER_FIELD_IPv4_VER << 10)
101715 +#define NET_HEADER_FIELD_IPv4_SRC_IP (NET_HEADER_FIELD_IPv4_VER << 11)
101716 +#define NET_HEADER_FIELD_IPv4_DST_IP (NET_HEADER_FIELD_IPv4_VER << 12)
101717 +#define NET_HEADER_FIELD_IPv4_OPTS (NET_HEADER_FIELD_IPv4_VER << 13)
101718 +#define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14)
101719 +#define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1)
101720 +
101721 +#define NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
101722 +#define NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
101723 +
101724 +
101725 +typedef uint8_t headerFieldIpv6_t;
101726 +
101727 +#define NET_HEADER_FIELD_IPv6_VER (1)
101728 +#define NET_HEADER_FIELD_IPv6_TC (NET_HEADER_FIELD_IPv6_VER << 1)
101729 +#define NET_HEADER_FIELD_IPv6_SRC_IP (NET_HEADER_FIELD_IPv6_VER << 2)
101730 +#define NET_HEADER_FIELD_IPv6_DST_IP (NET_HEADER_FIELD_IPv6_VER << 3)
101731 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR (NET_HEADER_FIELD_IPv6_VER << 4)
101732 +#define NET_HEADER_FIELD_IPv6_FL (NET_HEADER_FIELD_IPv6_VER << 5)
101733 +#define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6)
101734 +#define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1)
101735 +
101736 +#define NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
101737 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
101738 +
101739 +#define NET_HEADER_FIELD_ICMP_TYPE (1)
101740 +#define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1)
101741 +#define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2)
101742 +#define NET_HEADER_FIELD_ICMP_ID (NET_HEADER_FIELD_ICMP_TYPE << 3)
101743 +#define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4)
101744 +#define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
101745 +
101746 +#define NET_HEADER_FIELD_ICMP_CODE_SIZE 1
101747 +#define NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
101748 +
101749 +#define NET_HEADER_FIELD_IGMP_VERSION (1)
101750 +#define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1)
101751 +#define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2)
101752 +#define NET_HEADER_FIELD_IGMP_DATA (NET_HEADER_FIELD_IGMP_VERSION << 3)
101753 +#define NET_HEADER_FIELD_IGMP_ALL_FIELDS ((NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
101754 +
101755 +
101756 +typedef uint16_t headerFieldTcp_t;
101757 +
101758 +#define NET_HEADER_FIELD_TCP_PORT_SRC (1)
101759 +#define NET_HEADER_FIELD_TCP_PORT_DST (NET_HEADER_FIELD_TCP_PORT_SRC << 1)
101760 +#define NET_HEADER_FIELD_TCP_SEQ (NET_HEADER_FIELD_TCP_PORT_SRC << 2)
101761 +#define NET_HEADER_FIELD_TCP_ACK (NET_HEADER_FIELD_TCP_PORT_SRC << 3)
101762 +#define NET_HEADER_FIELD_TCP_OFFSET (NET_HEADER_FIELD_TCP_PORT_SRC << 4)
101763 +#define NET_HEADER_FIELD_TCP_FLAGS (NET_HEADER_FIELD_TCP_PORT_SRC << 5)
101764 +#define NET_HEADER_FIELD_TCP_WINDOW (NET_HEADER_FIELD_TCP_PORT_SRC << 6)
101765 +#define NET_HEADER_FIELD_TCP_CKSUM (NET_HEADER_FIELD_TCP_PORT_SRC << 7)
101766 +#define NET_HEADER_FIELD_TCP_URGPTR (NET_HEADER_FIELD_TCP_PORT_SRC << 8)
101767 +#define NET_HEADER_FIELD_TCP_OPTS (NET_HEADER_FIELD_TCP_PORT_SRC << 9)
101768 +#define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10)
101769 +#define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
101770 +
101771 +#define NET_HEADER_FIELD_TCP_PORT_SIZE 2
101772 +
101773 +
101774 +typedef uint8_t headerFieldSctp_t;
101775 +
101776 +#define NET_HEADER_FIELD_SCTP_PORT_SRC (1)
101777 +#define NET_HEADER_FIELD_SCTP_PORT_DST (NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
101778 +#define NET_HEADER_FIELD_SCTP_VER_TAG (NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
101779 +#define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
101780 +#define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
101781 +
101782 +#define NET_HEADER_FIELD_SCTP_PORT_SIZE 2
101783 +
101784 +typedef uint8_t headerFieldDccp_t;
101785 +
101786 +#define NET_HEADER_FIELD_DCCP_PORT_SRC (1)
101787 +#define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
101788 +#define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
101789 +
101790 +#define NET_HEADER_FIELD_DCCP_PORT_SIZE 2
101791 +
101792 +
101793 +typedef uint8_t headerFieldUdp_t;
101794 +
101795 +#define NET_HEADER_FIELD_UDP_PORT_SRC (1)
101796 +#define NET_HEADER_FIELD_UDP_PORT_DST (NET_HEADER_FIELD_UDP_PORT_SRC << 1)
101797 +#define NET_HEADER_FIELD_UDP_LEN (NET_HEADER_FIELD_UDP_PORT_SRC << 2)
101798 +#define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3)
101799 +#define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
101800 +
101801 +#define NET_HEADER_FIELD_UDP_PORT_SIZE 2
101802 +
101803 +typedef uint8_t headerFieldUdpLite_t;
101804 +
101805 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
101806 +#define NET_HEADER_FIELD_UDP_LITE_PORT_DST (NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
101807 +#define NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
101808 +
101809 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
101810 +
101811 +typedef uint8_t headerFieldUdpEncapEsp_t;
101812 +
101813 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
101814 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
101815 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
101816 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
101817 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
101818 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
101819 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
101820 +
101821 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
101822 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
101823 +
101824 +#define NET_HEADER_FIELD_IPHC_CID (1)
101825 +#define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1)
101826 +#define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2)
101827 +#define NET_HEADER_FIELD_IPHC_GEN (NET_HEADER_FIELD_IPHC_CID << 3)
101828 +#define NET_HEADER_FIELD_IPHC_D_BIT (NET_HEADER_FIELD_IPHC_CID << 4)
101829 +#define NET_HEADER_FIELD_IPHC_ALL_FIELDS ((NET_HEADER_FIELD_IPHC_CID << 5) - 1)
101830 +
101831 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
101832 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
101833 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
101834 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
101835 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
101836 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
101837 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
101838 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
101839 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
101840 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
101841 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
101842 +
101843 +#define NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
101844 +#define NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
101845 +#define NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
101846 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
101847 +#define NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
101848 +#define NET_HEADER_FIELD_L2TPv2_VERSION (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
101849 +#define NET_HEADER_FIELD_L2TPv2_LEN (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
101850 +#define NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
101851 +#define NET_HEADER_FIELD_L2TPv2_SESSION_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
101852 +#define NET_HEADER_FIELD_L2TPv2_NS (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
101853 +#define NET_HEADER_FIELD_L2TPv2_NR (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
101854 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
101855 +#define NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
101856 +#define NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
101857 +
101858 +#define NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
101859 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
101860 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
101861 +#define NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
101862 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
101863 +#define NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
101864 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SENT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
101865 +#define NET_HEADER_FIELD_L2TPv3_CTRL_RECV (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
101866 +#define NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
101867 +#define NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
101868 +
101869 +#define NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
101870 +#define NET_HEADER_FIELD_L2TPv3_SESS_VERSION (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
101871 +#define NET_HEADER_FIELD_L2TPv3_SESS_ID (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
101872 +#define NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
101873 +#define NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
101874 +
101875 +
101876 +typedef uint8_t headerFieldVlan_t;
101877 +
101878 +#define NET_HEADER_FIELD_VLAN_VPRI (1)
101879 +#define NET_HEADER_FIELD_VLAN_CFI (NET_HEADER_FIELD_VLAN_VPRI << 1)
101880 +#define NET_HEADER_FIELD_VLAN_VID (NET_HEADER_FIELD_VLAN_VPRI << 2)
101881 +#define NET_HEADER_FIELD_VLAN_LENGTH (NET_HEADER_FIELD_VLAN_VPRI << 3)
101882 +#define NET_HEADER_FIELD_VLAN_TYPE (NET_HEADER_FIELD_VLAN_VPRI << 4)
101883 +#define NET_HEADER_FIELD_VLAN_ALL_FIELDS ((NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
101884 +
101885 +#define NET_HEADER_FIELD_VLAN_TCI (NET_HEADER_FIELD_VLAN_VPRI | \
101886 + NET_HEADER_FIELD_VLAN_CFI | \
101887 + NET_HEADER_FIELD_VLAN_VID)
101888 +
101889 +
101890 +typedef uint8_t headerFieldLlc_t;
101891 +
101892 +#define NET_HEADER_FIELD_LLC_DSAP (1)
101893 +#define NET_HEADER_FIELD_LLC_SSAP (NET_HEADER_FIELD_LLC_DSAP << 1)
101894 +#define NET_HEADER_FIELD_LLC_CTRL (NET_HEADER_FIELD_LLC_DSAP << 2)
101895 +#define NET_HEADER_FIELD_LLC_ALL_FIELDS ((NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
101896 +
101897 +#define NET_HEADER_FIELD_NLPID_NLPID (1)
101898 +#define NET_HEADER_FIELD_NLPID_ALL_FIELDS ((NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
101899 +
101900 +
101901 +typedef uint8_t headerFieldSnap_t;
101902 +
101903 +#define NET_HEADER_FIELD_SNAP_OUI (1)
101904 +#define NET_HEADER_FIELD_SNAP_PID (NET_HEADER_FIELD_SNAP_OUI << 1)
101905 +#define NET_HEADER_FIELD_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
101906 +
101907 +
101908 +typedef uint8_t headerFieldLlcSnap_t;
101909 +
101910 +#define NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
101911 +#define NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
101912 +
101913 +#define NET_HEADER_FIELD_ARP_HTYPE (1)
101914 +#define NET_HEADER_FIELD_ARP_PTYPE (NET_HEADER_FIELD_ARP_HTYPE << 1)
101915 +#define NET_HEADER_FIELD_ARP_HLEN (NET_HEADER_FIELD_ARP_HTYPE << 2)
101916 +#define NET_HEADER_FIELD_ARP_PLEN (NET_HEADER_FIELD_ARP_HTYPE << 3)
101917 +#define NET_HEADER_FIELD_ARP_OPER (NET_HEADER_FIELD_ARP_HTYPE << 4)
101918 +#define NET_HEADER_FIELD_ARP_SHA (NET_HEADER_FIELD_ARP_HTYPE << 5)
101919 +#define NET_HEADER_FIELD_ARP_SPA (NET_HEADER_FIELD_ARP_HTYPE << 6)
101920 +#define NET_HEADER_FIELD_ARP_THA (NET_HEADER_FIELD_ARP_HTYPE << 7)
101921 +#define NET_HEADER_FIELD_ARP_TPA (NET_HEADER_FIELD_ARP_HTYPE << 8)
101922 +#define NET_HEADER_FIELD_ARP_ALL_FIELDS ((NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
101923 +
101924 +#define NET_HEADER_FIELD_RFC2684_LLC (1)
101925 +#define NET_HEADER_FIELD_RFC2684_NLPID (NET_HEADER_FIELD_RFC2684_LLC << 1)
101926 +#define NET_HEADER_FIELD_RFC2684_OUI (NET_HEADER_FIELD_RFC2684_LLC << 2)
101927 +#define NET_HEADER_FIELD_RFC2684_PID (NET_HEADER_FIELD_RFC2684_LLC << 3)
101928 +#define NET_HEADER_FIELD_RFC2684_VPN_OUI (NET_HEADER_FIELD_RFC2684_LLC << 4)
101929 +#define NET_HEADER_FIELD_RFC2684_VPN_IDX (NET_HEADER_FIELD_RFC2684_LLC << 5)
101930 +#define NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
101931 +
101932 +#define NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
101933 +#define NET_HEADER_FIELD_USER_DEFINED_PCDID (NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
101934 +#define NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
101935 +
101936 +#define NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
101937 +#define NET_HEADER_FIELD_PAYLOAD_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
101938 +#define NET_HEADER_FIELD_MAX_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
101939 +#define NET_HEADER_FIELD_MIN_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
101940 +#define NET_HEADER_FIELD_PAYLOAD_TYPE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
101941 +#define NET_HEADER_FIELD_FRAME_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
101942 +#define NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
101943 +
101944 +
101945 +typedef uint8_t headerFieldGre_t;
101946 +
101947 +#define NET_HEADER_FIELD_GRE_TYPE (1)
101948 +#define NET_HEADER_FIELD_GRE_ALL_FIELDS ((NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
101949 +
101950 +
101951 +typedef uint8_t headerFieldMinencap_t;
101952 +
101953 +#define NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
101954 +#define NET_HEADER_FIELD_MINENCAP_DST_IP (NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
101955 +#define NET_HEADER_FIELD_MINENCAP_TYPE (NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
101956 +#define NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
101957 +
101958 +
101959 +typedef uint8_t headerFieldIpsecAh_t;
101960 +
101961 +#define NET_HEADER_FIELD_IPSEC_AH_SPI (1)
101962 +#define NET_HEADER_FIELD_IPSEC_AH_NH (NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
101963 +#define NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
101964 +
101965 +
101966 +typedef uint8_t headerFieldIpsecEsp_t;
101967 +
101968 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
101969 +#define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
101970 +#define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
101971 +
101972 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
101973 +
101974 +
101975 +typedef uint8_t headerFieldMpls_t;
101976 +
101977 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
101978 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
101979 +
101980 +
101981 +typedef uint8_t headerFieldMacsec_t;
101982 +
101983 +#define NET_HEADER_FIELD_MACSEC_SECTAG (1)
101984 +#define NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
101985 +
101986 +
101987 +typedef enum {
101988 + HEADER_TYPE_NONE = 0,
101989 + HEADER_TYPE_PAYLOAD,
101990 + HEADER_TYPE_ETH,
101991 + HEADER_TYPE_VLAN,
101992 + HEADER_TYPE_IPv4,
101993 + HEADER_TYPE_IPv6,
101994 + HEADER_TYPE_IP,
101995 + HEADER_TYPE_TCP,
101996 + HEADER_TYPE_UDP,
101997 + HEADER_TYPE_UDP_LITE,
101998 + HEADER_TYPE_IPHC,
101999 + HEADER_TYPE_SCTP,
102000 + HEADER_TYPE_SCTP_CHUNK_DATA,
102001 + HEADER_TYPE_PPPoE,
102002 + HEADER_TYPE_PPP,
102003 + HEADER_TYPE_PPPMUX,
102004 + HEADER_TYPE_PPPMUX_SUBFRAME,
102005 + HEADER_TYPE_L2TPv2,
102006 + HEADER_TYPE_L2TPv3_CTRL,
102007 + HEADER_TYPE_L2TPv3_SESS,
102008 + HEADER_TYPE_LLC,
102009 + HEADER_TYPE_LLC_SNAP,
102010 + HEADER_TYPE_NLPID,
102011 + HEADER_TYPE_SNAP,
102012 + HEADER_TYPE_MPLS,
102013 + HEADER_TYPE_IPSEC_AH,
102014 + HEADER_TYPE_IPSEC_ESP,
102015 + HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
102016 + HEADER_TYPE_MACSEC,
102017 + HEADER_TYPE_GRE,
102018 + HEADER_TYPE_MINENCAP,
102019 + HEADER_TYPE_DCCP,
102020 + HEADER_TYPE_ICMP,
102021 + HEADER_TYPE_IGMP,
102022 + HEADER_TYPE_ARP,
102023 + HEADER_TYPE_CAPWAP,
102024 + HEADER_TYPE_CAPWAP_DTLS,
102025 + HEADER_TYPE_RFC2684,
102026 + HEADER_TYPE_USER_DEFINED_L2,
102027 + HEADER_TYPE_USER_DEFINED_L3,
102028 + HEADER_TYPE_USER_DEFINED_L4,
102029 + HEADER_TYPE_USER_DEFINED_SHIM1,
102030 + HEADER_TYPE_USER_DEFINED_SHIM2,
102031 + MAX_HEADER_TYPE_COUNT
102032 +} e_NetHeaderType;
102033 +
102034 +
102035 +#endif /* __NET_EXT_H */
102036 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
102037 new file mode 100644
102038 index 00000000..d91e6fdd
102039 --- /dev/null
102040 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
102041 @@ -0,0 +1,48 @@
102042 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102043 + * All rights reserved.
102044 + *
102045 + * Redistribution and use in source and binary forms, with or without
102046 + * modification, are permitted provided that the following conditions are met:
102047 + * * Redistributions of source code must retain the above copyright
102048 + * notice, this list of conditions and the following disclaimer.
102049 + * * Redistributions in binary form must reproduce the above copyright
102050 + * notice, this list of conditions and the following disclaimer in the
102051 + * documentation and/or other materials provided with the distribution.
102052 + * * Neither the name of Freescale Semiconductor nor the
102053 + * names of its contributors may be used to endorse or promote products
102054 + * derived from this software without specific prior written permission.
102055 + *
102056 + *
102057 + * ALTERNATIVELY, this software may be distributed under the terms of the
102058 + * GNU General Public License ("GPL") as published by the Free Software
102059 + * Foundation, either version 2 of that License or (at your option) any
102060 + * later version.
102061 + *
102062 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102063 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102064 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102065 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102066 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102067 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102068 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102069 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102070 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102071 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102072 + */
102073 +
102074 +
102075 +/**************************************************************************//**
102076 + @File std_ext.h
102077 +
102078 + @Description General Standard Definitions
102079 +*//***************************************************************************/
102080 +
102081 +#ifndef __STD_EXT_H
102082 +#define __STD_EXT_H
102083 +
102084 +
102085 +#include "types_ext.h"
102086 +#include "ncsw_ext.h"
102087 +
102088 +
102089 +#endif /* __STD_EXT_H */
102090 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
102091 new file mode 100644
102092 index 00000000..3c8bb0a0
102093 --- /dev/null
102094 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
102095 @@ -0,0 +1,49 @@
102096 +/*
102097 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102098 + *
102099 + * Redistribution and use in source and binary forms, with or without
102100 + * modification, are permitted provided that the following conditions are met:
102101 + * * Redistributions of source code must retain the above copyright
102102 + * notice, this list of conditions and the following disclaimer.
102103 + * * Redistributions in binary form must reproduce the above copyright
102104 + * notice, this list of conditions and the following disclaimer in the
102105 + * documentation and/or other materials provided with the distribution.
102106 + * * Neither the name of Freescale Semiconductor nor the
102107 + * names of its contributors may be used to endorse or promote products
102108 + * derived from this software without specific prior written permission.
102109 + *
102110 + *
102111 + * ALTERNATIVELY, this software may be distributed under the terms of the
102112 + * GNU General Public License ("GPL") as published by the Free Software
102113 + * Foundation, either version 2 of that License or (at your option) any
102114 + * later version.
102115 + *
102116 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102117 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102118 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102119 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102120 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102121 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102122 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102123 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102124 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102125 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102126 + */
102127 +
102128 +
102129 +#ifndef __STDARG_EXT_H
102130 +#define __STDARG_EXT_H
102131 +
102132 +
102133 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
102134 +#include <stdarg.h>
102135 +
102136 +#else
102137 +#include <stdarg.h>
102138 +
102139 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
102140 +
102141 +#include "std_ext.h"
102142 +
102143 +
102144 +#endif /* __STDARG_EXT_H */
102145 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
102146 new file mode 100644
102147 index 00000000..a47860cf
102148 --- /dev/null
102149 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
102150 @@ -0,0 +1,162 @@
102151 +/*
102152 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102153 + *
102154 + * Redistribution and use in source and binary forms, with or without
102155 + * modification, are permitted provided that the following conditions are met:
102156 + * * Redistributions of source code must retain the above copyright
102157 + * notice, this list of conditions and the following disclaimer.
102158 + * * Redistributions in binary form must reproduce the above copyright
102159 + * notice, this list of conditions and the following disclaimer in the
102160 + * documentation and/or other materials provided with the distribution.
102161 + * * Neither the name of Freescale Semiconductor nor the
102162 + * names of its contributors may be used to endorse or promote products
102163 + * derived from this software without specific prior written permission.
102164 + *
102165 + *
102166 + * ALTERNATIVELY, this software may be distributed under the terms of the
102167 + * GNU General Public License ("GPL") as published by the Free Software
102168 + * Foundation, either version 2 of that License or (at your option) any
102169 + * later version.
102170 + *
102171 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102172 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102173 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102174 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102175 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102176 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102177 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102178 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102179 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102180 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102181 + */
102182 +
102183 +
102184 +
102185 +#ifndef __STDLIB_EXT_H
102186 +#define __STDLIB_EXT_H
102187 +
102188 +
102189 +#if (defined(NCSW_LINUX)) && defined(__KERNEL__)
102190 +#include "stdarg_ext.h"
102191 +#include "std_ext.h"
102192 +
102193 +
102194 +/**
102195 + * strtoul - convert a string to an uint32_t
102196 + * @cp: The start of the string
102197 + * @endp: A pointer to the end of the parsed string will be placed here
102198 + * @base: The number base to use
102199 + */
102200 +uint32_t strtoul(const char *cp,char **endp,uint32_t base);
102201 +
102202 +/**
102203 + * strtol - convert a string to a int32_t
102204 + * @cp: The start of the string
102205 + * @endp: A pointer to the end of the parsed string will be placed here
102206 + * @base: The number base to use
102207 + */
102208 +long strtol(const char *cp,char **endp,uint32_t base);
102209 +
102210 +/**
102211 + * strtoull - convert a string to an uint64_t
102212 + * @cp: The start of the string
102213 + * @endp: A pointer to the end of the parsed string will be placed here
102214 + * @base: The number base to use
102215 + */
102216 +uint64_t strtoull(const char *cp,char **endp,uint32_t base);
102217 +
102218 +/**
102219 + * strtoll - convert a string to a int64 long
102220 + * @cp: The start of the string
102221 + * @endp: A pointer to the end of the parsed string will be placed here
102222 + * @base: The number base to use
102223 + */
102224 +long long strtoll(const char *cp,char **endp,uint32_t base);
102225 +
102226 +/**
102227 + * atoi - convert a character to a int
102228 + * @s: The start of the string
102229 + */
102230 +int atoi(const char *s);
102231 +
102232 +/**
102233 + * strnlen - Find the length of a length-limited string
102234 + * @s: The string to be sized
102235 + * @count: The maximum number of bytes to search
102236 + */
102237 +size_t strnlen(const char * s, size_t count);
102238 +
102239 +/**
102240 + * strlen - Find the length of a string
102241 + * @s: The string to be sized
102242 + */
102243 +size_t strlen(const char * s);
102244 +
102245 +/**
102246 + * strtok - Split a string into tokens
102247 + * @s: The string to be searched
102248 + * @ct: The characters to search for
102249 + *
102250 + * WARNING: strtok is deprecated, use strsep instead.
102251 + */
102252 +char * strtok(char * s,const char * ct);
102253 +
102254 +/**
102255 + * strncpy - Copy a length-limited, %NUL-terminated string
102256 + * @dest: Where to copy the string to
102257 + * @src: Where to copy the string from
102258 + * @count: The maximum number of bytes to copy
102259 + *
102260 + * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
102261 + * However, the result is not %NUL-terminated if the source exceeds
102262 + * @count bytes.
102263 + */
102264 +char * strncpy(char * dest,const char *src,size_t count);
102265 +
102266 +/**
102267 + * strcpy - Copy a %NUL terminated string
102268 + * @dest: Where to copy the string to
102269 + * @src: Where to copy the string from
102270 + */
102271 +char * strcpy(char * dest,const char *src);
102272 +
102273 +/**
102274 + * vsscanf - Unformat a buffer into a list of arguments
102275 + * @buf: input buffer
102276 + * @fmt: format of buffer
102277 + * @args: arguments
102278 + */
102279 +int vsscanf(const char * buf, const char * fmt, va_list args);
102280 +
102281 +/**
102282 + * vsnprintf - Format a string and place it in a buffer
102283 + * @buf: The buffer to place the result into
102284 + * @size: The size of the buffer, including the trailing null space
102285 + * @fmt: The format string to use
102286 + * @args: Arguments for the format string
102287 + *
102288 + * Call this function if you are already dealing with a va_list.
102289 + * You probably want snprintf instead.
102290 + */
102291 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
102292 +
102293 +/**
102294 + * vsprintf - Format a string and place it in a buffer
102295 + * @buf: The buffer to place the result into
102296 + * @fmt: The format string to use
102297 + * @args: Arguments for the format string
102298 + *
102299 + * Call this function if you are already dealing with a va_list.
102300 + * You probably want sprintf instead.
102301 + */
102302 +int vsprintf(char *buf, const char *fmt, va_list args);
102303 +
102304 +#else
102305 +#include <stdlib.h>
102306 +#include <stdio.h>
102307 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
102308 +
102309 +#include "std_ext.h"
102310 +
102311 +
102312 +#endif /* __STDLIB_EXT_H */
102313 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
102314 new file mode 100644
102315 index 00000000..a5c6c7e0
102316 --- /dev/null
102317 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
102318 @@ -0,0 +1,56 @@
102319 +/*
102320 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102321 + *
102322 + * Redistribution and use in source and binary forms, with or without
102323 + * modification, are permitted provided that the following conditions are met:
102324 + * * Redistributions of source code must retain the above copyright
102325 + * notice, this list of conditions and the following disclaimer.
102326 + * * Redistributions in binary form must reproduce the above copyright
102327 + * notice, this list of conditions and the following disclaimer in the
102328 + * documentation and/or other materials provided with the distribution.
102329 + * * Neither the name of Freescale Semiconductor nor the
102330 + * names of its contributors may be used to endorse or promote products
102331 + * derived from this software without specific prior written permission.
102332 + *
102333 + *
102334 + * ALTERNATIVELY, this software may be distributed under the terms of the
102335 + * GNU General Public License ("GPL") as published by the Free Software
102336 + * Foundation, either version 2 of that License or (at your option) any
102337 + * later version.
102338 + *
102339 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102340 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102341 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102342 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102343 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102344 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102345 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102346 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102347 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102348 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102349 + */
102350 +
102351 +
102352 +#ifndef __STRING_EXT_H
102353 +#define __STRING_EXT_H
102354 +
102355 +
102356 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
102357 +#include <linux/kernel.h>
102358 +#include <linux/string.h>
102359 +extern char * strtok ( char * str, const char * delimiters );
102360 +
102361 +#elif defined(__KERNEL__)
102362 +#include "linux/types.h"
102363 +#include "linux/posix_types.h"
102364 +#include "linux/string.h"
102365 +
102366 +#else
102367 +#include <string.h>
102368 +
102369 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
102370 +
102371 +#include "std_ext.h"
102372 +
102373 +
102374 +#endif /* __STRING_EXT_H */
102375 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
102376 new file mode 100644
102377 index 00000000..8c87edb7
102378 --- /dev/null
102379 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
102380 @@ -0,0 +1,62 @@
102381 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102382 + * All rights reserved.
102383 + *
102384 + * Redistribution and use in source and binary forms, with or without
102385 + * modification, are permitted provided that the following conditions are met:
102386 + * * Redistributions of source code must retain the above copyright
102387 + * notice, this list of conditions and the following disclaimer.
102388 + * * Redistributions in binary form must reproduce the above copyright
102389 + * notice, this list of conditions and the following disclaimer in the
102390 + * documentation and/or other materials provided with the distribution.
102391 + * * Neither the name of Freescale Semiconductor nor the
102392 + * names of its contributors may be used to endorse or promote products
102393 + * derived from this software without specific prior written permission.
102394 + *
102395 + *
102396 + * ALTERNATIVELY, this software may be distributed under the terms of the
102397 + * GNU General Public License ("GPL") as published by the Free Software
102398 + * Foundation, either version 2 of that License or (at your option) any
102399 + * later version.
102400 + *
102401 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102402 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102403 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102404 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102405 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102406 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102407 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102408 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102409 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102410 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102411 + */
102412 +
102413 +
102414 +/**************************************************************************//**
102415 + @File types_ext.h
102416 +
102417 + @Description General types Standard Definitions
102418 +*//***************************************************************************/
102419 +
102420 +#ifndef __TYPES_EXT_H
102421 +#define __TYPES_EXT_H
102422 +
102423 +#if defined(NCSW_LINUX)
102424 +#include "types_linux.h"
102425 +
102426 +#elif defined(NCSW_VXWORKS)
102427 +#include "types_vxworks.h"
102428 +
102429 +#elif defined(__GNUC__) && defined(__cplusplus)
102430 +#include "types_bb_gpp.h"
102431 +
102432 +#elif defined(__GNUC__)
102433 +#include "types_bb_gcc.h"
102434 +
102435 +#elif defined(__ghs__)
102436 +#include "types_ghs.h"
102437 +
102438 +#else
102439 +#include "types_dflt.h"
102440 +#endif /* defined (__ROCOO__) */
102441 +
102442 +#endif /* __TYPES_EXT_H */
102443 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
102444 new file mode 100644
102445 index 00000000..8e81094b
102446 --- /dev/null
102447 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
102448 @@ -0,0 +1,56 @@
102449 +/*
102450 + * Copyright 2012 Freescale Semiconductor Inc.
102451 + *
102452 + * Redistribution and use in source and binary forms, with or without
102453 + * modification, are permitted provided that the following conditions are met:
102454 + * * Redistributions of source code must retain the above copyright
102455 + * notice, this list of conditions and the following disclaimer.
102456 + * * Redistributions in binary form must reproduce the above copyright
102457 + * notice, this list of conditions and the following disclaimer in the
102458 + * documentation and/or other materials provided with the distribution.
102459 + * * Neither the name of Freescale Semiconductor nor the
102460 + * names of its contributors may be used to endorse or promote products
102461 + * derived from this software without specific prior written permission.
102462 + *
102463 + *
102464 + * ALTERNATIVELY, this software may be distributed under the terms of the
102465 + * GNU General Public License ("GPL") as published by the Free Software
102466 + * Foundation, either version 2 of that License or (at your option) any
102467 + * later version.
102468 + *
102469 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102470 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102471 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102472 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102473 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102474 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102475 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102476 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102477 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102478 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102479 + */
102480 +
102481 +
102482 +/**************************************************************************//**
102483 + @File debug_ext.h
102484 +
102485 + @Description Debug mode definitions.
102486 +*//***************************************************************************/
102487 +
102488 +#ifndef __XX_COMMON_H
102489 +#define __XX_COMMON_H
102490 +
102491 +/*****************************************************************************
102492 + * UNIFIED MODULE CODES
102493 + *****************************************************************************/
102494 +#define MODULE_UNKNOWN 0x00000000
102495 +#define MODULE_FM 0x00010000
102496 +#define MODULE_FM_MURAM 0x00020000
102497 +#define MODULE_FM_PCD 0x00030000
102498 +#define MODULE_FM_RTC 0x00040000
102499 +#define MODULE_FM_MAC 0x00050000
102500 +#define MODULE_FM_PORT 0x00060000
102501 +#define MODULE_MM 0x00070000
102502 +#define MODULE_FM_SP 0x00080000
102503 +#define MODULE_FM_MACSEC 0x00090000
102504 +#endif /* __XX_COMMON_H */
102505 diff --git a/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
102506 new file mode 100644
102507 index 00000000..21b62d0a
102508 --- /dev/null
102509 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
102510 @@ -0,0 +1,791 @@
102511 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102512 + * All rights reserved.
102513 + *
102514 + * Redistribution and use in source and binary forms, with or without
102515 + * modification, are permitted provided that the following conditions are met:
102516 + * * Redistributions of source code must retain the above copyright
102517 + * notice, this list of conditions and the following disclaimer.
102518 + * * Redistributions in binary form must reproduce the above copyright
102519 + * notice, this list of conditions and the following disclaimer in the
102520 + * documentation and/or other materials provided with the distribution.
102521 + * * Neither the name of Freescale Semiconductor nor the
102522 + * names of its contributors may be used to endorse or promote products
102523 + * derived from this software without specific prior written permission.
102524 + *
102525 + *
102526 + * ALTERNATIVELY, this software may be distributed under the terms of the
102527 + * GNU General Public License ("GPL") as published by the Free Software
102528 + * Foundation, either version 2 of that License or (at your option) any
102529 + * later version.
102530 + *
102531 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102532 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102533 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102534 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102535 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102536 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102537 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102538 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102539 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102540 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102541 + */
102542 +
102543 +
102544 +/**************************************************************************//**
102545 + @File xx_ext.h
102546 +
102547 + @Description Prototypes, externals and typedefs for system-supplied
102548 + (external) routines
102549 +*//***************************************************************************/
102550 +
102551 +#ifndef __XX_EXT_H
102552 +#define __XX_EXT_H
102553 +
102554 +#include "std_ext.h"
102555 +#include "xx_common.h"
102556 +#include "part_ext.h"
102557 +
102558 +
102559 +
102560 +/**************************************************************************//**
102561 + @Group xx_id XX Interface (System call hooks)
102562 +
102563 + @Description Prototypes, externals and typedefs for system-supplied
102564 + (external) routines
102565 +
102566 + @{
102567 +*//***************************************************************************/
102568 +
102569 +#ifdef DEBUG_XX_MALLOC
102570 +void * XX_MallocDebug(uint32_t size, char *fname, int line);
102571 +
102572 +void * XX_MallocSmartDebug(uint32_t size,
102573 + int memPartitionId,
102574 + uint32_t alignment,
102575 + char *fname,
102576 + int line);
102577 +
102578 +#define XX_Malloc(sz) \
102579 + XX_MallocDebug((sz), __FILE__, __LINE__)
102580 +
102581 +#define XX_MallocSmart(sz, memt, al) \
102582 + XX_MallocSmartDebug((sz), (memt), (al), __FILE__, __LINE__)
102583 +
102584 +#else /* not DEBUG_XX_MALLOC */
102585 +/**************************************************************************//**
102586 + @Function XX_Malloc
102587 +
102588 + @Description allocates contiguous block of memory.
102589 +
102590 + @Param[in] size - Number of bytes to allocate.
102591 +
102592 + @Return The address of the newly allocated block on success, NULL on failure.
102593 +*//***************************************************************************/
102594 +void * XX_Malloc(uint32_t size);
102595 +
102596 +/**************************************************************************//**
102597 + @Function XX_MallocSmart
102598 +
102599 + @Description Allocates contiguous block of memory in a specified
102600 + alignment and from the specified segment.
102601 +
102602 + @Param[in] size - Number of bytes to allocate.
102603 + @Param[in] memPartitionId - Memory partition ID; The value zero must
102604 + be mapped to the default heap partition.
102605 + @Param[in] alignment - Required memory alignment (in bytes).
102606 +
102607 + @Return The address of the newly allocated block on success, NULL on failure.
102608 +*//***************************************************************************/
102609 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment);
102610 +#endif /* not DEBUG_XX_MALLOC */
102611 +
102612 +/**************************************************************************//**
102613 + @Function XX_FreeSmart
102614 +
102615 + @Description Frees the memory block pointed to by "p".
102616 + Only for memory allocated by XX_MallocSmart
102617 +
102618 + @Param[in] p_Memory - pointer to the memory block.
102619 +
102620 + @Return None.
102621 +*//***************************************************************************/
102622 +void XX_FreeSmart(void *p_Memory);
102623 +
102624 +/**************************************************************************//**
102625 + @Function XX_Free
102626 +
102627 + @Description frees the memory block pointed to by "p".
102628 +
102629 + @Param[in] p_Memory - pointer to the memory block.
102630 +
102631 + @Return None.
102632 +*//***************************************************************************/
102633 +void XX_Free(void *p_Memory);
102634 +
102635 +/**************************************************************************//**
102636 + @Function XX_Print
102637 +
102638 + @Description print a string.
102639 +
102640 + @Param[in] str - string to print.
102641 +
102642 + @Return None.
102643 +*//***************************************************************************/
102644 +void XX_Print(char *str, ...);
102645 +
102646 +/**************************************************************************//**
102647 + @Function XX_SetIntr
102648 +
102649 + @Description Set an interrupt service routine for a specific interrupt source.
102650 +
102651 + @Param[in] irq - Interrupt ID (system-specific number).
102652 + @Param[in] f_Isr - Callback routine that will be called when the interrupt occurs.
102653 + @Param[in] handle - The argument for the user callback routine.
102654 +
102655 + @Return E_OK on success; error code otherwise..
102656 +*//***************************************************************************/
102657 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle);
102658 +
102659 +/**************************************************************************//**
102660 + @Function XX_FreeIntr
102661 +
102662 + @Description Free a specific interrupt and a specific callback routine.
102663 +
102664 + @Param[in] irq - Interrupt ID (system-specific number).
102665 +
102666 + @Return E_OK on success; error code otherwise..
102667 +*//***************************************************************************/
102668 +t_Error XX_FreeIntr(int irq);
102669 +
102670 +/**************************************************************************//**
102671 + @Function XX_EnableIntr
102672 +
102673 + @Description Enable a specific interrupt.
102674 +
102675 + @Param[in] irq - Interrupt ID (system-specific number).
102676 +
102677 + @Return E_OK on success; error code otherwise..
102678 +*//***************************************************************************/
102679 +t_Error XX_EnableIntr(int irq);
102680 +
102681 +/**************************************************************************//**
102682 + @Function XX_DisableIntr
102683 +
102684 + @Description Disable a specific interrupt.
102685 +
102686 + @Param[in] irq - Interrupt ID (system-specific number).
102687 +
102688 + @Return E_OK on success; error code otherwise..
102689 +*//***************************************************************************/
102690 +t_Error XX_DisableIntr(int irq);
102691 +
102692 +/**************************************************************************//**
102693 + @Function XX_DisableAllIntr
102694 +
102695 + @Description Disable all interrupts by masking them at the CPU.
102696 +
102697 + @Return A value that represents the interrupts state before the
102698 + operation, and should be passed to the matching
102699 + XX_RestoreAllIntr() call.
102700 +*//***************************************************************************/
102701 +uint32_t XX_DisableAllIntr(void);
102702 +
102703 +/**************************************************************************//**
102704 + @Function XX_RestoreAllIntr
102705 +
102706 + @Description Restore previous state of interrupts level at the CPU.
102707 +
102708 + @Param[in] flags - A value that represents the interrupts state to restore,
102709 + as returned by the matching call for XX_DisableAllIntr().
102710 +
102711 + @Return None.
102712 +*//***************************************************************************/
102713 +void XX_RestoreAllIntr(uint32_t flags);
102714 +
102715 +
102716 +/**************************************************************************//**
102717 + @Function XX_Exit
102718 +
102719 + @Description Stop execution and report status (where it is applicable)
102720 +
102721 + @Param[in] status - exit status
102722 +*//***************************************************************************/
102723 +void XX_Exit(int status);
102724 +
102725 +
102726 +/*****************************************************************************/
102727 +/* Tasklet Service Routines */
102728 +/*****************************************************************************/
102729 +typedef t_Handle t_TaskletHandle;
102730 +
102731 +/**************************************************************************//**
102732 + @Function XX_InitTasklet
102733 +
102734 + @Description Create and initialize a tasklet object.
102735 +
102736 + @Param[in] routine - A routine to be ran as a tasklet.
102737 + @Param[in] data - An argument to pass to the tasklet.
102738 +
102739 + @Return Tasklet handle is returned on success. NULL is returned otherwise.
102740 +*//***************************************************************************/
102741 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data);
102742 +
102743 +/**************************************************************************//**
102744 + @Function XX_FreeTasklet
102745 +
102746 + @Description Free a tasklet object.
102747 +
102748 + @Param[in] h_Tasklet - A handle to a tasklet to be free.
102749 +
102750 + @Return None.
102751 +*//***************************************************************************/
102752 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet);
102753 +
102754 +/**************************************************************************//**
102755 + @Function XX_ScheduleTask
102756 +
102757 + @Description Schedule a tasklet object.
102758 +
102759 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102760 + @Param[in] immediate - Indicate whether to schedule this tasklet on
102761 + the immediate queue or on the delayed one.
102762 +
102763 + @Return 0 - on success. Error code - otherwise.
102764 +*//***************************************************************************/
102765 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate);
102766 +
102767 +/**************************************************************************//**
102768 + @Function XX_FlushScheduledTasks
102769 +
102770 + @Description Flush all tasks there are in the scheduled tasks queue.
102771 +
102772 + @Return None.
102773 +*//***************************************************************************/
102774 +void XX_FlushScheduledTasks(void);
102775 +
102776 +/**************************************************************************//**
102777 + @Function XX_TaskletIsQueued
102778 +
102779 + @Description Check if task is queued.
102780 +
102781 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102782 +
102783 + @Return 1 - task is queued. 0 - otherwise.
102784 +*//***************************************************************************/
102785 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet);
102786 +
102787 +/**************************************************************************//**
102788 + @Function XX_SetTaskletData
102789 +
102790 + @Description Set data to a scheduled task. Used to change data of already
102791 + scheduled task.
102792 +
102793 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102794 + @Param[in] data - Data to be set.
102795 +*//***************************************************************************/
102796 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data);
102797 +
102798 +/**************************************************************************//**
102799 + @Function XX_GetTaskletData
102800 +
102801 + @Description Get the data of scheduled task.
102802 +
102803 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102804 +
102805 + @Return handle to the data of the task.
102806 +*//***************************************************************************/
102807 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet);
102808 +
102809 +/**************************************************************************//**
102810 + @Function XX_BottomHalf
102811 +
102812 + @Description Bottom half implementation, invoked by the interrupt handler.
102813 +
102814 + This routine handles all bottom-half tasklets with interrupts
102815 + enabled.
102816 +
102817 + @Return None.
102818 +*//***************************************************************************/
102819 +void XX_BottomHalf(void);
102820 +
102821 +
102822 +/*****************************************************************************/
102823 +/* Spinlock Service Routines */
102824 +/*****************************************************************************/
102825 +
102826 +/**************************************************************************//**
102827 + @Function XX_InitSpinlock
102828 +
102829 + @Description Creates a spinlock.
102830 +
102831 + @Return Spinlock handle is returned on success; NULL otherwise.
102832 +*//***************************************************************************/
102833 +t_Handle XX_InitSpinlock(void);
102834 +
102835 +/**************************************************************************//**
102836 + @Function XX_FreeSpinlock
102837 +
102838 + @Description Frees the memory allocated for the spinlock creation.
102839 +
102840 + @Param[in] h_Spinlock - A handle to a spinlock.
102841 +
102842 + @Return None.
102843 +*//***************************************************************************/
102844 +void XX_FreeSpinlock(t_Handle h_Spinlock);
102845 +
102846 +/**************************************************************************//**
102847 + @Function XX_LockSpinlock
102848 +
102849 + @Description Locks a spinlock.
102850 +
102851 + @Param[in] h_Spinlock - A handle to a spinlock.
102852 +
102853 + @Return None.
102854 +*//***************************************************************************/
102855 +void XX_LockSpinlock(t_Handle h_Spinlock);
102856 +
102857 +/**************************************************************************//**
102858 + @Function XX_UnlockSpinlock
102859 +
102860 + @Description Unlocks a spinlock.
102861 +
102862 + @Param[in] h_Spinlock - A handle to a spinlock.
102863 +
102864 + @Return None.
102865 +*//***************************************************************************/
102866 +void XX_UnlockSpinlock(t_Handle h_Spinlock);
102867 +
102868 +/**************************************************************************//**
102869 + @Function XX_LockIntrSpinlock
102870 +
102871 + @Description Locks a spinlock (interrupt safe).
102872 +
102873 + @Param[in] h_Spinlock - A handle to a spinlock.
102874 +
102875 + @Return A value that represents the interrupts state before the
102876 + operation, and should be passed to the matching
102877 + XX_UnlockIntrSpinlock() call.
102878 +*//***************************************************************************/
102879 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock);
102880 +
102881 +/**************************************************************************//**
102882 + @Function XX_UnlockIntrSpinlock
102883 +
102884 + @Description Unlocks a spinlock (interrupt safe).
102885 +
102886 + @Param[in] h_Spinlock - A handle to a spinlock.
102887 + @Param[in] intrFlags - A value that represents the interrupts state to
102888 + restore, as returned by the matching call for
102889 + XX_LockIntrSpinlock().
102890 +
102891 + @Return None.
102892 +*//***************************************************************************/
102893 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags);
102894 +
102895 +
102896 +/*****************************************************************************/
102897 +/* Timers Service Routines */
102898 +/*****************************************************************************/
102899 +
102900 +/**************************************************************************//**
102901 + @Function XX_CurrentTime
102902 +
102903 + @Description Returns current system time.
102904 +
102905 + @Return Current system time (in milliseconds).
102906 +*//***************************************************************************/
102907 +uint32_t XX_CurrentTime(void);
102908 +
102909 +/**************************************************************************//**
102910 + @Function XX_CreateTimer
102911 +
102912 + @Description Creates a timer.
102913 +
102914 + @Return Timer handle is returned on success; NULL otherwise.
102915 +*//***************************************************************************/
102916 +t_Handle XX_CreateTimer(void);
102917 +
102918 +/**************************************************************************//**
102919 + @Function XX_FreeTimer
102920 +
102921 + @Description Frees the memory allocated for the timer creation.
102922 +
102923 + @Param[in] h_Timer - A handle to a timer.
102924 +
102925 + @Return None.
102926 +*//***************************************************************************/
102927 +void XX_FreeTimer(t_Handle h_Timer);
102928 +
102929 +/**************************************************************************//**
102930 + @Function XX_StartTimer
102931 +
102932 + @Description Starts a timer.
102933 +
102934 + The user can select to start the timer as periodic timer or as
102935 + one-shot timer. The user should provide a callback routine that
102936 + will be called when the timer expires.
102937 +
102938 + @Param[in] h_Timer - A handle to a timer.
102939 + @Param[in] msecs - Timer expiration period (in milliseconds).
102940 + @Param[in] periodic - TRUE for a periodic timer;
102941 + FALSE for a one-shot timer..
102942 + @Param[in] f_TimerExpired - A callback routine to be called when the
102943 + timer expires.
102944 + @Param[in] h_Arg - The argument to pass in the timer-expired
102945 + callback routine.
102946 +
102947 + @Return None.
102948 +*//***************************************************************************/
102949 +void XX_StartTimer(t_Handle h_Timer,
102950 + uint32_t msecs,
102951 + bool periodic,
102952 + void (*f_TimerExpired)(t_Handle h_Arg),
102953 + t_Handle h_Arg);
102954 +
102955 +/**************************************************************************//**
102956 + @Function XX_StopTimer
102957 +
102958 + @Description Frees the memory allocated for the timer creation.
102959 +
102960 + @Param[in] h_Timer - A handle to a timer.
102961 +
102962 + @Return None.
102963 +*//***************************************************************************/
102964 +void XX_StopTimer(t_Handle h_Timer);
102965 +
102966 +/**************************************************************************//**
102967 + @Function XX_ModTimer
102968 +
102969 + @Description Updates the expiration time of a timer.
102970 +
102971 + This routine adds the given time to the current system time,
102972 + and sets this value as the new expiration time of the timer.
102973 +
102974 + @Param[in] h_Timer - A handle to a timer.
102975 + @Param[in] msecs - The new interval until timer expiration
102976 + (in milliseconds).
102977 +
102978 + @Return None.
102979 +*//***************************************************************************/
102980 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs);
102981 +
102982 +/**************************************************************************//**
102983 + @Function XX_Sleep
102984 +
102985 + @Description Non-busy wait until the desired time (in milliseconds) has passed.
102986 +
102987 + @Param[in] msecs - The requested sleep time (in milliseconds).
102988 +
102989 + @Return Zero if the requested time has elapsed; Otherwise, the value
102990 + returned will be the unslept amount) in milliseconds.
102991 +
102992 + @Cautions This routine enables interrupts during its wait time.
102993 +*//***************************************************************************/
102994 +uint32_t XX_Sleep(uint32_t msecs);
102995 +
102996 +/**************************************************************************//**
102997 + @Function XX_UDelay
102998 +
102999 + @Description Busy-wait until the desired time (in microseconds) has passed.
103000 +
103001 + @Param[in] usecs - The requested delay time (in microseconds).
103002 +
103003 + @Return None.
103004 +
103005 + @Cautions It is highly unrecommended to call this routine during interrupt
103006 + time, because the system time may not be updated properly during
103007 + the delay loop. The behavior of this routine during interrupt
103008 + time is unexpected.
103009 +*//***************************************************************************/
103010 +void XX_UDelay(uint32_t usecs);
103011 +
103012 +
103013 +/*****************************************************************************/
103014 +/* Other Service Routines */
103015 +/*****************************************************************************/
103016 +
103017 +/**************************************************************************//**
103018 + @Function XX_PhysToVirt
103019 +
103020 + @Description Translates a physical address to the matching virtual address.
103021 +
103022 + @Param[in] addr - The physical address to translate.
103023 +
103024 + @Return Virtual address.
103025 +*//***************************************************************************/
103026 +void * XX_PhysToVirt(physAddress_t addr);
103027 +
103028 +/**************************************************************************//**
103029 + @Function XX_VirtToPhys
103030 +
103031 + @Description Translates a virtual address to the matching physical address.
103032 +
103033 + @Param[in] addr - The virtual address to translate.
103034 +
103035 + @Return Physical address.
103036 +*//***************************************************************************/
103037 +physAddress_t XX_VirtToPhys(void *addr);
103038 +
103039 +
103040 +/**************************************************************************//**
103041 + @Group xx_ipc XX Inter-Partition-Communication API
103042 +
103043 + @Description The following API is to be used when working with multiple
103044 + partitions configuration.
103045 +
103046 + @{
103047 +*//***************************************************************************/
103048 +
103049 +#define XX_IPC_MAX_ADDR_NAME_LENGTH 16 /**< Maximum length of an endpoint name string;
103050 + The IPC service can use this constant to limit
103051 + the storage space for IPC endpoint names. */
103052 +
103053 +
103054 +/**************************************************************************//**
103055 + @Function t_IpcMsgCompletion
103056 +
103057 + @Description Callback function used upon IPC non-blocking transaction completion
103058 + to return message buffer to the caller and to forward reply if available.
103059 +
103060 + This callback function may be attached by the source endpoint to any outgoing
103061 + IPC message to indicate a non-blocking send (see also XX_IpcSendMessage() routine).
103062 + Upon completion of an IPC transaction (consisting of a message and an optional reply),
103063 + the IPC service invokes this callback routine to return the message buffer to the sender
103064 + and to provide the received reply, if requested.
103065 +
103066 + User provides this function. Driver invokes it.
103067 +
103068 + @Param[in] h_Module - Abstract handle to the sending module - the same handle as was passed
103069 + in the XX_IpcSendMessage() function; This handle is typically used to point
103070 + to the internal data structure of the source endpoint.
103071 + @Param[in] p_Msg - Pointer to original (sent) message buffer;
103072 + The source endpoint can free (or reuse) this buffer when message
103073 + completion callback is called.
103074 + @Param[in] p_Reply - Pointer to (received) reply buffer;
103075 + This pointer is the same as was provided by the source endpoint in
103076 + XX_IpcSendMessage().
103077 + @Param[in] replyLength - Length (in bytes) of actual data in the reply buffer.
103078 + @Param[in] status - Completion status - E_OK or failure indication, e.g. IPC transaction completion
103079 + timeout.
103080 +
103081 + @Return None
103082 + *//***************************************************************************/
103083 +typedef void (t_IpcMsgCompletion)(t_Handle h_Module,
103084 + uint8_t *p_Msg,
103085 + uint8_t *p_Reply,
103086 + uint32_t replyLength,
103087 + t_Error status);
103088 +
103089 +/**************************************************************************//**
103090 + @Function t_IpcMsgHandler
103091 +
103092 + @Description Callback function used as IPC message handler.
103093 +
103094 + The IPC service invokes message handlers for each IPC message received.
103095 + The actual function pointer should be registered by each destination endpoint
103096 + via the XX_IpcRegisterMsgHandler() routine.
103097 +
103098 + User provides this function. Driver invokes it.
103099 +
103100 + @Param[in] h_Module - Abstract handle to the message handling module - the same handle as
103101 + was passed in the XX_IpcRegisterMsgHandler() function; this handle is
103102 + typically used to point to the internal data structure of the destination
103103 + endpoint.
103104 + @Param[in] p_Msg - Pointer to message buffer with data received from peer.
103105 + @Param[in] msgLength - Length (in bytes) of message data.
103106 + @Param[in] p_Reply - Pointer to reply buffer, to be filled by the message handler and then sent
103107 + by the IPC service;
103108 + The reply buffer is allocated by the IPC service with size equals to the
103109 + replyLength parameter provided in message handler registration (see
103110 + XX_IpcRegisterMsgHandler() function);
103111 + If replyLength was initially specified as zero during message handler registration,
103112 + the IPC service may set this pointer to NULL and assume that a reply is not needed;
103113 + The IPC service is also responsible for freeing the reply buffer after the
103114 + reply has been sent or dismissed.
103115 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
103116 + [In] equals the replyLength parameter provided in message handler
103117 + registration (see XX_IpcRegisterMsgHandler() function), and
103118 + [Out] should be updated by message handler to the actual reply length; if
103119 + this value is set to zero, the IPC service must assume that a reply should
103120 + not be sent;
103121 + Note: If p_Reply is not NULL, p_ReplyLength must not be NULL as well.
103122 +
103123 + @Return E_OK on success; Error code otherwise.
103124 + *//***************************************************************************/
103125 +typedef t_Error (t_IpcMsgHandler)(t_Handle h_Module,
103126 + uint8_t *p_Msg,
103127 + uint32_t msgLength,
103128 + uint8_t *p_Reply,
103129 + uint32_t *p_ReplyLength);
103130 +
103131 +/**************************************************************************//**
103132 + @Function XX_IpcRegisterMsgHandler
103133 +
103134 + @Description IPC mailbox registration.
103135 +
103136 + This function is used for registering an IPC message handler in the IPC service.
103137 + This function is called by each destination endpoint to indicate that it is ready
103138 + to handle incoming messages. The IPC service invokes the message handler upon receiving
103139 + a message addressed to the specified destination endpoint.
103140 +
103141 + @Param[in] addr - The address name string associated with the destination endpoint;
103142 + This address must be unique across the IPC service domain to ensure
103143 + correct message routing.
103144 + @Param[in] f_MsgHandler - Pointer to the message handler callback for processing incoming
103145 + message; invoked by the IPC service upon receiving a message
103146 + addressed to the destination endpoint specified by the addr
103147 + parameter.
103148 + @Param[in] h_Module - Abstract handle to the message handling module, passed unchanged
103149 + to f_MsgHandler callback function.
103150 + @Param[in] replyLength - The maximal data length (in bytes) of any reply that the specified message handler
103151 + may generate; the IPC service provides the message handler with buffer
103152 + for reply according to the length specified here (refer also to the description
103153 + of #t_IpcMsgHandler callback function type);
103154 + This size shall be zero if the message handler never generates replies.
103155 +
103156 + @Return E_OK on success; Error code otherwise.
103157 +*//***************************************************************************/
103158 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
103159 + t_IpcMsgHandler *f_MsgHandler,
103160 + t_Handle h_Module,
103161 + uint32_t replyLength);
103162 +
103163 +/**************************************************************************//**
103164 + @Function XX_IpcUnregisterMsgHandler
103165 +
103166 + @Description Release IPC mailbox routine.
103167 +
103168 + This function is used for unregistering an IPC message handler from the IPC service.
103169 + This function is called by each destination endpoint to indicate that it is no longer
103170 + capable of handling incoming messages.
103171 +
103172 + @Param[in] addr - The address name string associated with the destination endpoint;
103173 + This address is the same as was used when the message handler was
103174 + registered via XX_IpcRegisterMsgHandler().
103175 +
103176 + @Return E_OK on success; Error code otherwise.
103177 +*//***************************************************************************/
103178 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
103179 +
103180 +/**************************************************************************//**
103181 + @Function XX_IpcInitSession
103182 +
103183 + @Description This function is used for creating an IPC session between the source endpoint
103184 + and the destination endpoint.
103185 +
103186 + The actual implementation and representation of a session is left for the IPC service.
103187 + The function returns an abstract handle to the created session. This handle shall be used
103188 + by the source endpoint in subsequent calls to XX_IpcSendMessage().
103189 + The IPC service assumes that before this function is called, no messages are sent from
103190 + the specified source endpoint to the specified destination endpoint.
103191 +
103192 + The IPC service may use a connection-oriented approach or a connectionless approach (or both)
103193 + as described below.
103194 +
103195 + @par Connection-Oriented Approach
103196 +
103197 + The IPC service may implement a session in a connection-oriented approach - when this function is called,
103198 + the IPC service should take the necessary steps to bring up a source-to-destination channel for messages
103199 + and a destination-to-source channel for replies. The returned handle should represent the internal
103200 + representation of these channels.
103201 +
103202 + @par Connectionless Approach
103203 +
103204 + The IPC service may implement a session in a connectionless approach - when this function is called, the
103205 + IPC service should not perform any particular steps, but it must store the pair of source and destination
103206 + addresses in some session representation and return it as a handle. When XX_IpcSendMessage() shall be
103207 + called, the IPC service may use this handle to provide the necessary identifiers for routing the messages
103208 + through the connectionless medium.
103209 +
103210 + @Param[in] destAddr - The address name string associated with the destination endpoint.
103211 + @Param[in] srcAddr - The address name string associated with the source endpoint.
103212 +
103213 + @Return Abstract handle to the initialized session, or NULL on error.
103214 +*//***************************************************************************/
103215 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
103216 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
103217 +
103218 +/**************************************************************************//**
103219 + @Function XX_IpcFreeSession
103220 +
103221 + @Description This function is used for terminating an existing IPC session between a source endpoint
103222 + and a destination endpoint.
103223 +
103224 + The IPC service assumes that after this function is called, no messages shall be sent from
103225 + the associated source endpoint to the associated destination endpoint.
103226 +
103227 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
103228 + returned by the XX_IpcInitSession() function.
103229 +
103230 + @Return E_OK on success; Error code otherwise.
103231 +*//***************************************************************************/
103232 +t_Error XX_IpcFreeSession(t_Handle h_Session);
103233 +
103234 +/**************************************************************************//**
103235 + @Function XX_IpcSendMessage
103236 +
103237 + @Description IPC message send routine.
103238 +
103239 + This function may be used by a source endpoint to send an IPC message to a destination
103240 + endpoint. The source endpoint cannot send a message to the destination endpoint without
103241 + first initiating a session with that destination endpoint via XX_IpcInitSession() routine.
103242 +
103243 + The source endpoint must provide the buffer pointer and length of the outgoing message.
103244 + Optionally, it may also provide a buffer for an expected reply. In the latter case, the
103245 + transaction is not considered complete by the IPC service until the reply has been received.
103246 + If the source endpoint does not provide a reply buffer, the transaction is considered
103247 + complete after the message has been sent. The source endpoint must keep the message (and
103248 + optional reply) buffers valid until the transaction is complete.
103249 +
103250 + @par Non-blocking mode
103251 +
103252 + The source endpoint may request a non-blocking send by providing a non-NULL pointer to a message
103253 + completion callback function (f_Completion). Upon completion of the IPC transaction (consisting of a
103254 + message and an optional reply), the IPC service invokes this callback routine to return the message
103255 + buffer to the sender and to provide the received reply, if requested.
103256 +
103257 + @par Blocking mode
103258 +
103259 + The source endpoint may request a blocking send by setting f_Completion to NULL. The function is
103260 + expected to block until the IPC transaction is complete - either the reply has been received or (if no reply
103261 + was requested) the message has been sent.
103262 +
103263 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
103264 + returned by the XX_IpcInitSession() function.
103265 + @Param[in] p_Msg - Pointer to message buffer to send.
103266 + @Param[in] msgLength - Length (in bytes) of actual data in the message buffer.
103267 + @Param[in] p_Reply - Pointer to reply buffer - if this buffer is not NULL, the IPC service
103268 + fills this buffer with the received reply data;
103269 + In blocking mode, the reply data must be valid when the function returns;
103270 + In non-blocking mode, the reply data is valid when f_Completion is called;
103271 + If this pointer is NULL, no reply is expected.
103272 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
103273 + [In] specifies the maximal length (in bytes) of the reply buffer pointed by
103274 + p_Reply, and
103275 + [Out] in non-blocking mode this value is updated by the IPC service to the
103276 + actual reply length (in bytes).
103277 + @Param[in] f_Completion - Pointer to a completion callback to be used in non-blocking send mode;
103278 + The completion callback is invoked by the IPC service upon
103279 + completion of the IPC transaction (consisting of a message and an optional
103280 + reply);
103281 + If this pointer is NULL, the function is expected to block until the IPC
103282 + transaction is complete.
103283 + @Param[in] h_Arg - Abstract handle to the sending module; passed unchanged to the f_Completion
103284 + callback function as the first argument.
103285 +
103286 + @Return E_OK on success; Error code otherwise.
103287 +*//***************************************************************************/
103288 +t_Error XX_IpcSendMessage(t_Handle h_Session,
103289 + uint8_t *p_Msg,
103290 + uint32_t msgLength,
103291 + uint8_t *p_Reply,
103292 + uint32_t *p_ReplyLength,
103293 + t_IpcMsgCompletion *f_Completion,
103294 + t_Handle h_Arg);
103295 +
103296 +
103297 +/** @} */ /* end of xx_ipc group */
103298 +/** @} */ /* end of xx_id group */
103299 +
103300 +
103301 +#endif /* __XX_EXT_H */
103302 diff --git a/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
103303 new file mode 100644
103304 index 00000000..c3a5a623
103305 --- /dev/null
103306 +++ b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
103307 @@ -0,0 +1,56 @@
103308 +/*
103309 + * Copyright 2012 Freescale Semiconductor Inc.
103310 + *
103311 + * Redistribution and use in source and binary forms, with or without
103312 + * modification, are permitted provided that the following conditions are met:
103313 + * * Redistributions of source code must retain the above copyright
103314 + * notice, this list of conditions and the following disclaimer.
103315 + * * Redistributions in binary form must reproduce the above copyright
103316 + * notice, this list of conditions and the following disclaimer in the
103317 + * documentation and/or other materials provided with the distribution.
103318 + * * Neither the name of Freescale Semiconductor nor the
103319 + * names of its contributors may be used to endorse or promote products
103320 + * derived from this software without specific prior written permission.
103321 + *
103322 + *
103323 + * ALTERNATIVELY, this software may be distributed under the terms of the
103324 + * GNU General Public License ("GPL") as published by the Free Software
103325 + * Foundation, either version 2 of that License or (at your option) any
103326 + * later version.
103327 + *
103328 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103329 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103330 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103331 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103332 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103333 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103334 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103335 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103336 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103337 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103338 + */
103339 +
103340 +#ifndef __dflags_h
103341 +#define __dflags_h
103342 +
103343 +
103344 +#define NCSW_LINUX
103345 +
103346 +#define LS1043
103347 +
103348 +#define DEBUG_ERRORS 1
103349 +
103350 +#if defined(DEBUG)
103351 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103352 +
103353 +#define DEBUG_XX_MALLOC
103354 +#define DEBUG_MEM_LEAKS
103355 +
103356 +#else
103357 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103358 +#endif /* (DEBUG) */
103359 +
103360 +#define REPORT_EVENTS 1
103361 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103362 +
103363 +#endif /* __dflags_h */
103364 diff --git a/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
103365 new file mode 100644
103366 index 00000000..586f9c79
103367 --- /dev/null
103368 +++ b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
103369 @@ -0,0 +1,53 @@
103370 +#
103371 +# Makefile config for the Freescale NetcommSW
103372 +#
103373 +NET_DPA = $(srctree)/drivers/net
103374 +DRV_DPA = $(srctree)/drivers/net/ethernet/freescale/sdk_dpaa
103375 +FMAN = $(srctree)/drivers/net/ethernet/freescale/sdk_fman
103376 +
103377 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
103378 +ccflags-y +=-include $(FMAN)/p3040_4080_5020_dflags.h
103379 +endif
103380 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
103381 +ccflags-y +=-include $(FMAN)/p1023_dflags.h
103382 +endif
103383 +ifdef CONFIG_FMAN_V3H
103384 +ccflags-y +=-include $(FMAN)/fmanv3h_dflags.h
103385 +endif
103386 +ifdef CONFIG_FMAN_V3L
103387 +ccflags-y +=-include $(FMAN)/fmanv3l_dflags.h
103388 +endif
103389 +ifdef CONFIG_FMAN_ARM
103390 +ccflags-y +=-include $(FMAN)/ls1043_dflags.h
103391 +endif
103392 +
103393 +ccflags-y += -I$(DRV_DPA)/
103394 +ccflags-y += -I$(FMAN)/inc
103395 +ccflags-y += -I$(FMAN)/inc/cores
103396 +ccflags-y += -I$(FMAN)/inc/etc
103397 +ccflags-y += -I$(FMAN)/inc/Peripherals
103398 +ccflags-y += -I$(FMAN)/inc/flib
103399 +
103400 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
103401 +ccflags-y += -I$(FMAN)/inc/integrations/P3040_P4080_P5020
103402 +endif
103403 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
103404 +ccflags-y += -I$(FMAN)/inc/integrations/P1023
103405 +endif
103406 +ifdef CONFIG_FMAN_V3H
103407 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3H
103408 +endif
103409 +ifdef CONFIG_FMAN_V3L
103410 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3L
103411 +endif
103412 +ifdef CONFIG_FMAN_ARM
103413 +ccflags-y += -I$(FMAN)/inc/integrations/LS1043
103414 +endif
103415 +
103416 +ccflags-y += -I$(FMAN)/src/inc
103417 +ccflags-y += -I$(FMAN)/src/inc/system
103418 +ccflags-y += -I$(FMAN)/src/inc/wrapper
103419 +ccflags-y += -I$(FMAN)/src/inc/xx
103420 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd
103421 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/Peripherals
103422 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/integrations
103423 diff --git a/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
103424 new file mode 100644
103425 index 00000000..b48819d7
103426 --- /dev/null
103427 +++ b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
103428 @@ -0,0 +1,65 @@
103429 +/*
103430 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103431 + *
103432 + * Redistribution and use in source and binary forms, with or without
103433 + * modification, are permitted provided that the following conditions are met:
103434 + * * Redistributions of source code must retain the above copyright
103435 + * notice, this list of conditions and the following disclaimer.
103436 + * * Redistributions in binary form must reproduce the above copyright
103437 + * notice, this list of conditions and the following disclaimer in the
103438 + * documentation and/or other materials provided with the distribution.
103439 + * * Neither the name of Freescale Semiconductor nor the
103440 + * names of its contributors may be used to endorse or promote products
103441 + * derived from this software without specific prior written permission.
103442 + *
103443 + *
103444 + * ALTERNATIVELY, this software may be distributed under the terms of the
103445 + * GNU General Public License ("GPL") as published by the Free Software
103446 + * Foundation, either version 2 of that License or (at your option) any
103447 + * later version.
103448 + *
103449 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103450 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103451 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103452 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103453 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103454 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103455 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103456 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103457 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103458 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103459 + */
103460 +
103461 +#ifndef __dflags_h
103462 +#define __dflags_h
103463 +
103464 +
103465 +#define NCSW_LINUX
103466 +#if 0
103467 +#define DEBUG
103468 +#endif
103469 +
103470 +#define P1023
103471 +#define NCSW_PPC_CORE
103472 +
103473 +#define DEBUG_ERRORS 1
103474 +
103475 +#if defined(DEBUG)
103476 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103477 +
103478 +#define DEBUG_XX_MALLOC
103479 +#define DEBUG_MEM_LEAKS
103480 +
103481 +#else
103482 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103483 +#endif /* (DEBUG) */
103484 +
103485 +#define REPORT_EVENTS 1
103486 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103487 +
103488 +#ifdef CONFIG_P4080_SIM
103489 +#error "Do not define CONFIG_P4080_SIM..."
103490 +#endif
103491 +
103492 +
103493 +#endif /* __dflags_h */
103494 diff --git a/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
103495 new file mode 100644
103496 index 00000000..74389742
103497 --- /dev/null
103498 +++ b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
103499 @@ -0,0 +1,62 @@
103500 +/*
103501 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103502 + *
103503 + * Redistribution and use in source and binary forms, with or without
103504 + * modification, are permitted provided that the following conditions are met:
103505 + * * Redistributions of source code must retain the above copyright
103506 + * notice, this list of conditions and the following disclaimer.
103507 + * * Redistributions in binary form must reproduce the above copyright
103508 + * notice, this list of conditions and the following disclaimer in the
103509 + * documentation and/or other materials provided with the distribution.
103510 + * * Neither the name of Freescale Semiconductor nor the
103511 + * names of its contributors may be used to endorse or promote products
103512 + * derived from this software without specific prior written permission.
103513 + *
103514 + *
103515 + * ALTERNATIVELY, this software may be distributed under the terms of the
103516 + * GNU General Public License ("GPL") as published by the Free Software
103517 + * Foundation, either version 2 of that License or (at your option) any
103518 + * later version.
103519 + *
103520 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103521 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103522 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103523 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103524 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103525 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103526 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103527 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103528 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103529 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103530 + */
103531 +
103532 +#ifndef __dflags_h
103533 +#define __dflags_h
103534 +
103535 +
103536 +#define NCSW_LINUX
103537 +
103538 +#define P4080
103539 +#define NCSW_PPC_CORE
103540 +
103541 +#define DEBUG_ERRORS 1
103542 +
103543 +#if defined(DEBUG)
103544 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103545 +
103546 +#define DEBUG_XX_MALLOC
103547 +#define DEBUG_MEM_LEAKS
103548 +
103549 +#else
103550 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103551 +#endif /* (DEBUG) */
103552 +
103553 +#define REPORT_EVENTS 1
103554 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103555 +
103556 +#ifdef CONFIG_P4080_SIM
103557 +#define SIMULATOR
103558 +#endif /* CONFIG_P4080_SIM */
103559 +
103560 +
103561 +#endif /* __dflags_h */
103562 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/Makefile b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile
103563 new file mode 100644
103564 index 00000000..49405d0e
103565 --- /dev/null
103566 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile
103567 @@ -0,0 +1,11 @@
103568 +#
103569 +# Makefile for the Freescale Ethernet controllers
103570 +#
103571 +ccflags-y += -DVERSION=\"\"
103572 +#
103573 +#Include netcomm SW specific definitions
103574 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
103575 +#
103576 +obj-y += system/
103577 +obj-y += wrapper/
103578 +obj-y += xx/
103579 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
103580 new file mode 100644
103581 index 00000000..20f27d29
103582 --- /dev/null
103583 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
103584 @@ -0,0 +1,118 @@
103585 +/*
103586 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103587 + *
103588 + * Redistribution and use in source and binary forms, with or without
103589 + * modification, are permitted provided that the following conditions are met:
103590 + * * Redistributions of source code must retain the above copyright
103591 + * notice, this list of conditions and the following disclaimer.
103592 + * * Redistributions in binary form must reproduce the above copyright
103593 + * notice, this list of conditions and the following disclaimer in the
103594 + * documentation and/or other materials provided with the distribution.
103595 + * * Neither the name of Freescale Semiconductor nor the
103596 + * names of its contributors may be used to endorse or promote products
103597 + * derived from this software without specific prior written permission.
103598 + *
103599 + *
103600 + * ALTERNATIVELY, this software may be distributed under the terms of the
103601 + * GNU General Public License ("GPL") as published by the Free Software
103602 + * Foundation, either version 2 of that License or (at your option) any
103603 + * later version.
103604 + *
103605 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103606 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103607 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103608 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103609 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103610 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103611 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103612 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103613 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103614 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103615 + */
103616 +
103617 +#ifndef __SYS_EXT_H
103618 +#define __SYS_EXT_H
103619 +
103620 +#include "std_ext.h"
103621 +
103622 +
103623 +/**************************************************************************//**
103624 + @Group sys_grp System Interfaces
103625 +
103626 + @Description Linux system programming interfaces.
103627 +
103628 + @{
103629 +*//***************************************************************************/
103630 +
103631 +/**************************************************************************//**
103632 + @Group sys_gen_grp System General Interface
103633 +
103634 + @Description General definitions, structures and routines of the linux
103635 + system programming interface.
103636 +
103637 + @{
103638 +*//***************************************************************************/
103639 +
103640 +/**************************************************************************//**
103641 + @Collection Macros for Advanced Configuration Requests
103642 + @{
103643 +*//***************************************************************************/
103644 +#define SYS_MAX_ADV_CONFIG_ARGS 4
103645 + /**< Maximum number of arguments in
103646 + an advanced configuration entry */
103647 +/* @} */
103648 +
103649 +/**************************************************************************//**
103650 + @Description System Object Advanced Configuration Entry
103651 +
103652 + This structure represents a single request for an advanced
103653 + configuration call on the initialized object. An array of such
103654 + requests may be contained in the settings structure of the
103655 + corresponding object.
103656 +
103657 + The maximum number of arguments is limited to #SYS_MAX_ADV_CONFIG_ARGS.
103658 +*//***************************************************************************/
103659 +typedef struct t_SysObjectAdvConfigEntry
103660 +{
103661 + void *p_Function; /**< Pointer to advanced configuration routine */
103662 +
103663 + uintptr_t args[SYS_MAX_ADV_CONFIG_ARGS];
103664 + /**< Array of arguments for the specified routine;
103665 + All arguments should be casted to uint32_t. */
103666 +} t_SysObjectAdvConfigEntry;
103667 +
103668 +
103669 +/** @} */ /* end of sys_gen_grp */
103670 +/** @} */ /* end of sys_grp */
103671 +
103672 +#define NCSW_PARAMS(_num, _params) ADV_CONFIG_PARAMS_##_num _params
103673 +
103674 +#define ADV_CONFIG_PARAMS_1(_type) \
103675 + , (_type)p_Entry->args[0]
103676 +
103677 +#define SET_ADV_CONFIG_ARGS_1(_arg0) \
103678 + p_Entry->args[0] = (uintptr_t )(_arg0); \
103679 +
103680 +#define ARGS(_num, _params) SET_ADV_CONFIG_ARGS_##_num _params
103681 +
103682 +#define ADD_ADV_CONFIG_START(_p_Entries, _maxEntries) \
103683 + { \
103684 + t_SysObjectAdvConfigEntry *p_Entry; \
103685 + t_SysObjectAdvConfigEntry *p_Entrys = (_p_Entries); \
103686 + int i=0, max = (_maxEntries); \
103687 +
103688 +#define ADD_ADV_CONFIG_END \
103689 + }
103690 +
103691 +#define ADV_CONFIG_CHECK_START(_p_Entry) \
103692 + { \
103693 + t_SysObjectAdvConfigEntry *p_Entry = _p_Entry; \
103694 + t_Error errCode; \
103695 +
103696 +#define ADV_CONFIG_CHECK(_handle, _func, _params) \
103697 + if (p_Entry->p_Function == _func) \
103698 + { \
103699 + errCode = _func(_handle _params); \
103700 + } else
103701 +
103702 +#endif /* __SYS_EXT_H */
103703 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
103704 new file mode 100644
103705 index 00000000..d6aa9d41
103706 --- /dev/null
103707 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
103708 @@ -0,0 +1,46 @@
103709 +/*
103710 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103711 + *
103712 + * Redistribution and use in source and binary forms, with or without
103713 + * modification, are permitted provided that the following conditions are met:
103714 + * * Redistributions of source code must retain the above copyright
103715 + * notice, this list of conditions and the following disclaimer.
103716 + * * Redistributions in binary form must reproduce the above copyright
103717 + * notice, this list of conditions and the following disclaimer in the
103718 + * documentation and/or other materials provided with the distribution.
103719 + * * Neither the name of Freescale Semiconductor nor the
103720 + * names of its contributors may be used to endorse or promote products
103721 + * derived from this software without specific prior written permission.
103722 + *
103723 + *
103724 + * ALTERNATIVELY, this software may be distributed under the terms of the
103725 + * GNU General Public License ("GPL") as published by the Free Software
103726 + * Foundation, either version 2 of that License or (at your option) any
103727 + * later version.
103728 + *
103729 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103730 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103731 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103732 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103733 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103734 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103735 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103736 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103737 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103738 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103739 + */
103740 +
103741 +#ifndef __SYS_IO_EXT_H
103742 +#define __SYS_IO_EXT_H
103743 +
103744 +#include "std_ext.h"
103745 +#include "error_ext.h"
103746 +
103747 +
103748 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size);
103749 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr);
103750 +uint64_t SYS_PhysToVirt (uint64_t addr);
103751 +uint64_t SYS_VirtToPhys (uint64_t addr);
103752 +
103753 +
103754 +#endif /* __SYS_IO_EXT_H */
103755 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
103756 new file mode 100644
103757 index 00000000..201ad699
103758 --- /dev/null
103759 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
103760 @@ -0,0 +1,208 @@
103761 +/*
103762 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103763 + *
103764 + * Redistribution and use in source and binary forms, with or without
103765 + * modification, are permitted provided that the following conditions are met:
103766 + * * Redistributions of source code must retain the above copyright
103767 + * notice, this list of conditions and the following disclaimer.
103768 + * * Redistributions in binary form must reproduce the above copyright
103769 + * notice, this list of conditions and the following disclaimer in the
103770 + * documentation and/or other materials provided with the distribution.
103771 + * * Neither the name of Freescale Semiconductor nor the
103772 + * names of its contributors may be used to endorse or promote products
103773 + * derived from this software without specific prior written permission.
103774 + *
103775 + *
103776 + * ALTERNATIVELY, this software may be distributed under the terms of the
103777 + * GNU General Public License ("GPL") as published by the Free Software
103778 + * Foundation, either version 2 of that License or (at your option) any
103779 + * later version.
103780 + *
103781 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103782 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103783 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103784 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103785 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103786 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103787 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103788 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103789 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103790 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103791 + */
103792 +
103793 +#ifndef __TYPES_LINUX_H__
103794 +#define __TYPES_LINUX_H__
103795 +
103796 +#include <linux/version.h>
103797 +
103798 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
103799 +#define MODVERSIONS
103800 +#endif
103801 +#ifdef MODVERSIONS
103802 +#include <config/modversions.h>
103803 +#endif /* MODVERSIONS */
103804 +
103805 +#include <linux/kernel.h>
103806 +#include <linux/types.h>
103807 +#include <asm/io.h>
103808 +#include <linux/delay.h>
103809 +
103810 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
103811 + #error "This kernel is probably not supported!!!"
103812 +#elif (!((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) || \
103813 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)) || \
103814 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30))))
103815 + #warning "This kernel is probably not supported!!! You may need to add some fixes."
103816 +#endif /* LINUX_VERSION_CODE */
103817 +
103818 +
103819 +typedef float float_t; /* Single precision floating point */
103820 +typedef double double_t; /* Double precision floating point */
103821 +
103822 +
103823 +#define _Packed
103824 +#define _PackedType __attribute__ ((packed))
103825 +
103826 +typedef phys_addr_t physAddress_t;
103827 +
103828 +#define UINT8_MAX 0xFF
103829 +#define UINT8_MIN 0
103830 +#define UINT16_MAX 0xFFFF
103831 +#define UINT16_MIN 0
103832 +#define UINT32_MAX 0xFFFFFFFF
103833 +#define UINT32_MIN 0
103834 +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFLL
103835 +#define UINT64_MIN 0
103836 +#define INT8_MAX 0x7F
103837 +#define INT8_MIN 0x80
103838 +#define INT16_MAX 0x7FFF
103839 +#define INT16_MIN 0x8000
103840 +#define INT32_MAX 0x7FFFFFFF
103841 +#define INT32_MIN 0x80000000
103842 +#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
103843 +#define INT64_MIN 0x8000000000000000LL
103844 +
103845 +#define ON 1
103846 +#define OFF 0
103847 +
103848 +#define FALSE false
103849 +#define TRUE true
103850 +
103851 +
103852 +/************************/
103853 +/* memory access macros */
103854 +/************************/
103855 +#ifdef CONFIG_FMAN_ARM
103856 +#define in_be16(a) __be16_to_cpu(__raw_readw(a))
103857 +#define in_be32(a) __be32_to_cpu(__raw_readl(a))
103858 +#define out_be16(a, v) __raw_writew(__cpu_to_be16(v), a)
103859 +#define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a)
103860 +#endif
103861 +
103862 +#define GET_UINT8(arg) *(volatile uint8_t *)(&(arg))
103863 +#define GET_UINT16(arg) in_be16(&(arg))//*(volatile uint16_t*)(&(arg))
103864 +#define GET_UINT32(arg) in_be32(&(arg))//*(volatile uint32_t*)(&(arg))
103865 +#define GET_UINT64(arg) *(volatile uint64_t*)(&(arg))
103866 +
103867 +#ifdef VERBOSE_WRITE
103868 +void XX_Print(char *str, ...);
103869 +#define WRITE_UINT8(arg, data) \
103870 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%02x\r\n", (uint32_t)&(arg), (data)); *(volatile uint8_t *)(&(arg)) = (data); } while (0)
103871 +#define WRITE_UINT16(arg, data) \
103872 + 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)
103873 +#define WRITE_UINT32(arg, data) \
103874 + 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)
103875 +#define WRITE_UINT64(arg, data) \
103876 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%016llx\r\n", (uint32_t)&(arg), (data)); *(volatile uint64_t*)(&(arg)) = (data); } while (0)
103877 +
103878 +#else /* not VERBOSE_WRITE */
103879 +#define WRITE_UINT8(arg, data) *(volatile uint8_t *)(&(arg)) = (data)
103880 +#define WRITE_UINT16(arg, data) out_be16(&(arg), data)//*(volatile uint16_t*)(&(arg)) = (data)
103881 +#define WRITE_UINT32(arg, data) out_be32(&(arg), data)//*(volatile unsigned int *)(&(arg)) = (data)
103882 +#define WRITE_UINT64(arg, data) *(volatile uint64_t*)(&(arg)) = (data)
103883 +#endif /* not VERBOSE_WRITE */
103884 +
103885 +
103886 +/*****************************************************************************/
103887 +/* General stuff */
103888 +/*****************************************************************************/
103889 +#ifdef ARRAY_SIZE
103890 +#undef ARRAY_SIZE
103891 +#endif /* ARRAY_SIZE */
103892 +
103893 +#ifdef MAJOR
103894 +#undef MAJOR
103895 +#endif /* MAJOR */
103896 +
103897 +#ifdef MINOR
103898 +#undef MINOR
103899 +#endif /* MINOR */
103900 +
103901 +#ifdef QE_SIZEOF_BD
103902 +#undef QE_SIZEOF_BD
103903 +#endif /* QE_SIZEOF_BD */
103904 +
103905 +#ifdef BD_BUFFER_CLEAR
103906 +#undef BD_BUFFER_CLEAR
103907 +#endif /* BD_BUFFER_CLEAR */
103908 +
103909 +#ifdef BD_BUFFER
103910 +#undef BD_BUFFER
103911 +#endif /* BD_BUFFER */
103912 +
103913 +#ifdef BD_STATUS_AND_LENGTH_SET
103914 +#undef BD_STATUS_AND_LENGTH_SET
103915 +#endif /* BD_STATUS_AND_LENGTH_SET */
103916 +
103917 +#ifdef BD_STATUS_AND_LENGTH
103918 +#undef BD_STATUS_AND_LENGTH
103919 +#endif /* BD_STATUS_AND_LENGTH */
103920 +
103921 +#ifdef BD_BUFFER_ARG
103922 +#undef BD_BUFFER_ARG
103923 +#endif /* BD_BUFFER_ARG */
103924 +
103925 +#ifdef BD_GET_NEXT
103926 +#undef BD_GET_NEXT
103927 +#endif /* BD_GET_NEXT */
103928 +
103929 +#ifdef QE_SDEBCR_BA_MASK
103930 +#undef QE_SDEBCR_BA_MASK
103931 +#endif /* QE_SDEBCR_BA_MASK */
103932 +
103933 +#ifdef BD_BUFFER_SET
103934 +#undef BD_BUFFER_SET
103935 +#endif /* BD_BUFFER_SET */
103936 +
103937 +#ifdef UPGCR_PROTOCOL
103938 +#undef UPGCR_PROTOCOL
103939 +#endif /* UPGCR_PROTOCOL */
103940 +
103941 +#ifdef UPGCR_TMS
103942 +#undef UPGCR_TMS
103943 +#endif /* UPGCR_TMS */
103944 +
103945 +#ifdef UPGCR_RMS
103946 +#undef UPGCR_RMS
103947 +#endif /* UPGCR_RMS */
103948 +
103949 +#ifdef UPGCR_ADDR
103950 +#undef UPGCR_ADDR
103951 +#endif /* UPGCR_ADDR */
103952 +
103953 +#ifdef UPGCR_DIAG
103954 +#undef UPGCR_DIAG
103955 +#endif /* UPGCR_DIAG */
103956 +
103957 +#ifdef NCSW_PARAMS
103958 +#undef NCSW_PARAMS
103959 +#endif /* NCSW_PARAMS */
103960 +
103961 +#ifdef NO_IRQ
103962 +#undef NO_IRQ
103963 +#endif /* NO_IRQ */
103964 +
103965 +#define PRINT_LINE XX_Print("%s:\n %s [%d]\n",__FILE__,__FUNCTION__,__LINE__);
103966 +
103967 +
103968 +#endif /* __TYPES_LINUX_H__ */
103969 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
103970 new file mode 100644
103971 index 00000000..0466a473
103972 --- /dev/null
103973 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
103974 @@ -0,0 +1,84 @@
103975 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
103976 + * All rights reserved.
103977 + *
103978 + * Redistribution and use in source and binary forms, with or without
103979 + * modification, are permitted provided that the following conditions are met:
103980 + * * Redistributions of source code must retain the above copyright
103981 + * notice, this list of conditions and the following disclaimer.
103982 + * * Redistributions in binary form must reproduce the above copyright
103983 + * notice, this list of conditions and the following disclaimer in the
103984 + * documentation and/or other materials provided with the distribution.
103985 + * * Neither the name of Freescale Semiconductor nor the
103986 + * names of its contributors may be used to endorse or promote products
103987 + * derived from this software without specific prior written permission.
103988 + *
103989 + *
103990 + * ALTERNATIVELY, this software may be distributed under the terms of the
103991 + * GNU General Public License ("GPL") as published by the Free Software
103992 + * Foundation, either version 2 of that License or (at your option) any
103993 + * later version.
103994 + *
103995 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103996 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103997 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103998 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103999 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104000 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104001 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104002 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104003 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104004 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104005 + */
104006 +
104007 +/******************************************************************************
104008 + @File fsl_fman_test.h
104009 +
104010 + @Description
104011 +*//***************************************************************************/
104012 +
104013 +#ifndef __FSL_FMAN_TEST_H
104014 +#define __FSL_FMAN_TEST_H
104015 +
104016 +#include <linux/types.h>
104017 +#include <linux/smp.h> /* raw_smp_processor_id() */
104018 +
104019 +//#define FMT_K_DBG
104020 +//#define FMT_K_DBG_RUNTIME
104021 +
104022 +#define _fmt_prk(stage, format, arg...) \
104023 + printk(stage "fmt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
104024 +
104025 +#define _fmt_inf(format, arg...) _fmt_prk(KERN_INFO, format, ##arg)
104026 +#define _fmt_wrn(format, arg...) _fmt_prk(KERN_WARNING, format, ##arg)
104027 +#define _fmt_err(format, arg...) _fmt_prk(KERN_ERR, format, ##arg)
104028 +
104029 +/* there are two macros for debugging: for runtime and generic.
104030 + * Helps when the runtime functions are not targeted for debugging,
104031 + * thus all the unnecessary information will be skipped.
104032 + */
104033 +/* used for generic debugging */
104034 +#if defined(FMT_K_DBG)
104035 + #define _fmt_dbg(format, arg...) \
104036 + printk("fmt [%s:%u](cpu:%u) - " format, \
104037 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
104038 +#else
104039 +# define _fmt_dbg(arg...)
104040 +#endif
104041 +
104042 +/* used for debugging runtime functions */
104043 +#if defined(FMT_K_DBG_RUNTIME)
104044 + #define _fmt_dbgr(format, arg...) \
104045 + printk("fmt [%s:%u](cpu:%u) - " format, \
104046 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
104047 +#else
104048 +# define _fmt_dbgr(arg...)
104049 +#endif
104050 +
104051 +#define FMT_RX_ERR_Q 0xffffffff
104052 +#define FMT_RX_DFLT_Q 0xfffffffe
104053 +#define FMT_TX_ERR_Q 0xfffffffd
104054 +#define FMT_TX_CONF_Q 0xfffffffc
104055 +
104056 +#define FMAN_TEST_MAX_TX_FQS 8
104057 +
104058 +#endif /* __FSL_FMAN_TEST_H */
104059 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
104060 new file mode 100644
104061 index 00000000..dd0f03ac
104062 --- /dev/null
104063 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
104064 @@ -0,0 +1,130 @@
104065 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
104066 + * All rights reserved.
104067 + *
104068 + * Redistribution and use in source and binary forms, with or without
104069 + * modification, are permitted provided that the following conditions are met:
104070 + * * Redistributions of source code must retain the above copyright
104071 + * notice, this list of conditions and the following disclaimer.
104072 + * * Redistributions in binary form must reproduce the above copyright
104073 + * notice, this list of conditions and the following disclaimer in the
104074 + * documentation and/or other materials provided with the distribution.
104075 + * * Neither the name of Freescale Semiconductor nor the
104076 + * names of its contributors may be used to endorse or promote products
104077 + * derived from this software without specific prior written permission.
104078 + *
104079 + *
104080 + * ALTERNATIVELY, this software may be distributed under the terms of the
104081 + * GNU General Public License ("GPL") as published by the Free Software
104082 + * Foundation, either version 2 of that License or (at your option) any
104083 + * later version.
104084 + *
104085 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104086 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104087 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104088 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104089 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104090 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104091 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104092 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104093 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104094 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104095 + */
104096 +
104097 +/*
104098 + @File lnxwrp_exp_sym.h
104099 + @Description FMan exported routines
104100 +*/
104101 +
104102 +#ifndef __LNXWRP_EXP_SYM_H
104103 +#define __LNXWRP_EXP_SYM_H
104104 +
104105 +#include "fm_port_ext.h"
104106 +#include "fm_pcd_ext.h"
104107 +#include "fm_mac_ext.h"
104108 +
104109 +
104110 +/* FMAN Port exported routines */
104111 +EXPORT_SYMBOL(FM_PORT_Disable);
104112 +EXPORT_SYMBOL(FM_PORT_Enable);
104113 +EXPORT_SYMBOL(FM_PORT_SetPCD);
104114 +EXPORT_SYMBOL(FM_PORT_DeletePCD);
104115 +
104116 +/* Runtime PCD exported routines */
104117 +EXPORT_SYMBOL(FM_PCD_Enable);
104118 +EXPORT_SYMBOL(FM_PCD_Disable);
104119 +EXPORT_SYMBOL(FM_PCD_GetCounter);
104120 +EXPORT_SYMBOL(FM_PCD_PrsLoadSw);
104121 +EXPORT_SYMBOL(FM_PCD_KgSetDfltValue);
104122 +EXPORT_SYMBOL(FM_PCD_KgSetAdditionalDataAfterParsing);
104123 +EXPORT_SYMBOL(FM_PCD_SetException);
104124 +EXPORT_SYMBOL(FM_PCD_ModifyCounter);
104125 +EXPORT_SYMBOL(FM_PCD_SetPlcrStatistics);
104126 +EXPORT_SYMBOL(FM_PCD_SetPrsStatistics);
104127 +EXPORT_SYMBOL(FM_PCD_ForceIntr);
104128 +EXPORT_SYMBOL(FM_PCD_HcTxConf);
104129 +
104130 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsSet);
104131 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsDelete);
104132 +EXPORT_SYMBOL(FM_PCD_KgSchemeSet);
104133 +EXPORT_SYMBOL(FM_PCD_KgSchemeDelete);
104134 +EXPORT_SYMBOL(FM_PCD_KgSchemeGetCounter);
104135 +EXPORT_SYMBOL(FM_PCD_KgSchemeSetCounter);
104136 +EXPORT_SYMBOL(FM_PCD_CcRootBuild);
104137 +EXPORT_SYMBOL(FM_PCD_CcRootDelete);
104138 +EXPORT_SYMBOL(FM_PCD_MatchTableSet);
104139 +EXPORT_SYMBOL(FM_PCD_MatchTableDelete);
104140 +EXPORT_SYMBOL(FM_PCD_CcRootModifyNextEngine);
104141 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyNextEngine);
104142 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyNextEngine);
104143 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyMissNextEngine);
104144 +EXPORT_SYMBOL(FM_PCD_MatchTableRemoveKey);
104145 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNRemoveKey);
104146 +EXPORT_SYMBOL(FM_PCD_MatchTableAddKey);
104147 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKeyAndNextEngine);
104148 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKeyAndNextEngine);
104149 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKey);
104150 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKey);
104151 +EXPORT_SYMBOL(FM_PCD_MatchTableGetIndexedHashBucket);
104152 +EXPORT_SYMBOL(FM_PCD_MatchTableGetNextEngine);
104153 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyCounter);
104154 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyStatistics);
104155 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNGetKeyStatistics);
104156 +EXPORT_SYMBOL(FM_PCD_MatchTableGetMissStatistics);
104157 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissStatistics);
104158 +EXPORT_SYMBOL(FM_PCD_HashTableSet);
104159 +EXPORT_SYMBOL(FM_PCD_HashTableDelete);
104160 +EXPORT_SYMBOL(FM_PCD_HashTableAddKey);
104161 +EXPORT_SYMBOL(FM_PCD_HashTableRemoveKey);
104162 +EXPORT_SYMBOL(FM_PCD_HashTableModifyNextEngine);
104163 +EXPORT_SYMBOL(FM_PCD_HashTableModifyMissNextEngine);
104164 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissNextEngine);
104165 +EXPORT_SYMBOL(FM_PCD_HashTableFindNGetKeyStatistics);
104166 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSet);
104167 +EXPORT_SYMBOL(FM_PCD_PlcrProfileDelete);
104168 +EXPORT_SYMBOL(FM_PCD_PlcrProfileGetCounter);
104169 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSetCounter);
104170 +EXPORT_SYMBOL(FM_PCD_ManipNodeSet);
104171 +EXPORT_SYMBOL(FM_PCD_ManipNodeDelete);
104172 +EXPORT_SYMBOL(FM_PCD_ManipGetStatistics);
104173 +EXPORT_SYMBOL(FM_PCD_ManipNodeReplace);
104174 +#if (DPAA_VERSION >= 11)
104175 +EXPORT_SYMBOL(FM_PCD_FrmReplicSetGroup);
104176 +EXPORT_SYMBOL(FM_PCD_FrmReplicDeleteGroup);
104177 +EXPORT_SYMBOL(FM_PCD_FrmReplicAddMember);
104178 +EXPORT_SYMBOL(FM_PCD_FrmReplicRemoveMember);
104179 +#endif /* DPAA_VERSION >= 11 */
104180 +
104181 +#ifdef FM_CAPWAP_SUPPORT
104182 +EXPORT_SYMBOL(FM_PCD_StatisticsSetNode);
104183 +#endif /* FM_CAPWAP_SUPPORT */
104184 +
104185 +EXPORT_SYMBOL(FM_PCD_SetAdvancedOffloadSupport);
104186 +
104187 +/* FMAN MAC exported routines */
104188 +EXPORT_SYMBOL(FM_MAC_GetStatistics);
104189 +
104190 +EXPORT_SYMBOL(FM_MAC_GetFrameSizeCounters);
104191 +
104192 +EXPORT_SYMBOL(FM_GetSpecialOperationCoding);
104193 +
104194 +#endif /* __LNXWRP_EXP_SYM_H */
104195 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
104196 new file mode 100644
104197 index 00000000..a72c8670
104198 --- /dev/null
104199 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
104200 @@ -0,0 +1,163 @@
104201 +/*
104202 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104203 + *
104204 + * Redistribution and use in source and binary forms, with or without
104205 + * modification, are permitted provided that the following conditions are met:
104206 + * * Redistributions of source code must retain the above copyright
104207 + * notice, this list of conditions and the following disclaimer.
104208 + * * Redistributions in binary form must reproduce the above copyright
104209 + * notice, this list of conditions and the following disclaimer in the
104210 + * documentation and/or other materials provided with the distribution.
104211 + * * Neither the name of Freescale Semiconductor nor the
104212 + * names of its contributors may be used to endorse or promote products
104213 + * derived from this software without specific prior written permission.
104214 + *
104215 + *
104216 + * ALTERNATIVELY, this software may be distributed under the terms of the
104217 + * GNU General Public License ("GPL") as published by the Free Software
104218 + * Foundation, either version 2 of that License or (at your option) any
104219 + * later version.
104220 + *
104221 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104222 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104223 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104224 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104225 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104226 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104227 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104228 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104229 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104230 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104231 + */
104232 +
104233 +/******************************************************************************
104234 + @File lnxwrp_fm_ext.h
104235 +
104236 + @Description TODO
104237 +*//***************************************************************************/
104238 +
104239 +#ifndef __LNXWRP_FM_EXT_H
104240 +#define __LNXWRP_FM_EXT_H
104241 +
104242 +#include "std_ext.h"
104243 +#include "sys_ext.h"
104244 +#include "fm_ext.h"
104245 +#include "fm_muram_ext.h"
104246 +#include "fm_pcd_ext.h"
104247 +#include "fm_port_ext.h"
104248 +#include "fm_mac_ext.h"
104249 +#include "fm_rtc_ext.h"
104250 +
104251 +
104252 +/**************************************************************************//**
104253 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
104254 +
104255 + @Description FM API functions, definitions and enums.
104256 +
104257 + @{
104258 +*//***************************************************************************/
104259 +
104260 +/**************************************************************************//**
104261 + @Group FM_LnxKern_init_grp Initialization Unit
104262 +
104263 + @Description Initialization Unit
104264 +
104265 + Initialization Flow:
104266 + Initialization of the FM Module will be carried out by the Linux
104267 + kernel according to the following sequence:
104268 + a. Calling the initialization routine with no parameters.
104269 + b. The driver will register to the Device-Tree.
104270 + c. The Linux Device-Tree will initiate a call to the driver for
104271 + initialization.
104272 + d. The driver will read the appropriate information from the Device-Tree
104273 + e. [Optional] Calling the advance initialization routines to change
104274 + driver's defaults.
104275 + f. Initialization of the device will be automatically upon using it.
104276 +
104277 + @{
104278 +*//***************************************************************************/
104279 +
104280 +typedef struct t_WrpFmDevSettings
104281 +{
104282 + t_FmParams param;
104283 + t_SysObjectAdvConfigEntry *advConfig;
104284 +} t_WrpFmDevSettings;
104285 +
104286 +typedef struct t_WrpFmPcdDevSettings
104287 +{
104288 + t_FmPcdParams param;
104289 + t_SysObjectAdvConfigEntry *advConfig;
104290 +} t_WrpFmPcdDevSettings;
104291 +
104292 +typedef struct t_WrpFmPortDevSettings
104293 +{
104294 + bool frag_enabled;
104295 + t_FmPortParams param;
104296 + t_SysObjectAdvConfigEntry *advConfig;
104297 +} t_WrpFmPortDevSettings;
104298 +
104299 +typedef struct t_WrpFmMacDevSettings
104300 +{
104301 + t_FmMacParams param;
104302 + t_SysObjectAdvConfigEntry *advConfig;
104303 +} t_WrpFmMacDevSettings;
104304 +
104305 +
104306 +/**************************************************************************//**
104307 + @Function LNXWRP_FM_Init
104308 +
104309 + @Description Initialize the FM linux wrapper.
104310 +
104311 + @Return A handle (descriptor) of the newly created FM Linux wrapper
104312 + structure.
104313 +*//***************************************************************************/
104314 +t_Handle LNXWRP_FM_Init(void);
104315 +
104316 +/**************************************************************************//**
104317 + @Function LNXWRP_FM_Free
104318 +
104319 + @Description Free the FM linux wrapper.
104320 +
104321 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
104322 +
104323 + @Return E_OK on success; Error code otherwise.
104324 +*//***************************************************************************/
104325 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm);
104326 +
104327 +/**************************************************************************//**
104328 + @Function LNXWRP_FM_GetMacHandle
104329 +
104330 + @Description Get the FM-MAC LLD handle from the FM linux wrapper.
104331 +
104332 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
104333 + @Param[in] fmId - Index of the FM device to get the MAC handle from.
104334 + @Param[in] macId - Index of the mac handle.
104335 +
104336 + @Return A handle of the LLD compressor.
104337 +*//***************************************************************************/
104338 +t_Handle LNXWRP_FM_GetMacHandle(t_Handle h_LnxWrpFm, uint8_t fmId, uint8_t macId);
104339 +
104340 +#ifdef CONFIG_FSL_SDK_FMAN_TEST
104341 +t_Handle LNXWRP_FM_TEST_Init(void);
104342 +t_Error LNXWRP_FM_TEST_Free(t_Handle h_FmTestLnxWrp);
104343 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
104344 +
104345 +/** @} */ /* end of FM_LnxKern_init_grp group */
104346 +
104347 +
104348 +/**************************************************************************//**
104349 + @Group FM_LnxKern_ctrl_grp Control Unit
104350 +
104351 + @Description Control Unit
104352 +
104353 + TODO
104354 + @{
104355 +*//***************************************************************************/
104356 +
104357 +#include "lnxwrp_fsl_fman.h"
104358 +
104359 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
104360 +/** @} */ /* end of FM_LnxKern_grp group */
104361 +
104362 +
104363 +#endif /* __LNXWRP_FM_EXT_H */
104364 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
104365 new file mode 100644
104366 index 00000000..c50031cf
104367 --- /dev/null
104368 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
104369 @@ -0,0 +1,921 @@
104370 +/*
104371 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104372 + *
104373 + * Redistribution and use in source and binary forms, with or without
104374 + * modification, are permitted provided that the following conditions are met:
104375 + * * Redistributions of source code must retain the above copyright
104376 + * notice, this list of conditions and the following disclaimer.
104377 + * * Redistributions in binary form must reproduce the above copyright
104378 + * notice, this list of conditions and the following disclaimer in the
104379 + * documentation and/or other materials provided with the distribution.
104380 + * * Neither the name of Freescale Semiconductor nor the
104381 + * names of its contributors may be used to endorse or promote products
104382 + * derived from this software without specific prior written permission.
104383 + *
104384 + *
104385 + * ALTERNATIVELY, this software may be distributed under the terms of the
104386 + * GNU General Public License ("GPL") as published by the Free Software
104387 + * Foundation, either version 2 of that License or (at your option) any
104388 + * later version.
104389 + *
104390 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104391 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104392 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104393 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104394 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104395 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104396 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104397 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104398 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104399 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104400 + */
104401 +
104402 +/******************************************************************************
104403 + @File lnxwrp_fsl_fman.h
104404 +
104405 + @Description Linux internal kernel API
104406 +*//***************************************************************************/
104407 +
104408 +#ifndef __LNXWRP_FSL_FMAN_H
104409 +#define __LNXWRP_FSL_FMAN_H
104410 +
104411 +#include <linux/types.h>
104412 +#include <linux/device.h> /* struct device */
104413 +#include <linux/fsl_qman.h> /* struct qman_fq */
104414 +#include "dpaa_integration_ext.h"
104415 +#include "fm_port_ext.h"
104416 +#include "fm_mac_ext.h"
104417 +#include "fm_macsec_ext.h"
104418 +#include "fm_rtc_ext.h"
104419 +
104420 +/**************************************************************************//**
104421 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
104422 +
104423 + @Description FM API functions, definitions and enums.
104424 +
104425 + @{
104426 +*//***************************************************************************/
104427 +
104428 +/**************************************************************************//**
104429 + @Group FM_LnxKern_ctrl_grp Control Unit
104430 +
104431 + @Description Control Unit
104432 +
104433 + Internal Kernel Control Unit API
104434 + @{
104435 +*//***************************************************************************/
104436 +
104437 +/*****************************************************************************/
104438 +/* Internal Linux kernel routines */
104439 +/*****************************************************************************/
104440 +
104441 +/**************************************************************************//**
104442 + @Description MACSEC Exceptions wrapper
104443 +*//***************************************************************************/
104444 +typedef enum fm_macsec_exception {
104445 + SINGLE_BIT_ECC = e_FM_MACSEC_EX_SINGLE_BIT_ECC,
104446 + MULTI_BIT_ECC = e_FM_MACSEC_EX_MULTI_BIT_ECC
104447 +} fm_macsec_exception;
104448 +
104449 +/**************************************************************************//**
104450 + @Description Unknown sci frame treatment wrapper
104451 +*//***************************************************************************/
104452 +typedef enum fm_macsec_unknown_sci_frame_treatment {
104453 + SCI_DISCARD_BOTH = e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH,
104454 + SCI_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
104455 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED,
104456 + SCI_DELIVER_UNCTRL_DISCARD_CTRL = \
104457 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
104458 + SCI_DELIVER_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
104459 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED
104460 +} fm_macsec_unknown_sci_frame_treatment;
104461 +
104462 +/**************************************************************************//**
104463 + @Description Untag frame treatment wrapper
104464 +*//***************************************************************************/
104465 +typedef enum fm_macsec_untag_frame_treatment {
104466 + UNTAG_DELIVER_UNCTRL_DISCARD_CTRL = \
104467 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
104468 + UNTAG_DISCARD_BOTH = e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH,
104469 + UNTAG_DISCARD_UNCTRL_DELIVER_CTRL_UNMODIFIED = \
104470 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED
104471 +} fm_macsec_untag_frame_treatment;
104472 +
104473 +/**************************************************************************//**
104474 +@Description MACSEC SECY Cipher Suite wrapper
104475 +*//***************************************************************************/
104476 +typedef enum fm_macsec_secy_cipher_suite {
104477 + SECY_GCM_AES_128 = e_FM_MACSEC_SECY_GCM_AES_128, /**< GCM-AES-128 */
104478 +#if (DPAA_VERSION >= 11)
104479 + SECY_GCM_AES_256 = e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
104480 +#endif /* (DPAA_VERSION >= 11) */
104481 +} fm_macsec_secy_cipher_suite;
104482 +
104483 +/**************************************************************************//**
104484 + @Description MACSEC SECY Exceptions wrapper
104485 +*//***************************************************************************/
104486 +typedef enum fm_macsec_secy_exception {
104487 + SECY_EX_FRAME_DISCARDED = e_FM_MACSEC_SECY_EX_FRAME_DISCARDED
104488 +} fm_macsec_secy_exception;
104489 +
104490 +/**************************************************************************//**
104491 + @Description MACSEC SECY Events wrapper
104492 +*//***************************************************************************/
104493 +typedef enum fm_macsec_secy_event {
104494 + SECY_EV_NEXT_PN = e_FM_MACSEC_SECY_EV_NEXT_PN
104495 +} fm_macsec_secy_event;
104496 +
104497 +/**************************************************************************//**
104498 + @Description Valid frame behaviors wrapper
104499 +*//***************************************************************************/
104500 +typedef enum fm_macsec_valid_frame_behavior {
104501 + VALID_FRAME_BEHAVIOR_DISABLE = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE,
104502 + VALID_FRAME_BEHAVIOR_CHECK = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK,
104503 + VALID_FRAME_BEHAVIOR_STRICT = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
104504 +} fm_macsec_valid_frame_behavior;
104505 +
104506 +/**************************************************************************//**
104507 + @Description SCI insertion modes wrapper
104508 +*//***************************************************************************/
104509 +typedef enum fm_macsec_sci_insertion_mode {
104510 + SCI_INSERTION_MODE_EXPLICIT_SECTAG = \
104511 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG,
104512 + SCI_INSERTION_MODE_EXPLICIT_MAC_SA = \
104513 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA,
104514 + SCI_INSERTION_MODE_IMPLICT_PTP = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP
104515 +} fm_macsec_sci_insertion_mode;
104516 +
104517 +typedef macsecSAKey_t macsec_sa_key_t;
104518 +typedef macsecSCI_t macsec_sci_t;
104519 +typedef macsecAN_t macsec_an_t;
104520 +typedef t_Handle handle_t;
104521 +
104522 +/**************************************************************************//**
104523 + @Function fm_macsec_secy_exception_callback wrapper
104524 + @Description Exceptions user callback routine, will be called upon an
104525 + exception passing the exception identification.
104526 + @Param[in] app_h A handle to an application layer object; This handle
104527 + will be passed by the driver upon calling this callback.
104528 + @Param[in] exception The exception.
104529 +*//***************************************************************************/
104530 +typedef void (fm_macsec_secy_exception_callback) (handle_t app_h,
104531 + fm_macsec_secy_exception exception);
104532 +
104533 +/**************************************************************************//**
104534 + @Function fm_macsec_secy_event_callback wrapper
104535 + @Description Events user callback routine, will be called upon an
104536 + event passing the event identification.
104537 + @Param[in] app_h A handle to an application layer object; This handle
104538 + will be passed by the driver upon calling this callback.
104539 + @Param[in] event The event.
104540 +*//***************************************************************************/
104541 +typedef void (fm_macsec_secy_event_callback) (handle_t app_h,
104542 + fm_macsec_secy_event event);
104543 +
104544 +/**************************************************************************//**
104545 + @Function fm_macsec_exception_callback wrapper
104546 + @Description Exceptions user callback routine, will be called upon an
104547 + exception passing the exception identification.
104548 + @Param[in] app_h A handle to an application layer object; This handle
104549 + will be passed by the driver upon calling this callback.
104550 + @Param[in] exception The exception.
104551 +*//***************************************************************************/
104552 +typedef void (fm_macsec_exception_callback) (handle_t app_h,
104553 + fm_macsec_exception exception);
104554 +
104555 +/**************************************************************************//**
104556 + @Description MACSEC SecY SC Params wrapper
104557 +*//***************************************************************************/
104558 +struct fm_macsec_secy_sc_params {
104559 + macsec_sci_t sci;
104560 + fm_macsec_secy_cipher_suite cipher_suite;
104561 +};
104562 +
104563 +/**************************************************************************//**
104564 + @Description FM MACSEC SecY config input wrapper
104565 +*//***************************************************************************/
104566 +struct fm_macsec_secy_params {
104567 + handle_t fm_macsec_h;
104568 + struct fm_macsec_secy_sc_params tx_sc_params;
104569 + uint32_t num_receive_channels;
104570 + fm_macsec_secy_exception_callback *exception_f;
104571 + fm_macsec_secy_event_callback *event_f;
104572 + handle_t app_h;
104573 +};
104574 +
104575 +/**************************************************************************//**
104576 + @Description FM MACSEC config input wrapper
104577 +*//***************************************************************************/
104578 +struct fm_macsec_params {
104579 + handle_t fm_h;
104580 + bool guest_mode;
104581 +
104582 + union {
104583 + struct {
104584 + uint8_t fm_mac_id;
104585 + } guest_params;
104586 +
104587 + struct {
104588 + uintptr_t base_addr;
104589 + handle_t fm_mac_h;
104590 + fm_macsec_exception_callback *exception_f;
104591 + handle_t app_h;
104592 + } non_guest_params;
104593 + };
104594 +
104595 +};
104596 +
104597 +/**************************************************************************//**
104598 + @Description FM device opaque structure used for type checking
104599 +*//***************************************************************************/
104600 +struct fm;
104601 +
104602 +/**************************************************************************//**
104603 + @Description FM MAC device opaque structure used for type checking
104604 +*//***************************************************************************/
104605 +struct fm_mac_dev;
104606 +
104607 +/**************************************************************************//**
104608 + @Description FM MACSEC device opaque structure used for type checking
104609 +*//***************************************************************************/
104610 +struct fm_macsec_dev;
104611 +struct fm_macsec_secy_dev;
104612 +
104613 +/**************************************************************************//**
104614 + @Description A structure ..,
104615 +*//***************************************************************************/
104616 +struct fm_port;
104617 +
104618 +typedef int (*alloc_pcd_fqids)(struct device *dev, uint32_t num,
104619 + uint8_t alignment, uint32_t *base_fqid);
104620 +
104621 +typedef int (*free_pcd_fqids)(struct device *dev, uint32_t base_fqid);
104622 +
104623 +struct fm_port_pcd_param {
104624 + alloc_pcd_fqids cba;
104625 + free_pcd_fqids cbf;
104626 + struct device *dev;
104627 +};
104628 +
104629 +/**************************************************************************//**
104630 + @Description A structure of information about each of the external
104631 + buffer pools used by the port,
104632 +*//***************************************************************************/
104633 +struct fm_port_pool_param {
104634 + uint8_t id; /**< External buffer pool id */
104635 + uint16_t size; /**< External buffer pool buffer size */
104636 +};
104637 +
104638 +/**************************************************************************//**
104639 + @Description structure for additional port parameters
104640 +*//***************************************************************************/
104641 +struct fm_port_params {
104642 + uint32_t errq; /**< Error Queue Id. */
104643 + uint32_t defq; /**< For Tx and HC - Default Confirmation queue,
104644 + 0 means no Tx conf for processed frames.
104645 + For Rx and OP - default Rx queue. */
104646 + uint8_t num_pools; /**< Number of pools use by this port */
104647 + struct fm_port_pool_param pool_param[FM_PORT_MAX_NUM_OF_EXT_POOLS];
104648 + /**< Parameters for each pool */
104649 + uint16_t priv_data_size; /**< Area that user may save for his own
104650 + need (E.g. save the SKB) */
104651 + bool parse_results; /**< Put the parser-results in the Rx/Tx buffer */
104652 + bool hash_results; /**< Put the hash-results in the Rx/Tx buffer */
104653 + bool time_stamp; /**< Put the time-stamp in the Rx/Tx buffer */
104654 + bool frag_enable; /**< Fragmentation support, for OP only */
104655 + uint16_t data_align; /**< value for selecting a data alignment (must be a power of 2);
104656 + if write optimization is used, must be >= 16. */
104657 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
104658 + Note that this field impacts the size of the buffer-prefix
104659 + (i.e. it pushes the data offset); */
104660 +};
104661 +
104662 +/**************************************************************************//**
104663 + @Function fm_bind
104664 +
104665 + @Description Bind to a specific FM device.
104666 +
104667 + @Param[in] fm_dev - the OF handle of the FM device.
104668 +
104669 + @Return A handle of the FM device.
104670 +
104671 + @Cautions Allowed only after the port was created.
104672 +*//***************************************************************************/
104673 +struct fm *fm_bind(struct device *fm_dev);
104674 +
104675 +/**************************************************************************//**
104676 + @Function fm_unbind
104677 +
104678 + @Description Un-bind from a specific FM device.
104679 +
104680 + @Param[in] fm - A handle of the FM device.
104681 +
104682 + @Cautions Allowed only after the port was created.
104683 +*//***************************************************************************/
104684 +void fm_unbind(struct fm *fm);
104685 +
104686 +void *fm_get_handle(struct fm *fm);
104687 +void *fm_get_rtc_handle(struct fm *fm);
104688 +struct resource *fm_get_mem_region(struct fm *fm);
104689 +
104690 +/**************************************************************************//**
104691 + @Function fm_port_bind
104692 +
104693 + @Description Bind to a specific FM-port device (may be Rx or Tx port).
104694 +
104695 + @Param[in] fm_port_dev - the OF handle of the FM port device.
104696 +
104697 + @Return A handle of the FM port device.
104698 +
104699 + @Cautions Allowed only after the port was created.
104700 +*//***************************************************************************/
104701 +struct fm_port *fm_port_bind(struct device *fm_port_dev);
104702 +
104703 +/**************************************************************************//**
104704 + @Function fm_port_unbind
104705 +
104706 + @Description Un-bind from a specific FM-port device (may be Rx or Tx port).
104707 +
104708 + @Param[in] port - A handle of the FM port device.
104709 +
104710 + @Cautions Allowed only after the port was created.
104711 +*//***************************************************************************/
104712 +void fm_port_unbind(struct fm_port *port);
104713 +
104714 +/**************************************************************************//**
104715 + @Function fm_set_rx_port_params
104716 +
104717 + @Description Configure parameters for a specific Rx FM-port device.
104718 +
104719 + @Param[in] port - A handle of the FM port device.
104720 + @Param[in] params - Rx port parameters
104721 +
104722 + @Cautions Allowed only after the port is binded.
104723 +*//***************************************************************************/
104724 +void fm_set_rx_port_params(struct fm_port *port,
104725 + struct fm_port_params *params);
104726 +
104727 +/**************************************************************************//**
104728 + @Function fm_port_pcd_bind
104729 +
104730 + @Description Bind as a listener on a port PCD.
104731 +
104732 + @Param[in] port - A handle of the FM port device.
104733 + @Param[in] params - PCD port parameters
104734 +
104735 + @Cautions Allowed only after the port is binded.
104736 +*//***************************************************************************/
104737 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params);
104738 +
104739 +/**************************************************************************//**
104740 + @Function fm_port_get_buff_layout_ext_params
104741 +
104742 + @Description Get data_align and manip_extra_space from the device tree
104743 + chosen node if applied.
104744 + This function will only update these two parameters.
104745 + When this port has no such parameters in the device tree
104746 + values will be set to 0.
104747 +
104748 + @Param[in] port - A handle of the FM port device.
104749 + @Param[in] params - PCD port parameters
104750 +
104751 + @Cautions Allowed only after the port is binded.
104752 +*//***************************************************************************/
104753 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params);
104754 +
104755 +/**************************************************************************//**
104756 + @Function fm_get_tx_port_channel
104757 +
104758 + @Description Get qman-channel number for this Tx port.
104759 +
104760 + @Param[in] port - A handle of the FM port device.
104761 +
104762 + @Return qman-channel number for this Tx port.
104763 +
104764 + @Cautions Allowed only after the port is binded.
104765 +*//***************************************************************************/
104766 +uint16_t fm_get_tx_port_channel(struct fm_port *port);
104767 +
104768 +/**************************************************************************//**
104769 + @Function fm_set_tx_port_params
104770 +
104771 + @Description Configure parameters for a specific Tx FM-port device
104772 +
104773 + @Param[in] port - A handle of the FM port device.
104774 + @Param[in] params - Tx port parameters
104775 +
104776 + @Cautions Allowed only after the port is binded.
104777 +*//***************************************************************************/
104778 +void fm_set_tx_port_params(struct fm_port *port, struct fm_port_params *params);
104779 +
104780 +
104781 +/**************************************************************************//**
104782 + @Function fm_mac_set_handle
104783 +
104784 + @Description Set mac handle
104785 +
104786 + @Param[in] h_lnx_wrp_fm_dev - A handle of the LnxWrp FM device.
104787 + @Param[in] h_fm_mac - A handle of the LnxWrp FM MAC device.
104788 + @Param[in] mac_id - MAC id.
104789 +*//***************************************************************************/
104790 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev, t_Handle h_fm_mac,
104791 + int mac_id);
104792 +
104793 +/**************************************************************************//**
104794 + @Function fm_port_enable
104795 +
104796 + @Description Enable specific FM-port device (may be Rx or Tx port).
104797 +
104798 + @Param[in] port - A handle of the FM port device.
104799 +
104800 + @Cautions Allowed only after the port is initialized.
104801 +*//***************************************************************************/
104802 +int fm_port_enable(struct fm_port *port);
104803 +
104804 +/**************************************************************************//**
104805 + @Function fm_port_disable
104806 +
104807 + @Description Disable specific FM-port device (may be Rx or Tx port).
104808 +
104809 + @Param[in] port - A handle of the FM port device.
104810 +
104811 + @Cautions Allowed only after the port is initialized.
104812 +*//***************************************************************************/
104813 +int fm_port_disable(struct fm_port *port);
104814 +
104815 +void *fm_port_get_handle(const struct fm_port *port);
104816 +
104817 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
104818 + const void *data);
104819 +
104820 +/**************************************************************************//**
104821 + @Function fm_port_get_base_address
104822 +
104823 + @Description Get base address of this port. Useful for accessing
104824 + port-specific registers (i.e., not common ones).
104825 +
104826 + @Param[in] port - A handle of the FM port device.
104827 +
104828 + @Param[out] base_addr - The port's base addr (virtual address).
104829 +*//***************************************************************************/
104830 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr);
104831 +
104832 +/**************************************************************************//**
104833 + @Function fm_mutex_lock
104834 +
104835 + @Description Lock function required before any FMD/LLD call.
104836 +*//***************************************************************************/
104837 +void fm_mutex_lock(void);
104838 +
104839 +/**************************************************************************//**
104840 + @Function fm_mutex_unlock
104841 +
104842 + @Description Unlock function required after any FMD/LLD call.
104843 +*//***************************************************************************/
104844 +void fm_mutex_unlock(void);
104845 +
104846 +/**************************************************************************//**
104847 + @Function fm_get_max_frm
104848 +
104849 + @Description Get the maximum frame size
104850 +*//***************************************************************************/
104851 +int fm_get_max_frm(void);
104852 +
104853 +/**************************************************************************//**
104854 + @Function fm_get_rx_extra_headroom
104855 +
104856 + @Description Get the extra headroom size
104857 +*//***************************************************************************/
104858 +int fm_get_rx_extra_headroom(void);
104859 +
104860 +/**************************************************************************//**
104861 +@Function fm_port_set_rate_limit
104862 +
104863 +@Description Configure Shaper parameter on FM-port device (Tx port).
104864 +
104865 +@Param[in] port - A handle of the FM port device.
104866 +@Param[in] max_burst_size - Value of maximum burst size allowed.
104867 +@Param[in] rate_limit - The required rate value.
104868 +
104869 +@Cautions Allowed only after the port is initialized.
104870 +*//***************************************************************************/
104871 +int fm_port_set_rate_limit(struct fm_port *port,
104872 + uint16_t max_burst_size,
104873 + uint32_t rate_limit);
104874 +/**************************************************************************//**
104875 +@Function fm_port_set_rate_limit
104876 +
104877 +@Description Delete Shaper configuration on FM-port device (Tx port).
104878 +
104879 +@Param[in] port - A handle of the FM port device.
104880 +
104881 +@Cautions Allowed only after the port is initialized.
104882 +*//***************************************************************************/
104883 +int fm_port_del_rate_limit(struct fm_port *port);
104884 +
104885 +struct auto_res_tables_sizes
104886 +{
104887 + uint16_t max_num_of_arp_entries;
104888 + uint16_t max_num_of_echo_ipv4_entries;
104889 + uint16_t max_num_of_ndp_entries;
104890 + uint16_t max_num_of_echo_ipv6_entries;
104891 + uint16_t max_num_of_snmp_ipv4_entries;
104892 + uint16_t max_num_of_snmp_ipv6_entries;
104893 + uint16_t max_num_of_snmp_oid_entries;
104894 + uint16_t max_num_of_snmp_char; /* total amount of character needed
104895 + for the snmp table */
104896 + uint16_t max_num_of_ip_prot_filtering;
104897 + uint16_t max_num_of_tcp_port_filtering;
104898 + uint16_t max_num_of_udp_port_filtering;
104899 +};
104900 +/* ARP */
104901 +struct auto_res_arp_entry
104902 +{
104903 + uint32_t ip_address;
104904 + uint8_t mac[6];
104905 + bool is_vlan;
104906 + uint16_t vid;
104907 +};
104908 +struct auto_res_arp_info
104909 +{
104910 + uint8_t table_size;
104911 + struct auto_res_arp_entry *auto_res_table;
104912 + bool enable_conflict_detection; /* when TRUE
104913 + Conflict Detection will be checked and wake the host if
104914 + needed */
104915 +};
104916 +
104917 +/* NDP */
104918 +struct auto_res_ndp_entry
104919 +{
104920 + uint32_t ip_address[4];
104921 + uint8_t mac[6];
104922 + bool is_vlan;
104923 + uint16_t vid;
104924 +};
104925 +struct auto_res_ndp_info
104926 +{
104927 + uint32_t multicast_group;
104928 + uint8_t table_size_assigned;
104929 + struct auto_res_ndp_entry *auto_res_table_assigned; /* This list
104930 + refer to solicitation IP addresses. Note that all IP adresses
104931 + must be from the same multicast group. This will be checked and
104932 + if not operation will fail. */
104933 + uint8_t table_size_tmp;
104934 + struct auto_res_ndp_entry *auto_res_table_tmp; /* This list
104935 + refer to temp IP addresses. Note that all temp IP adresses must
104936 + be from the same multicast group. This will be checked and if
104937 + not operation will fail. */
104938 +
104939 + bool enable_conflict_detection; /* when TRUE
104940 + Conflict Detection will be checked and wake the host if
104941 + needed */
104942 +};
104943 +
104944 +/* ICMP ECHO */
104945 +struct auto_res_echo_ipv4_info
104946 +{
104947 + uint8_t table_size;
104948 + struct auto_res_arp_entry *auto_res_table;
104949 +};
104950 +
104951 +struct auto_res_echo_ipv6_info
104952 +{
104953 + uint8_t table_size;
104954 + struct auto_res_ndp_entry *auto_res_table;
104955 +};
104956 +
104957 +/* SNMP */
104958 +struct auto_res_snmp_entry
104959 +{
104960 + uint16_t oidSize;
104961 + uint8_t *oidVal; /* only the oid string */
104962 + uint16_t resSize;
104963 + uint8_t *resVal; /* resVal will be the entire reply,
104964 + i.e. "Type|Length|Value" */
104965 +};
104966 +
104967 +/**************************************************************************//**
104968 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
104969 + Refer to the FMan Controller spec for more details.
104970 +*//***************************************************************************/
104971 +struct auto_res_snmp_ipv4addr_tbl_entry
104972 +{
104973 + uint32_t ipv4addr; /*!< 32 bit IPv4 Address. */
104974 + bool is_vlan;
104975 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104976 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104977 +};
104978 +
104979 +/**************************************************************************//**
104980 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
104981 + Refer to the FMan Controller spec for more details.
104982 +*//***************************************************************************/
104983 +struct auto_res_snmp_ipv6addr_tbl_entry
104984 +{
104985 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
104986 + bool isVlan;
104987 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104988 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104989 +};
104990 +
104991 +struct auto_res_snmp_info
104992 +{
104993 + uint16_t control; /**< Control bits [0-15]. */
104994 + uint16_t max_snmp_msg_length; /**< Maximal allowed SNMP message length. */
104995 + uint16_t num_ipv4_addresses; /**< Number of entries in IPv4 addresses table. */
104996 + uint16_t num_ipv6_addresses; /**< Number of entries in IPv6 addresses table. */
104997 + struct auto_res_snmp_ipv4addr_tbl_entry *ipv4addr_tbl; /**< Pointer to IPv4 addresses table. */
104998 + struct auto_res_snmp_ipv6addr_tbl_entry *ipv6addr_tbl; /**< Pointer to IPv6 addresses table. */
104999 + char *community_read_write_string;
105000 + char *community_read_only_string;
105001 + struct auto_res_snmp_entry *oid_table;
105002 + uint32_t oid_table_size;
105003 + uint32_t *statistics;
105004 +};
105005 +
105006 +/* Filtering */
105007 +struct auto_res_port_filtering_entry
105008 +{
105009 + uint16_t src_port;
105010 + uint16_t dst_port;
105011 + uint16_t src_port_mask;
105012 + uint16_t dst_port_mask;
105013 +};
105014 +struct auto_res_filtering_info
105015 +{
105016 + /* IP protocol filtering parameters */
105017 + uint8_t ip_prot_table_size;
105018 + uint8_t *ip_prot_table_ptr;
105019 + bool ip_prot_pass_on_hit; /* when TRUE, miss in the table will
105020 + cause the packet to be droped, hit will pass the packet to
105021 + UDP/TCP filters if needed and if not to the classification
105022 + tree. If the classification tree will pass the packet to a
105023 + queue it will cause a wake interupt. When FALSE it the other
105024 + way around. */
105025 + /* UDP port filtering parameters */
105026 + uint8_t udp_ports_table_size;
105027 + struct auto_res_port_filtering_entry *udp_ports_table_ptr;
105028 + bool udp_port_pass_on_hit; /* when TRUE, miss in the table will
105029 + cause the packet to be droped, hit will pass the packet to
105030 + classification tree. If the classification tree will pass the
105031 + packet to a queue it will cause a wake interupt. When FALSE it
105032 + the other way around. */
105033 + /* TCP port filtering parameters */
105034 + uint16_t tcp_flags_mask;
105035 + uint8_t tcp_ports_table_size;
105036 + struct auto_res_port_filtering_entry *tcp_ports_table_ptr;
105037 + bool tcp_port_pass_on_hit; /* when TRUE, miss in the table will
105038 + cause the packet to be droped, hit will pass the packet to
105039 + classification tree. If the classification tree will pass the
105040 + packet to a queue it will cause a wake interupt. When FALSE it
105041 + the other way around. */
105042 +};
105043 +
105044 +struct auto_res_port_params
105045 +{
105046 + t_Handle h_FmPortTx;
105047 + struct auto_res_arp_info *p_auto_res_arp_info;
105048 + struct auto_res_echo_ipv4_info *p_auto_res_echo_ipv4_info;
105049 + struct auto_res_ndp_info *p_auto_res_ndp_info;
105050 + struct auto_res_echo_ipv6_info *p_auto_res_echo_ipv6_info;
105051 + struct auto_res_snmp_info *p_auto_res_snmp_info;
105052 + struct auto_res_filtering_info *p_auto_res_filtering_info;
105053 +};
105054 +
105055 +struct auto_res_port_stats
105056 +{
105057 + uint32_t arp_ar_cnt;
105058 + uint32_t echo_icmpv4_ar_cnt;
105059 + uint32_t ndp_ar_cnt;
105060 + uint32_t echo_icmpv6_ar_cnt;
105061 +};
105062 +
105063 +int fm_port_config_autores_for_deepsleep_support(struct fm_port *port,
105064 + struct auto_res_tables_sizes *params);
105065 +
105066 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
105067 + struct auto_res_port_params *params);
105068 +
105069 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
105070 + struct fm_port *port_tx);
105071 +
105072 +bool fm_port_is_in_auto_res_mode(struct fm_port *port);
105073 +
105074 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
105075 + struct fm_port *port);
105076 +
105077 +int fm_port_get_autores_stats(struct fm_port *port, struct auto_res_port_stats
105078 + *stats);
105079 +
105080 +int fm_port_resume(struct fm_port *port);
105081 +
105082 +int fm_port_suspend(struct fm_port *port);
105083 +
105084 +#ifdef CONFIG_FMAN_PFC
105085 +/**************************************************************************//**
105086 +@Function fm_port_set_pfc_priorities_mapping_to_qman_wq
105087 +
105088 +@Description Associate a QMan Work Queue with a PFC priority on this
105089 + FM-port device (Tx port).
105090 +
105091 +@Param[in] port - A handle of the FM port device.
105092 +
105093 +@Param[in] prio - The PFC priority.
105094 +
105095 +@Param[in] wq - The Work Queue associated with the PFC priority.
105096 +
105097 +@Cautions Allowed only after the port is initialized.
105098 +*//***************************************************************************/
105099 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
105100 + uint8_t prio, uint8_t wq);
105101 +#endif
105102 +
105103 +/**************************************************************************//**
105104 +@Function fm_mac_set_exception
105105 +
105106 +@Description Set MAC exception state.
105107 +
105108 +@Param[in] fm_mac_dev - A handle of the FM MAC device.
105109 +@Param[in] exception - FM MAC exception type.
105110 +@Param[in] enable - new state.
105111 +
105112 +*//***************************************************************************/
105113 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
105114 + e_FmMacExceptions exception, bool enable);
105115 +
105116 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev);
105117 +
105118 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params);
105119 +
105120 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
105121 + int len);
105122 +
105123 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable);
105124 +
105125 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable);
105126 +
105127 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable);
105128 +
105129 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev);
105130 +
105131 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version);
105132 +
105133 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev);
105134 +
105135 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev);
105136 +
105137 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev);
105138 +
105139 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
105140 + bool enable);
105141 +
105142 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
105143 + t_EnetAddr *mac_addr);
105144 +
105145 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
105146 + t_EnetAddr *mac_addr);
105147 +
105148 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
105149 + uint8_t *addr);
105150 +
105151 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
105152 + bool link, int speed, bool duplex);
105153 +
105154 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
105155 +
105156 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
105157 +
105158 +int fm_mac_set_rx_pause_frames(
105159 + struct fm_mac_dev *fm_mac_dev, bool en);
105160 +
105161 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
105162 + bool en);
105163 +
105164 +int fm_rtc_enable(struct fm *fm_dev);
105165 +
105166 +int fm_rtc_disable(struct fm *fm_dev);
105167 +
105168 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts);
105169 +
105170 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts);
105171 +
105172 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift);
105173 +
105174 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift);
105175 +
105176 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
105177 + uint64_t time);
105178 +
105179 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
105180 + uint64_t fiper);
105181 +
105182 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
105183 + bool en);
105184 +
105185 +/**************************************************************************//**
105186 +@Function fm_macsec_set_exception
105187 +
105188 +@Description Set MACSEC exception state.
105189 +
105190 +@Param[in] fm_macsec_dev - A handle of the FM MACSEC device.
105191 +@Param[in] exception - FM MACSEC exception type.
105192 +@Param[in] enable - new state.
105193 +
105194 +*//***************************************************************************/
105195 +
105196 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
105197 + fm_macsec_exception exception, bool enable);
105198 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev);
105199 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params);
105200 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev);
105201 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
105202 + *fm_macsec_dev,
105203 + fm_macsec_unknown_sci_frame_treatment treat_mode);
105204 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
105205 + bool deliver_uncontrolled);
105206 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
105207 + bool discard_uncontrolled);
105208 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
105209 + fm_macsec_untag_frame_treatment treat_mode);
105210 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
105211 + uint32_t pnExhThr);
105212 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev);
105213 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev);
105214 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
105215 + fm_macsec_exception exception, bool enable);
105216 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
105217 + int *macsec_revision);
105218 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev);
105219 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev);
105220 +
105221 +
105222 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105223 + fm_macsec_secy_exception exception,
105224 + bool enable);
105225 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
105226 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params);
105227 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
105228 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105229 + fm_macsec_sci_insertion_mode sci_insertion_mode);
105230 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105231 + bool protect_frames);
105232 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105233 + bool replay_protect, uint32_t replay_window);
105234 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105235 + fm_macsec_valid_frame_behavior validate_frames);
105236 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105237 + bool confidentiality_enable,
105238 + uint32_t confidentiality_offset);
105239 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
105240 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105241 + fm_macsec_secy_event event,
105242 + bool enable);
105243 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105244 + struct fm_macsec_secy_sc_params *params);
105245 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105246 + struct rx_sc_dev *sc);
105247 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105248 + struct rx_sc_dev *sc, macsec_an_t an,
105249 + uint32_t lowest_pn, macsec_sa_key_t key);
105250 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105251 + struct rx_sc_dev *sc, macsec_an_t an);
105252 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105253 + struct rx_sc_dev *sc,
105254 + macsec_an_t an);
105255 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105256 + struct rx_sc_dev *sc,
105257 + macsec_an_t an);
105258 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105259 + struct rx_sc_dev *sc,
105260 + macsec_an_t an, uint32_t updt_next_pn);
105261 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105262 + struct rx_sc_dev *sc,
105263 + macsec_an_t an, uint32_t updt_lowest_pn);
105264 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105265 + struct rx_sc_dev *sc,
105266 + macsec_an_t an, macsec_sa_key_t key);
105267 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105268 + macsec_an_t an, macsec_sa_key_t key);
105269 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105270 + macsec_an_t an);
105271 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105272 + macsec_an_t next_active_an,
105273 + macsec_sa_key_t key);
105274 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105275 + macsec_an_t an);
105276 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105277 + macsec_an_t *p_an);
105278 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105279 + struct rx_sc_dev *sc, uint32_t *sc_phys_id);
105280 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
105281 + uint32_t *sc_phys_id);
105282 +
105283 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
105284 +/** @} */ /* end of FM_LnxKern_grp group */
105285 +
105286 +/* default values for initializing PTP 1588 timer clock */
105287 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT 2 /* power of 2 for better performance */
105288 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_NS (1 << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT) /* 4ns,250MHz */
105289 +
105290 +#endif /* __LNXWRP_FSL_FMAN_H */
105291 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
105292 new file mode 100644
105293 index 00000000..b183c86d
105294 --- /dev/null
105295 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
105296 @@ -0,0 +1,50 @@
105297 +/*
105298 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105299 + *
105300 + * Redistribution and use in source and binary forms, with or without
105301 + * modification, are permitted provided that the following conditions are met:
105302 + * * Redistributions of source code must retain the above copyright
105303 + * notice, this list of conditions and the following disclaimer.
105304 + * * Redistributions in binary form must reproduce the above copyright
105305 + * notice, this list of conditions and the following disclaimer in the
105306 + * documentation and/or other materials provided with the distribution.
105307 + * * Neither the name of Freescale Semiconductor nor the
105308 + * names of its contributors may be used to endorse or promote products
105309 + * derived from this software without specific prior written permission.
105310 + *
105311 + *
105312 + * ALTERNATIVELY, this software may be distributed under the terms of the
105313 + * GNU General Public License ("GPL") as published by the Free Software
105314 + * Foundation, either version 2 of that License or (at your option) any
105315 + * later version.
105316 + *
105317 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105318 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105319 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105320 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105321 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105322 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105323 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105324 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105325 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105326 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105327 + */
105328 +
105329 +#ifndef __XX_H
105330 +#define __XX_H
105331 +
105332 +#include "xx_ext.h"
105333 +
105334 +void * xx_Malloc(uint32_t n);
105335 +void xx_Free(void *p);
105336 +
105337 +void *xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t align);
105338 +void xx_FreeSmart(void *p);
105339 +
105340 +/* never used: */
105341 +#define GetDeviceName(irq) ((char *)NULL)
105342 +
105343 +int GetDeviceIrqNum(int irq);
105344 +
105345 +
105346 +#endif /* __XX_H */
105347 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
105348 new file mode 100644
105349 index 00000000..667cd859
105350 --- /dev/null
105351 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
105352 @@ -0,0 +1,10 @@
105353 +#
105354 +# Makefile for the Freescale Ethernet controllers
105355 +#
105356 +ccflags-y += -DVERSION=\"\"
105357 +#
105358 +#Include netcomm SW specific definitions
105359 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
105360 +#
105361 +
105362 +obj-y += sys_io.o
105363 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
105364 new file mode 100644
105365 index 00000000..c106a8b7
105366 --- /dev/null
105367 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
105368 @@ -0,0 +1,171 @@
105369 +/*
105370 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105371 + *
105372 + * Redistribution and use in source and binary forms, with or without
105373 + * modification, are permitted provided that the following conditions are met:
105374 + * * Redistributions of source code must retain the above copyright
105375 + * notice, this list of conditions and the following disclaimer.
105376 + * * Redistributions in binary form must reproduce the above copyright
105377 + * notice, this list of conditions and the following disclaimer in the
105378 + * documentation and/or other materials provided with the distribution.
105379 + * * Neither the name of Freescale Semiconductor nor the
105380 + * names of its contributors may be used to endorse or promote products
105381 + * derived from this software without specific prior written permission.
105382 + *
105383 + *
105384 + * ALTERNATIVELY, this software may be distributed under the terms of the
105385 + * GNU General Public License ("GPL") as published by the Free Software
105386 + * Foundation, either version 2 of that License or (at your option) any
105387 + * later version.
105388 + *
105389 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105390 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105391 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105392 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105393 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105394 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105395 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105396 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105397 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105398 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105399 + */
105400 +
105401 +#include <linux/version.h>
105402 +
105403 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
105404 +#define MODVERSIONS
105405 +#endif
105406 +#ifdef MODVERSIONS
105407 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
105408 +#include <linux/modversions.h>
105409 +#else
105410 +#include <config/modversions.h>
105411 +#endif /* LINUX_VERSION_CODE */
105412 +#endif /* MODVERSIONS */
105413 +
105414 +#include <linux/module.h>
105415 +#include <linux/kernel.h>
105416 +
105417 +#include <asm/io.h>
105418 +
105419 +#include "std_ext.h"
105420 +#include "error_ext.h"
105421 +#include "string_ext.h"
105422 +#include "list_ext.h"
105423 +#include "sys_io_ext.h"
105424 +
105425 +
105426 +#define __ERR_MODULE__ MODULE_UNKNOWN
105427 +
105428 +
105429 +typedef struct {
105430 + uint64_t virtAddr;
105431 + uint64_t physAddr;
105432 + uint32_t size;
105433 + t_List node;
105434 +} t_IoMap;
105435 +#define IOMAP_OBJECT(ptr) LIST_OBJECT(ptr, t_IoMap, node)
105436 +
105437 +LIST(mapsList);
105438 +
105439 +
105440 +static void EnqueueIoMap(t_IoMap *p_IoMap)
105441 +{
105442 + uint32_t intFlags;
105443 +
105444 + intFlags = XX_DisableAllIntr();
105445 + LIST_AddToTail(&p_IoMap->node, &mapsList);
105446 + XX_RestoreAllIntr(intFlags);
105447 +}
105448 +
105449 +static t_IoMap * FindIoMapByVirtAddr(uint64_t addr)
105450 +{
105451 + t_IoMap *p_IoMap;
105452 + t_List *p_Pos;
105453 +
105454 + LIST_FOR_EACH(p_Pos, &mapsList)
105455 + {
105456 + p_IoMap = IOMAP_OBJECT(p_Pos);
105457 + if ((addr >= p_IoMap->virtAddr) && (addr < p_IoMap->virtAddr+p_IoMap->size))
105458 + return p_IoMap;
105459 + }
105460 +
105461 + return NULL;
105462 +}
105463 +
105464 +static t_IoMap * FindIoMapByPhysAddr(uint64_t addr)
105465 +{
105466 + t_IoMap *p_IoMap;
105467 + t_List *p_Pos;
105468 +
105469 + LIST_FOR_EACH(p_Pos, &mapsList)
105470 + {
105471 + p_IoMap = IOMAP_OBJECT(p_Pos);
105472 + if ((addr >= p_IoMap->physAddr) && (addr < p_IoMap->physAddr+p_IoMap->size))
105473 + return p_IoMap;
105474 + }
105475 +
105476 + return NULL;
105477 +}
105478 +
105479 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size)
105480 +{
105481 + t_IoMap *p_IoMap;
105482 +
105483 + p_IoMap = (t_IoMap*)XX_Malloc(sizeof(t_IoMap));
105484 + if (!p_IoMap)
105485 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
105486 + memset(p_IoMap, 0, sizeof(t_IoMap));
105487 +
105488 + p_IoMap->virtAddr = virtAddr;
105489 + p_IoMap->physAddr = physAddr;
105490 + p_IoMap->size = size;
105491 +
105492 + INIT_LIST(&p_IoMap->node);
105493 + EnqueueIoMap(p_IoMap);
105494 +
105495 + return E_OK;
105496 +}
105497 +
105498 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr)
105499 +{
105500 + t_IoMap *p_IoMap = FindIoMapByVirtAddr(virtAddr);
105501 + if (!p_IoMap)
105502 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
105503 +
105504 + LIST_Del(&p_IoMap->node);
105505 + XX_Free(p_IoMap);
105506 +
105507 + return E_OK;
105508 +}
105509 +
105510 +uint64_t SYS_PhysToVirt(uint64_t addr)
105511 +{
105512 + t_IoMap *p_IoMap = FindIoMapByPhysAddr(addr);
105513 + if (p_IoMap)
105514 + {
105515 + /* This is optimization - put the latest in the list-head - like a cache */
105516 + if (mapsList.p_Next != &p_IoMap->node)
105517 + {
105518 + uint32_t intFlags = XX_DisableAllIntr();
105519 + LIST_DelAndInit(&p_IoMap->node);
105520 + LIST_Add(&p_IoMap->node, &mapsList);
105521 + XX_RestoreAllIntr(intFlags);
105522 + }
105523 + return (uint64_t)(addr - p_IoMap->physAddr + p_IoMap->virtAddr);
105524 + }
105525 + return PTR_TO_UINT(phys_to_virt((unsigned long)addr));
105526 +}
105527 +
105528 +uint64_t SYS_VirtToPhys(uint64_t addr)
105529 +{
105530 + t_IoMap *p_IoMap;
105531 +
105532 + if (addr == 0)
105533 + return 0;
105534 +
105535 + p_IoMap = FindIoMapByVirtAddr(addr);
105536 + if (p_IoMap)
105537 + return (uint64_t)(addr - p_IoMap->virtAddr + p_IoMap->physAddr);
105538 + return (uint64_t)virt_to_phys(UINT_TO_PTR(addr));
105539 +}
105540 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
105541 new file mode 100644
105542 index 00000000..62713d62
105543 --- /dev/null
105544 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
105545 @@ -0,0 +1,19 @@
105546 +#
105547 +# Makefile for the Freescale Ethernet controllers
105548 +#
105549 +ccflags-y += -DVERSION=\"\"
105550 +#
105551 +#Include netcomm SW specific definitions
105552 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
105553 +
105554 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
105555 +
105556 +ccflags-y += -I$(NCSW_FM_INC)
105557 +ccflags-y += -I$(NET_DPA)
105558 +
105559 +obj-y += fsl-ncsw-PFM.o
105560 +obj-$(CONFIG_FSL_SDK_FMAN_TEST) += fman_test.o
105561 +
105562 +fsl-ncsw-PFM-objs := lnxwrp_fm.o lnxwrp_fm_port.o lnxwrp_ioctls_fm.o \
105563 + lnxwrp_sysfs.o lnxwrp_sysfs_fm.o lnxwrp_sysfs_fm_port.o
105564 +obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o
105565 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
105566 new file mode 100644
105567 index 00000000..270d07b8
105568 --- /dev/null
105569 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
105570 @@ -0,0 +1,1665 @@
105571 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
105572 + * All rights reserved.
105573 + *
105574 + * Redistribution and use in source and binary forms, with or without
105575 + * modification, are permitted provided that the following conditions are met:
105576 + * * Redistributions of source code must retain the above copyright
105577 + * notice, this list of conditions and the following disclaimer.
105578 + * * Redistributions in binary form must reproduce the above copyright
105579 + * notice, this list of conditions and the following disclaimer in the
105580 + * documentation and/or other materials provided with the distribution.
105581 + * * Neither the name of Freescale Semiconductor nor the
105582 + * names of its contributors may be used to endorse or promote products
105583 + * derived from this software without specific prior written permission.
105584 + *
105585 + *
105586 + * ALTERNATIVELY, this software may be distributed under the terms of the
105587 + * GNU General Public License ("GPL") as published by the Free Software
105588 + * Foundation, either version 2 of that License or (at your option) any
105589 + * later version.
105590 + *
105591 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105592 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105593 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105594 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105595 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105596 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105597 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105598 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105599 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105600 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105601 + */
105602 +
105603 +/*
105604 + @File fman_test.c
105605 + @Authors Pistirica Sorin Andrei
105606 + @Description FM Linux test environment
105607 +*/
105608 +
105609 +#include <linux/kernel.h>
105610 +#include <linux/module.h>
105611 +#include <linux/fs.h>
105612 +#include <linux/cdev.h>
105613 +#include <linux/device.h>
105614 +#include <linux/io.h>
105615 +#include <linux/ioport.h>
105616 +#include <linux/of_platform.h>
105617 +#include <linux/ip.h>
105618 +#include <linux/compat.h>
105619 +#include <linux/uaccess.h>
105620 +#include <linux/errno.h>
105621 +#include <linux/netdevice.h>
105622 +#include <linux/spinlock.h>
105623 +#include <linux/types.h>
105624 +#include <linux/fsl_qman.h>
105625 +#include <linux/fsl_bman.h>
105626 +
105627 +/* private headers */
105628 +#include "fm_ext.h"
105629 +#include "lnxwrp_fsl_fman.h"
105630 +#include "fm_port_ext.h"
105631 +#if (DPAA_VERSION == 11)
105632 +#include "../../Peripherals/FM/MAC/memac.h"
105633 +#endif
105634 +#include "fm_test_ioctls.h"
105635 +#include "fsl_fman_test.h"
105636 +
105637 +#include "dpaa_eth.h"
105638 +#include "dpaa_eth_common.h"
105639 +
105640 +#define FMT_FRM_WATERMARK 0xdeadbeefdeadbeeaLL
105641 +
105642 +struct fmt_frame_s {
105643 + ioc_fmt_buff_desc_t buff;
105644 + struct list_head list;
105645 +};
105646 +
105647 +struct fmt_fqs_s {
105648 + struct qman_fq fq_base;
105649 + bool init;
105650 + struct fmt_port_s *fmt_port_priv;
105651 +};
105652 +
105653 +struct fmt_port_pcd_s {
105654 + int num_queues;
105655 + struct fmt_fqs_s *fmt_pcd_fqs;
105656 + uint32_t fqid_base;
105657 +};
105658 +
105659 +/* char dev structure: fm test port */
105660 +struct fmt_port_s {
105661 + bool valid;
105662 + uint8_t id;
105663 + ioc_fmt_port_type port_type;
105664 + ioc_diag_mode diag;
105665 + bool compat_test_type;
105666 +
105667 + /* fm ports */
105668 + /* ! for oh ports p_tx_fm_port_dev == p_rx_fm_port_dev &&
105669 + * p_tx_port == p_rx_port */
105670 + /* t_LnxWrpFmPortDev */
105671 + struct fm_port *p_tx_port;
105672 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
105673 + void *p_tx_fm_port_dev;
105674 + /* t_LnxWrpFmPortDev */
105675 + struct fm_port *p_rx_port;
105676 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
105677 + void *p_rx_fm_port_dev;
105678 +
105679 + void *p_mac_dev;
105680 + uint64_t fm_phys_base_addr;
105681 +
105682 + /* read/write queue manipulation */
105683 + spinlock_t rx_q_lock;
105684 + struct list_head rx_q;
105685 +
105686 + /* tx queuee for injecting traffic */
105687 + int num_of_tx_fqs;
105688 + struct fmt_fqs_s p_tx_fqs[FMAN_TEST_MAX_TX_FQS];
105689 +
105690 + /* pcd private queues manipulation */
105691 + struct fmt_port_pcd_s fmt_port_pcd;
105692 +
105693 + /* debugging stuff */
105694 +
105695 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105696 + atomic_t enqueue_to_qman_frm;
105697 + atomic_t enqueue_to_rxq;
105698 + atomic_t dequeue_from_rxq;
105699 + atomic_t not_enqueue_to_rxq_wrong_frm;
105700 +#endif
105701 +
105702 +};
105703 +
105704 +/* The devices. */
105705 +struct fmt_s {
105706 + int major;
105707 + struct fmt_port_s ports[IOC_FMT_MAX_NUM_OF_PORTS];
105708 + struct class *fmt_class;
105709 +};
105710 +
105711 +/* fm test structure */
105712 +static struct fmt_s fm_test;
105713 +
105714 +#if (DPAA_VERSION == 11)
105715 +struct mac_priv_s {
105716 + t_Handle mac;
105717 +};
105718 +#endif
105719 +
105720 +#define DTSEC_BASE_ADDR 0x000e0000
105721 +#define DTSEC_MEM_RANGE 0x00002000
105722 +#define MAC_1G_MACCFG1 0x00000100
105723 +#define MAC_1G_LOOP_MASK 0x00000100
105724 +static int set_1gmac_loopback(
105725 + struct fmt_port_s *fmt_port,
105726 + bool en)
105727 +{
105728 +#if (DPAA_VERSION <= 10)
105729 + uint32_t dtsec_idx = fmt_port->id; /* dtsec for which port */
105730 + uint32_t dtsec_idx_off = dtsec_idx * DTSEC_MEM_RANGE;
105731 + phys_addr_t maccfg1_hw;
105732 + void *maccfg1_map;
105733 + uint32_t maccfg1_val;
105734 +
105735 + /* compute the maccfg1 register address */
105736 + maccfg1_hw = fmt_port->fm_phys_base_addr +
105737 + (phys_addr_t)(DTSEC_BASE_ADDR +
105738 + dtsec_idx_off +
105739 + MAC_1G_MACCFG1);
105740 +
105741 + /* map register */
105742 + maccfg1_map = ioremap(maccfg1_hw, sizeof(u32));
105743 +
105744 + /* set register */
105745 + maccfg1_val = in_be32(maccfg1_map);
105746 + if (en)
105747 + maccfg1_val |= MAC_1G_LOOP_MASK;
105748 + else
105749 + maccfg1_val &= ~MAC_1G_LOOP_MASK;
105750 + out_be32(maccfg1_map, maccfg1_val);
105751 +
105752 + /* unmap register */
105753 + iounmap(maccfg1_map);
105754 +#else
105755 + struct mac_device *mac_dev;
105756 + struct mac_priv_s *priv;
105757 + t_Memac *p_memac;
105758 +
105759 + if (!fmt_port)
105760 + return -EINVAL;
105761 +
105762 + mac_dev = (struct mac_device *)fmt_port->p_mac_dev;
105763 +
105764 + if (!mac_dev)
105765 + return -EINVAL;
105766 +
105767 + priv = macdev_priv(mac_dev);
105768 +
105769 + if (!priv)
105770 + return -EINVAL;
105771 +
105772 + p_memac = priv->mac;
105773 +
105774 + if (!p_memac)
105775 + return -EINVAL;
105776 +
105777 + memac_set_loopback(p_memac->p_MemMap, en);
105778 +#endif
105779 + return 0;
105780 +}
105781 +
105782 +/* TODO: re-write this function */
105783 +static int set_10gmac_int_loopback(
105784 + struct fmt_port_s *fmt_port,
105785 + bool en)
105786 +{
105787 +#ifndef FM_10G_MAC_NO_CTRL_LOOPBACK
105788 +#define FM_10GMAC0_OFFSET 0x000f0000
105789 +#define FM_10GMAC_CMD_CONF_CTRL_OFFSET 0x8
105790 +#define CMD_CFG_LOOPBACK_EN 0x00000400
105791 +
105792 + uint64_t base_addr, reg_addr;
105793 + uint32_t tmp_val;
105794 +
105795 + base_addr = fmt_port->fm_phys_base_addr + (FM_10GMAC0_OFFSET +
105796 + ((fmt_port->id-FM_MAX_NUM_OF_1G_RX_PORTS)*0x2000));
105797 +
105798 + base_addr = PTR_TO_UINT(ioremap(base_addr, 0x1000));
105799 +
105800 + reg_addr = base_addr + FM_10GMAC_CMD_CONF_CTRL_OFFSET;
105801 + tmp_val = GET_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)));
105802 + if (en)
105803 + tmp_val |= CMD_CFG_LOOPBACK_EN;
105804 + else
105805 + tmp_val &= ~CMD_CFG_LOOPBACK_EN;
105806 + WRITE_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)), tmp_val);
105807 +
105808 + iounmap(UINT_TO_PTR(base_addr));
105809 +
105810 + return 0;
105811 +#else
105812 + _fmt_err("TGEC don't have internal-loopback.\n");
105813 + return -EPERM;
105814 +#endif
105815 +}
105816 +
105817 +static int set_mac_int_loopback(struct fmt_port_s *fmt_port, bool en)
105818 +{
105819 + int _err = 0;
105820 +
105821 + switch (fmt_port->port_type) {
105822 +
105823 + case e_IOC_FMT_PORT_T_RXTX:
105824 + /* 1G port */
105825 + if (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS)
105826 + _err = set_1gmac_loopback(fmt_port, en);
105827 + /* 10g port */
105828 + else if ((fmt_port->id >= FM_MAX_NUM_OF_1G_RX_PORTS) &&
105829 + (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS +
105830 + FM_MAX_NUM_OF_10G_RX_PORTS)) {
105831 +
105832 + _err = set_10gmac_int_loopback(fmt_port, en);
105833 + } else
105834 + _err = -EINVAL;
105835 + break;
105836 + /* op port does not have MAC (loopback mode) */
105837 + case e_IOC_FMT_PORT_T_OP:
105838 +
105839 + _err = 0;
105840 + break;
105841 + default:
105842 +
105843 + _err = -EPERM;
105844 + break;
105845 + }
105846 +
105847 + return _err;
105848 +}
105849 +
105850 +static void enqueue_fmt_frame(
105851 + struct fmt_port_s *fmt_port,
105852 + struct fmt_frame_s *p_fmt_frame)
105853 +{
105854 + spinlock_t *rx_q_lock = NULL;
105855 +
105856 + rx_q_lock = &fmt_port->rx_q_lock;
105857 +
105858 + spin_lock(rx_q_lock);
105859 + list_add_tail(&p_fmt_frame->list, &fmt_port->rx_q);
105860 + spin_unlock(rx_q_lock);
105861 +
105862 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105863 + atomic_inc(&fmt_port->enqueue_to_rxq);
105864 +#endif
105865 +}
105866 +
105867 +static struct fmt_frame_s *dequeue_fmt_frame(
105868 + struct fmt_port_s *fmt_port)
105869 +{
105870 + struct fmt_frame_s *p_fmt_frame = NULL;
105871 + spinlock_t *rx_q_lock = NULL;
105872 +
105873 + rx_q_lock = &fmt_port->rx_q_lock;
105874 +
105875 + spin_lock(rx_q_lock);
105876 +
105877 +#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
105878 +
105879 + if (!list_empty(&fmt_port->rx_q)) {
105880 + p_fmt_frame = list_last_entry(&fmt_port->rx_q,
105881 + struct fmt_frame_s,
105882 + list);
105883 + list_del(&p_fmt_frame->list);
105884 +
105885 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105886 + atomic_inc(&fmt_port->dequeue_from_rxq);
105887 +#endif
105888 + }
105889 +
105890 + spin_unlock(rx_q_lock);
105891 +
105892 + return p_fmt_frame;
105893 +}
105894 +
105895 +/* eth-dev -to- fmt port association */
105896 +struct fmt_port_s *match_dpa_to_fmt_port(
105897 + struct dpa_priv_s *dpa_priv) {
105898 + struct mac_device *mac_dev = dpa_priv->mac_dev;
105899 + struct fm_port *fm_port = (struct fm_port *) mac_dev;
105900 + struct fmt_port_s *fmt_port = NULL;
105901 + int i;
105902 +
105903 + _fmt_dbgr("calling...\n");
105904 +
105905 + /* find the FM-test-port object */
105906 + for (i = 0; i < IOC_FMT_MAX_NUM_OF_PORTS; i++)
105907 + if ((fm_test.ports[i].p_mac_dev &&
105908 + mac_dev == fm_test.ports[i].p_mac_dev) ||
105909 + fm_port == fm_test.ports[i].p_tx_port) {
105910 +
105911 + fmt_port = &fm_test.ports[i];
105912 + break;
105913 + }
105914 +
105915 + _fmt_dbgr("called\n");
105916 + return fmt_port;
105917 +}
105918 +
105919 +void dump_frame(
105920 + uint8_t *buffer,
105921 + uint32_t size)
105922 +{
105923 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105924 + unsigned int i;
105925 +
105926 + for (i = 0; i < size; i++) {
105927 + if (i%16 == 0)
105928 + printk(KERN_DEBUG "\n");
105929 + printk(KERN_DEBUG "%2x ", *(buffer+i));
105930 + }
105931 +#endif
105932 + return;
105933 +}
105934 +
105935 +bool test_and_steal_frame(struct fmt_port_s *fmt_port,
105936 + uint32_t fqid,
105937 + uint8_t *buffer,
105938 + uint32_t size)
105939 +{
105940 + struct fmt_frame_s *p_fmt_frame = NULL;
105941 + bool test_and_steal_frame_frame;
105942 + uint32_t data_offset;
105943 + uint32_t i;
105944 +
105945 + _fmt_dbgr("calling...\n");
105946 +
105947 + if (!fmt_port || !fmt_port->p_rx_fm_port_dev)
105948 + return false;
105949 +
105950 + /* check watermark */
105951 + test_and_steal_frame_frame = false;
105952 + for (i = 0; i < size; i++) {
105953 + uint64_t temp = *((uint64_t *)(buffer + i));
105954 +
105955 + if (temp == (uint64_t) FMT_FRM_WATERMARK) {
105956 + _fmt_dbgr("watermark found!\n");
105957 + test_and_steal_frame_frame = true;
105958 + break;
105959 + }
105960 + }
105961 +
105962 + if (!test_and_steal_frame_frame) {
105963 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105964 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
105965 +#endif
105966 + _fmt_dbgr("NOT watermark found!\n");
105967 + return false;
105968 + }
105969 +
105970 + /* do not enqueue the tx conf/err frames */
105971 + if ((fqid == FMT_TX_CONF_Q) || (fqid == FMT_TX_ERR_Q))
105972 + goto _test_and_steal_frame_return_true;
105973 +
105974 + _fmt_dbgr("on port %d got FMUC frame\n", fmt_port->id);
105975 + data_offset = FM_PORT_GetBufferDataOffset(
105976 + fmt_port->p_rx_fm_port_dev);
105977 +
105978 + p_fmt_frame = kmalloc(sizeof(struct fmt_frame_s), GFP_KERNEL);
105979 +
105980 + /* dump frame... no more space left on device */
105981 + if (p_fmt_frame == NULL) {
105982 + _fmt_err("no space left on device!\n");
105983 + goto _test_and_steal_frame_return_true;
105984 + }
105985 +
105986 + memset(p_fmt_frame, 0, sizeof(struct fmt_frame_s));
105987 + p_fmt_frame->buff.p_data = kmalloc(size * sizeof(uint8_t), GFP_KERNEL);
105988 +
105989 + /* No more space left on device*/
105990 + if (p_fmt_frame->buff.p_data == NULL) {
105991 + _fmt_err("no space left on device!\n");
105992 + kfree(p_fmt_frame);
105993 + goto _test_and_steal_frame_return_true;
105994 + }
105995 +
105996 + p_fmt_frame->buff.size = size-data_offset;
105997 + p_fmt_frame->buff.qid = fqid;
105998 +
105999 + memcpy(p_fmt_frame->buff.p_data,
106000 + (uint8_t *)PTR_MOVE(buffer, data_offset),
106001 + p_fmt_frame->buff.size);
106002 +
106003 + memcpy(p_fmt_frame->buff.buff_context.fm_prs_res,
106004 + FM_PORT_GetBufferPrsResult(fmt_port->p_rx_fm_port_dev,
106005 + (char *)buffer),
106006 + 32);
106007 +
106008 + /* enqueue frame - this frame will go to us */
106009 + enqueue_fmt_frame(fmt_port, p_fmt_frame);
106010 +
106011 +_test_and_steal_frame_return_true:
106012 + return true;
106013 +}
106014 +
106015 +static int fmt_fq_release(const struct qm_fd *fd)
106016 +{
106017 + struct dpa_bp *_dpa_bp;
106018 + struct bm_buffer _bmb;
106019 +
106020 + if (fd->format == qm_fd_contig) {
106021 + _dpa_bp = dpa_bpid2pool(fd->bpid);
106022 + BUG_ON(IS_ERR(_dpa_bp));
106023 +
106024 + _bmb.hi = fd->addr_hi;
106025 + _bmb.lo = fd->addr_lo;
106026 +
106027 + while (bman_release(_dpa_bp->pool, &_bmb, 1, 0))
106028 + cpu_relax();
106029 +
106030 + } else {
106031 + _fmt_err("frame not supported !\n");
106032 + return -1;
106033 + }
106034 +
106035 + return 0;
106036 +}
106037 +
106038 +/* sync it w/ dpaa_eth.c: DPA_BP_HEAD */
106039 +#define DPA_BP_HEADROOM (DPA_TX_PRIV_DATA_SIZE + \
106040 + fm_get_rx_extra_headroom() + \
106041 + DPA_PARSE_RESULTS_SIZE + \
106042 + DPA_HASH_RESULTS_SIZE)
106043 +#define MAC_HEADER_LENGTH 14
106044 +#define L2_AND_HEADROOM_OFF ((DPA_BP_HEADROOM) + (MAC_HEADER_LENGTH))
106045 +
106046 +/* dpa ingress hooks definition */
106047 +enum dpaa_eth_hook_result fmt_rx_default_hook(
106048 + struct sk_buff *skb,
106049 + struct net_device *net_dev,
106050 + u32 fqid)
106051 +{
106052 + struct dpa_priv_s *dpa_priv = NULL;
106053 + struct fmt_port_s *fmt_port = NULL;
106054 + uint8_t *buffer;
106055 + uint32_t buffer_len;
106056 +
106057 + _fmt_dbgr("calling...\n");
106058 +
106059 + dpa_priv = netdev_priv(net_dev);
106060 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106061 +
106062 + /* conversion from skb to fd:
106063 + * skb cames processed for L3, so we need to go back for
106064 + * layer 2 offset */
106065 + buffer = (uint8_t *)(skb->data - ((int)L2_AND_HEADROOM_OFF));
106066 + buffer_len = skb->len + ((int)L2_AND_HEADROOM_OFF);
106067 +
106068 + /* if is not out frame let dpa to handle it */
106069 + if (test_and_steal_frame(fmt_port,
106070 + FMT_RX_DFLT_Q,
106071 + buffer,
106072 + buffer_len))
106073 + goto _fmt_rx_default_hook_stolen;
106074 +
106075 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
106076 + return DPAA_ETH_CONTINUE;
106077 +
106078 +_fmt_rx_default_hook_stolen:
106079 + dev_kfree_skb(skb);
106080 +
106081 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
106082 + return DPAA_ETH_STOLEN;
106083 +}
106084 +
106085 +enum dpaa_eth_hook_result fmt_rx_error_hook(
106086 + struct net_device *net_dev,
106087 + const struct qm_fd *fd,
106088 + u32 fqid)
106089 +{
106090 + struct dpa_priv_s *dpa_priv = NULL;
106091 + struct dpa_bp *dpa_bp = NULL;
106092 + struct fmt_port_s *fmt_port = NULL;
106093 + void *fd_virt_addr = NULL;
106094 + dma_addr_t addr = qm_fd_addr(fd);
106095 +
106096 + _fmt_dbgr("calling...\n");
106097 +
106098 + dpa_priv = netdev_priv(net_dev);
106099 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106100 +
106101 + /* dpaa doesn't do this... we have to do it here */
106102 + dpa_bp = dpa_bpid2pool(fd->bpid);
106103 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
106104 +
106105 + fd_virt_addr = phys_to_virt(addr);
106106 + /* if is not out frame let dpa to handle it */
106107 + if (test_and_steal_frame(fmt_port,
106108 + FMT_RX_ERR_Q,
106109 + fd_virt_addr,
106110 + fd->length20 + fd->offset)) {
106111 + goto _fmt_rx_error_hook_stolen;
106112 + }
106113 +
106114 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
106115 + return DPAA_ETH_CONTINUE;
106116 +
106117 +_fmt_rx_error_hook_stolen:
106118 + /* the frame data doesn't matter,
106119 + * so, no mapping is needed */
106120 + fmt_fq_release(fd);
106121 +
106122 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
106123 + return DPAA_ETH_STOLEN;
106124 +}
106125 +
106126 +enum dpaa_eth_hook_result fmt_tx_confirm_hook(
106127 + struct net_device *net_dev,
106128 + const struct qm_fd *fd,
106129 + u32 fqid)
106130 +{
106131 + struct dpa_priv_s *dpa_priv = NULL;
106132 + struct fmt_port_s *fmt_port = NULL;
106133 + dma_addr_t addr = qm_fd_addr(fd);
106134 + void *fd_virt_addr = NULL;
106135 + uint32_t fd_len = 0;
106136 +
106137 + _fmt_dbgr("calling...\n");
106138 +
106139 + dpa_priv = netdev_priv(net_dev);
106140 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106141 +
106142 + fd_virt_addr = phys_to_virt(addr);
106143 + fd_len = fd->length20 + fd->offset;
106144 +
106145 + if (fd_len > fm_get_max_frm()) {
106146 + _fmt_err("tx confirm bad frame size: %u!\n", fd_len);
106147 + goto _fmt_tx_confirm_hook_continue;
106148 + }
106149 +
106150 + if (test_and_steal_frame(fmt_port,
106151 + FMT_TX_CONF_Q,
106152 + fd_virt_addr,
106153 + fd_len))
106154 + goto _fmt_tx_confirm_hook_stolen;
106155 +
106156 +_fmt_tx_confirm_hook_continue:
106157 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
106158 + return DPAA_ETH_CONTINUE;
106159 +
106160 +_fmt_tx_confirm_hook_stolen:
106161 + kfree(fd_virt_addr);
106162 +
106163 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
106164 + return DPAA_ETH_STOLEN;
106165 +}
106166 +
106167 +enum dpaa_eth_hook_result fmt_tx_confirm_error_hook(
106168 + struct net_device *net_dev,
106169 + const struct qm_fd *fd,
106170 + u32 fqid)
106171 +{
106172 + struct dpa_priv_s *dpa_priv = NULL;
106173 + struct fmt_port_s *fmt_port = NULL;
106174 + dma_addr_t addr = qm_fd_addr(fd);
106175 + void *fd_virt_addr = NULL;
106176 + uint32_t fd_len = 0;
106177 +
106178 + _fmt_dbgr("calling...\n");
106179 +
106180 + dpa_priv = netdev_priv(net_dev);
106181 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106182 +
106183 + fd_virt_addr = phys_to_virt(addr);
106184 + fd_len = fd->length20 + fd->offset;
106185 +
106186 + if (fd_len > fm_get_max_frm()) {
106187 + _fmt_err("tx confirm err bad frame size: %u !\n", fd_len);
106188 + goto _priv_ingress_tx_err_continue;
106189 + }
106190 +
106191 + if (test_and_steal_frame(fmt_port, FMT_TX_ERR_Q, fd_virt_addr, fd_len))
106192 + goto _priv_ingress_tx_err_stolen;
106193 +
106194 +_priv_ingress_tx_err_continue:
106195 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
106196 + return DPAA_ETH_CONTINUE;
106197 +
106198 +_priv_ingress_tx_err_stolen:
106199 + kfree(fd_virt_addr);
106200 +
106201 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
106202 + return DPAA_ETH_STOLEN;
106203 +}
106204 +
106205 +/* egress callbacks definition */
106206 +enum qman_cb_dqrr_result fmt_egress_dqrr(
106207 + struct qman_portal *portal,
106208 + struct qman_fq *fq,
106209 + const struct qm_dqrr_entry *dqrr)
106210 +{
106211 + /* this callback should never be called */
106212 + BUG();
106213 + return qman_cb_dqrr_consume;
106214 +}
106215 +
106216 +static void fmt_egress_error_dqrr(
106217 + struct qman_portal *p,
106218 + struct qman_fq *fq,
106219 + const struct qm_mr_entry *msg)
106220 +{
106221 + uint8_t *fd_virt_addr = NULL;
106222 +
106223 + /* tx failure, on the ern callback - release buffer */
106224 + fd_virt_addr = (uint8_t *)phys_to_virt(qm_fd_addr(&msg->ern.fd));
106225 + kfree(fd_virt_addr);
106226 +
106227 + return;
106228 +}
106229 +
106230 +static const struct qman_fq fmt_egress_fq = {
106231 + .cb = { .dqrr = fmt_egress_dqrr,
106232 + .ern = fmt_egress_error_dqrr,
106233 + .fqs = NULL}
106234 +};
106235 +
106236 +int fmt_fq_alloc(
106237 + struct fmt_fqs_s *fmt_fqs,
106238 + const struct qman_fq *qman_fq,
106239 + uint32_t fqid, uint32_t flags,
106240 + uint16_t channel, uint8_t wq)
106241 +{
106242 + int _errno = 0;
106243 +
106244 + _fmt_dbg("calling...\n");
106245 +
106246 + fmt_fqs->fq_base = *qman_fq;
106247 +
106248 + if (fqid == 0) {
106249 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
106250 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
106251 + } else
106252 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
106253 +
106254 + fmt_fqs->init = !(flags & QMAN_FQ_FLAG_NO_MODIFY);
106255 +
106256 + _errno = qman_create_fq(fqid, flags, &fmt_fqs->fq_base);
106257 + if (_errno < 0) {
106258 + _fmt_err("frame queues create failed.\n");
106259 + return -EINVAL;
106260 + }
106261 +
106262 + if (fmt_fqs->init) {
106263 + struct qm_mcc_initfq initfq;
106264 +
106265 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
106266 + initfq.fqd.dest.channel = channel;
106267 + initfq.fqd.dest.wq = wq;
106268 +
106269 + _errno = qman_init_fq(&fmt_fqs->fq_base,
106270 + QMAN_INITFQ_FLAG_SCHED,
106271 + &initfq);
106272 + if (_errno < 0) {
106273 + _fmt_err("frame queues init erorr.\n");
106274 + qman_destroy_fq(&fmt_fqs->fq_base, 0);
106275 + return -EINVAL;
106276 + }
106277 + }
106278 +
106279 + _fmt_dbg("called.\n");
106280 + return 0;
106281 +}
106282 +
106283 +static int fmt_fq_free(struct fmt_fqs_s *fmt_fq)
106284 +{
106285 + int _err = 0;
106286 +
106287 + _fmt_dbg("calling...\n");
106288 +
106289 + if (fmt_fq->init) {
106290 + _err = qman_retire_fq(&fmt_fq->fq_base, NULL);
106291 + if (unlikely(_err < 0))
106292 + _fmt_err("qman_retire_fq(%u) = %d\n",
106293 + qman_fq_fqid(&fmt_fq->fq_base), _err);
106294 +
106295 + _err = qman_oos_fq(&fmt_fq->fq_base);
106296 + if (unlikely(_err < 0))
106297 + _fmt_err("qman_oos_fq(%u) = %d\n",
106298 + qman_fq_fqid(&fmt_fq->fq_base), _err);
106299 + }
106300 +
106301 + qman_destroy_fq(&fmt_fq->fq_base, 0);
106302 +
106303 + _fmt_dbg("called.\n");
106304 + return _err;
106305 +}
106306 +
106307 +/* private pcd dqrr calbacks */
106308 +static enum qman_cb_dqrr_result fmt_pcd_dqrr(
106309 + struct qman_portal *portal,
106310 + struct qman_fq *fq,
106311 + const struct qm_dqrr_entry *dq)
106312 +{
106313 + struct dpa_bp *dpa_bp = NULL;
106314 + dma_addr_t addr = qm_fd_addr(&dq->fd);
106315 + uint8_t *fd_virt_addr = NULL;
106316 + struct fmt_port_s *fmt_port;
106317 + struct fmt_port_pcd_s *fmt_port_pcd;
106318 + uint32_t relative_fqid = 0;
106319 + uint32_t fd_len = 0;
106320 +
106321 + _fmt_dbgr("calling...\n");
106322 +
106323 + /* upcast - from pcd_alloc_fq */
106324 + fmt_port = ((struct fmt_fqs_s *)fq)->fmt_port_priv;
106325 + if (!fmt_port) {
106326 + _fmt_err(" wrong fmt port -to- fq match.\n");
106327 + goto _fmt_pcd_dqrr_return;
106328 + }
106329 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
106330 +
106331 + relative_fqid = dq->fqid - fmt_port_pcd->fqid_base;
106332 + _fmt_dbgr("pcd dqrr got frame on relative fq:%u@base:%u\n",
106333 + relative_fqid, fmt_port_pcd->fqid_base);
106334 +
106335 + fd_len = dq->fd.length20 + dq->fd.offset;
106336 +
106337 + if (fd_len > fm_get_max_frm()) {
106338 + _fmt_err("pcd dqrr wrong frame size: %u (%u:%u)!\n",
106339 + fd_len, dq->fd.length20, dq->fd.offset);
106340 + goto _fmt_pcd_dqrr_return;
106341 + }
106342 +
106343 + dpa_bp = dpa_bpid2pool(dq->fd.bpid);
106344 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
106345 +
106346 + fd_virt_addr = phys_to_virt(addr);
106347 + if (!test_and_steal_frame(fmt_port, relative_fqid, fd_virt_addr,
106348 + fd_len)) {
106349 +
106350 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106351 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
106352 +#endif
106353 + _fmt_wrn("pcd dqrr unrecognized frame@fqid: %u,"
106354 + " frame len: %u (dropped).\n",
106355 + dq->fqid, dq->fd.length20);
106356 + dump_frame(fd_virt_addr, fd_len);
106357 + }
106358 +
106359 +_fmt_pcd_dqrr_return:
106360 + /* no need to map again here */
106361 + fmt_fq_release(&dq->fd);
106362 +
106363 + _fmt_dbgr("calle.\n");
106364 + return qman_cb_dqrr_consume;
106365 +}
106366 +
106367 +static void fmt_pcd_err_dqrr(
106368 + struct qman_portal *qm,
106369 + struct qman_fq *fq,
106370 + const struct qm_mr_entry *msg)
106371 +{
106372 + _fmt_err("this callback should never be called.\n");
106373 + BUG();
106374 + return;
106375 +}
106376 +
106377 +static void fmt_pcd_fqs_dqrr(
106378 + struct qman_portal *qm,
106379 + struct qman_fq *fq,
106380 + const struct qm_mr_entry *msg)
106381 +{
106382 + _fmt_dbg(" fq state(0x%x)@fqid(%u.\n", msg->fq.fqs, msg->fq.fqid);
106383 + return;
106384 +}
106385 +
106386 +/* private pcd queue template */
106387 +static const struct qman_fq pcd_fq = {
106388 + .cb = { .dqrr = fmt_pcd_dqrr,
106389 + .ern = fmt_pcd_err_dqrr,
106390 + .fqs = fmt_pcd_fqs_dqrr}
106391 +};
106392 +
106393 +/* defined as weak in dpaa driver. */
106394 +/* ! parameters come from IOCTL call - US */
106395 +int dpa_alloc_pcd_fqids(
106396 + struct device *dev,
106397 + uint32_t num, uint8_t alignment,
106398 + uint32_t *base_fqid)
106399 +{
106400 + int _err = 0, i;
106401 + struct net_device *net_dev = NULL;
106402 + struct dpa_priv_s *dpa_priv = NULL;
106403 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
106404 + struct fmt_fqs_s *fmt_fqs = NULL;
106405 + struct fmt_port_s *fmt_port = NULL;
106406 + int num_allocated = 0;
106407 +
106408 + _fmt_dbg("calling...\n");
106409 +
106410 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
106411 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
106412 +
106413 + if (!netif_msg_probe(dpa_priv)) {
106414 + _fmt_err("dpa not probe.\n");
106415 + _err = -ENODEV;
106416 + goto _pcd_alloc_fqs_err;
106417 + }
106418 +
106419 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106420 + if (!fmt_port) {
106421 + _fmt_err("fmt port not found.");
106422 + _err = -EINVAL;
106423 + goto _pcd_alloc_fqs_err;
106424 + }
106425 +
106426 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
106427 +
106428 + num_allocated = qman_alloc_fqid_range(base_fqid, num, alignment, 0);
106429 +
106430 + if ((num_allocated <= 0) ||
106431 + (num_allocated < num) ||
106432 + (alignment && (*base_fqid) % alignment)) {
106433 + *base_fqid = 0;
106434 + _fmt_err("Failed to alloc pcd fqs rang.\n");
106435 + _err = -EINVAL;
106436 + goto _pcd_alloc_fqs_err;
106437 + }
106438 +
106439 + _fmt_dbg("wanted %d fqs(align %d), got %d fqids@%u.\n",
106440 + num, alignment, num_allocated, *base_fqid);
106441 +
106442 + /* alloc pcd queues */
106443 + fmt_port_pcd->fmt_pcd_fqs = kmalloc(num_allocated *
106444 + sizeof(struct fmt_fqs_s),
106445 + GFP_KERNEL);
106446 + fmt_port_pcd->num_queues = num_allocated;
106447 + fmt_port_pcd->fqid_base = *base_fqid;
106448 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
106449 +
106450 + /* alloc the pcd queues */
106451 + for (i = 0; i < num_allocated; i++, fmt_fqs++) {
106452 + _err = fmt_fq_alloc(
106453 + fmt_fqs,
106454 + &pcd_fq,
106455 + (*base_fqid) + i, QMAN_FQ_FLAG_NO_ENQUEUE,
106456 + dpa_priv->channel, 7);
106457 +
106458 + if (_err < 0)
106459 + goto _pcd_alloc_fqs_err;
106460 +
106461 + /* upcast to identify from where the frames came from */
106462 + fmt_fqs->fmt_port_priv = fmt_port;
106463 + }
106464 +
106465 + _fmt_dbg("called.\n");
106466 + return _err;
106467 +_pcd_alloc_fqs_err:
106468 + if (num_allocated > 0)
106469 + qman_release_fqid_range(*base_fqid, num_allocated);
106470 + /*TODO: free fmt_pcd_fqs if are any */
106471 +
106472 + _fmt_dbg("called(_err:%d).\n", _err);
106473 + return _err;
106474 +}
106475 +
106476 +/* defined as weak in dpaa driver. */
106477 +int dpa_free_pcd_fqids(
106478 + struct device *dev,
106479 + uint32_t base_fqid)
106480 +{
106481 +
106482 + int _err = 0, i;
106483 + struct net_device *net_dev = NULL;
106484 + struct dpa_priv_s *dpa_priv = NULL;
106485 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
106486 + struct fmt_fqs_s *fmt_fqs = NULL;
106487 + struct fmt_port_s *fmt_port = NULL;
106488 + int num_allocated = 0;
106489 +
106490 + _fmt_dbg("calling...\n");
106491 +
106492 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
106493 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
106494 +
106495 + if (!netif_msg_probe(dpa_priv)) {
106496 + _fmt_err("dpa not probe.\n");
106497 + _err = -ENODEV;
106498 + goto _pcd_free_fqs_err;
106499 + }
106500 +
106501 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106502 + if (!fmt_port) {
106503 + _fmt_err("fmt port not found.");
106504 + _err = -EINVAL;
106505 + goto _pcd_free_fqs_err;
106506 + }
106507 +
106508 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
106509 + num_allocated = fmt_port_pcd->num_queues;
106510 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
106511 +
106512 + for (i = 0; i < num_allocated; i++, fmt_fqs++)
106513 + fmt_fq_free(fmt_fqs);
106514 +
106515 + qman_release_fqid_range(base_fqid,num_allocated);
106516 +
106517 + kfree(fmt_port_pcd->fmt_pcd_fqs);
106518 + memset(fmt_port_pcd, 0, sizeof(*fmt_port_pcd));
106519 +
106520 + /* debugging stuff */
106521 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106522 + _fmt_dbg(" portid: %u.\n", fmt_port->id);
106523 + _fmt_dbg(" frames enqueue to qman: %u.\n",
106524 + atomic_read(&fmt_port->enqueue_to_qman_frm));
106525 + _fmt_dbg(" frames enqueue to rxq: %u.\n",
106526 + atomic_read(&fmt_port->enqueue_to_rxq));
106527 + _fmt_dbg(" frames dequeue from rxq: %u.\n",
106528 + atomic_read(&fmt_port->dequeue_from_rxq));
106529 + _fmt_dbg(" frames not enqueue to rxq - wrong frm: %u.\n",
106530 + atomic_read(&fmt_port->not_enqueue_to_rxq_wrong_frm));
106531 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
106532 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
106533 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
106534 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
106535 +#endif
106536 + return 0;
106537 +
106538 +_pcd_free_fqs_err:
106539 + return _err;
106540 +}
106541 +
106542 +static int fmt_port_init(
106543 + struct fmt_port_s *fmt_port,
106544 + ioc_fmt_port_param_t *p_Params)
106545 +{
106546 + struct device_node *fm_node, *fm_port_node;
106547 + const uint32_t *uint32_prop;
106548 + int _errno = 0, lenp = 0, i;
106549 + static struct of_device_id fm_node_of_match[] = {
106550 + { .compatible = "fsl,fman", },
106551 + { /* end of list */ },
106552 + };
106553 +
106554 + _fmt_dbg("calling...\n");
106555 +
106556 + /* init send/receive tu US list */
106557 + INIT_LIST_HEAD(&fmt_port->rx_q);
106558 +
106559 + /* check parameters */
106560 + if (p_Params->num_tx_queues > FMAN_TEST_MAX_TX_FQS ||
106561 + p_Params->fm_port_id > IOC_FMT_MAX_NUM_OF_PORTS) {
106562 + _fmt_dbg("wrong test parameters.\n");
106563 + return -EINVAL;
106564 + }
106565 +
106566 + /* set port parameters */
106567 + fmt_port->num_of_tx_fqs = p_Params->num_tx_queues;
106568 + fmt_port->id = p_Params->fm_port_id;
106569 + fmt_port->port_type = p_Params->fm_port_type;
106570 + fmt_port->diag = e_IOC_DIAG_MODE_NONE;
106571 +
106572 + /* init debugging stuff */
106573 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106574 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
106575 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
106576 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
106577 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
106578 +#endif
106579 +
106580 + /* TODO: This should be done at probe time not at runtime
106581 + * very ugly function */
106582 + /* fill fmt port properties from dts */
106583 + for_each_matching_node(fm_node, fm_node_of_match) {
106584 +
106585 + uint32_prop = (uint32_t *)of_get_property(fm_node,
106586 + "cell-index", &lenp);
106587 + if (unlikely(uint32_prop == NULL)) {
106588 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
106589 + fm_node->full_name);
106590 + return -EINVAL;
106591 + }
106592 + if (WARN_ON(lenp != sizeof(uint32_t))) {
106593 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
106594 + fm_node->full_name);
106595 + return -EINVAL;
106596 + }
106597 +
106598 + if (*uint32_prop == p_Params->fm_id) {
106599 + struct resource res;
106600 +
106601 + /* Get the FM address */
106602 + _errno = of_address_to_resource(fm_node, 0, &res);
106603 + if (unlikely(_errno < 0)) {
106604 + _fmt_wrn("of_address_to_resource() = %u.\n", _errno);
106605 + return -EINVAL;
106606 + }
106607 +
106608 + fmt_port->fm_phys_base_addr = res.start;
106609 +
106610 + for_each_child_of_node(fm_node, fm_port_node) {
106611 + struct platform_device *of_dev;
106612 +
106613 + if (!of_device_is_available(fm_port_node))
106614 + continue;
106615 +
106616 + uint32_prop = (uint32_t *)of_get_property(
106617 + fm_port_node,
106618 + "cell-index",
106619 + &lenp);
106620 + if (uint32_prop == NULL)
106621 + continue;
106622 +
106623 + if (of_device_is_compatible(fm_port_node,
106624 + "fsl,fman-port-oh") &&
106625 + (fmt_port->port_type == e_IOC_FMT_PORT_T_OP)) {
106626 +
106627 + if (*uint32_prop == fmt_port->id) {
106628 + of_dev = of_find_device_by_node(fm_port_node);
106629 + if (unlikely(of_dev == NULL)) {
106630 + _fmt_wrn("fm id invalid\n");
106631 + return -EINVAL;
106632 + }
106633 +
106634 + fmt_port->p_tx_port =
106635 + fm_port_bind(&of_dev->dev);
106636 + fmt_port->p_tx_fm_port_dev =
106637 + (void *)fm_port_get_handle(
106638 + fmt_port->p_tx_port);
106639 + fmt_port->p_rx_port =
106640 + fmt_port->p_tx_port;
106641 + fmt_port->p_rx_fm_port_dev =
106642 + fmt_port->p_tx_fm_port_dev;
106643 + fmt_port->p_mac_dev = NULL;
106644 + break;
106645 + }
106646 + } else if ((*uint32_prop == fmt_port->id) &&
106647 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
106648 +
106649 + of_dev = of_find_device_by_node(fm_port_node);
106650 + if (unlikely(of_dev == NULL)) {
106651 + _fmt_wrn("dtb fm id invalid value");
106652 + return -EINVAL;
106653 + }
106654 +
106655 + if (of_device_is_compatible(fm_port_node,
106656 + "fsl,fman-port-1g-tx")) {
106657 + fmt_port->p_tx_port =
106658 + fm_port_bind(&of_dev->dev);
106659 + fmt_port->p_tx_fm_port_dev = (void *)
106660 + fm_port_get_handle(
106661 + fmt_port->p_tx_port);
106662 + } else if (of_device_is_compatible(fm_port_node,
106663 + "fsl,fman-port-1g-rx")) {
106664 + fmt_port->p_rx_port =
106665 + fm_port_bind(&of_dev->dev);
106666 + fmt_port->p_rx_fm_port_dev = (void *)
106667 + fm_port_get_handle(
106668 + fmt_port->p_rx_port);
106669 + } else if (of_device_is_compatible(fm_port_node,
106670 + "fsl,fman-1g-mac") ||
106671 + of_device_is_compatible(fm_port_node,
106672 + "fsl,fman-memac"))
106673 + fmt_port->p_mac_dev =
106674 + (typeof(fmt_port->p_mac_dev))
106675 + dev_get_drvdata(&of_dev->dev);
106676 + else
106677 + continue;
106678 +
106679 + if (fmt_port->p_tx_fm_port_dev &&
106680 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
106681 + break;
106682 + } else if (((*uint32_prop + FM_MAX_NUM_OF_1G_RX_PORTS) ==
106683 + fmt_port->id) &&
106684 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
106685 +
106686 + of_dev = of_find_device_by_node(fm_port_node);
106687 + if (unlikely(of_dev == NULL)) {
106688 + _fmt_wrn("dtb fm id invalid value\n");
106689 + return -EINVAL;
106690 + }
106691 +
106692 + if (of_device_is_compatible(fm_port_node,
106693 + "fsl,fman-port-10g-tx")) {
106694 + fmt_port->p_tx_port =
106695 + fm_port_bind(&of_dev->dev);
106696 + fmt_port->p_tx_fm_port_dev = (void *)
106697 + fm_port_get_handle(
106698 + fmt_port->p_tx_port);
106699 + } else if (of_device_is_compatible(fm_port_node,
106700 + "fsl,fman-port-10g-rx")) {
106701 + fmt_port->p_rx_port =
106702 + fm_port_bind(&of_dev->dev);
106703 + fmt_port->p_rx_fm_port_dev = (void *)
106704 + fm_port_get_handle(
106705 + fmt_port->p_rx_port);
106706 + } else if (of_device_is_compatible(fm_port_node,
106707 + "fsl,fman-10g-mac") ||
106708 + of_device_is_compatible(fm_port_node,
106709 + "fsl,fman-memac"))
106710 + fmt_port->p_mac_dev =
106711 + (typeof(fmt_port->p_mac_dev))
106712 + dev_get_drvdata(&of_dev->dev);
106713 + else
106714 + continue;
106715 +
106716 + if (fmt_port->p_tx_fm_port_dev &&
106717 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
106718 + break;
106719 + }
106720 + } /* for_each_child */
106721 + }
106722 + } /* for each matching node */
106723 +
106724 + if (fmt_port->p_tx_fm_port_dev == 0 ||
106725 + fmt_port->p_rx_fm_port_dev == 0) {
106726 +
106727 + _fmt_err("bad fm port pointers.\n");
106728 + return -EINVAL;
106729 + }
106730 +
106731 + _fmt_dbg("alloc %u tx queues.\n", fmt_port->num_of_tx_fqs);
106732 +
106733 + /* init fman test egress dynamic frame queues */
106734 + for (i = 0; i < fmt_port->num_of_tx_fqs; i++) {
106735 + int _errno;
106736 + _errno = fmt_fq_alloc(
106737 + &fmt_port->p_tx_fqs[i],
106738 + &fmt_egress_fq,
106739 + 0,
106740 + QMAN_FQ_FLAG_TO_DCPORTAL,
106741 + fm_get_tx_port_channel(fmt_port->p_tx_port),
106742 + i);
106743 +
106744 + if (_errno < 0) {
106745 + _fmt_err("tx queues allocation failed.\n");
106746 + /* TODO: memory leak here if 1 queue is allocated and
106747 + * next queues are failing ... */
106748 + return -EINVAL;
106749 + }
106750 + }
106751 +
106752 + /* port is valid and ready to use. */
106753 + fmt_port->valid = TRUE;
106754 +
106755 + _fmt_dbg("called.\n");
106756 + return 0;
106757 +}
106758 +
106759 +/* fm test chardev functions */
106760 +static int fmt_open(struct inode *inode, struct file *file)
106761 +{
106762 + unsigned int minor = iminor(inode);
106763 +
106764 + _fmt_dbg("calling...\n");
106765 +
106766 + if (file->private_data != NULL)
106767 + return 0;
106768 +
106769 + /* The minor represent the port number.
106770 + * Set the port structure accordingly, thus all the operations
106771 + * will be done on this port. */
106772 + if ((minor >= DEV_FM_TEST_PORTS_MINOR_BASE) &&
106773 + (minor < DEV_FM_TEST_MAX_MINORS))
106774 + file->private_data = &fm_test.ports[minor];
106775 + else
106776 + return -ENXIO;
106777 +
106778 + _fmt_dbg("called.\n");
106779 + return 0;
106780 +}
106781 +
106782 +static int fmt_close(struct inode *inode, struct file *file)
106783 +{
106784 + struct fmt_port_s *fmt_port = NULL;
106785 + struct fmt_frame_s *fmt_frame = NULL;
106786 +
106787 + int err = 0;
106788 +
106789 + _fmt_dbg("calling...\n");
106790 +
106791 + fmt_port = file->private_data;
106792 + if (!fmt_port)
106793 + return -ENODEV;
106794 +
106795 + /* Close the current test port by invalidating it. */
106796 + fmt_port->valid = FALSE;
106797 +
106798 + /* clean the fmt port queue */
106799 + while ((fmt_frame = dequeue_fmt_frame(fmt_port)) != NULL) {
106800 + if (fmt_frame && fmt_frame->buff.p_data){
106801 + kfree(fmt_frame->buff.p_data);
106802 + kfree(fmt_frame);
106803 + }
106804 + }
106805 +
106806 + /* !!! the qman queues are cleaning from fm_ioctl...
106807 + * - very ugly */
106808 +
106809 + _fmt_dbg("called.\n");
106810 + return err;
106811 +}
106812 +
106813 +static int fmt_ioctls(unsigned int minor,
106814 + struct file *file,
106815 + unsigned int cmd,
106816 + unsigned long arg,
106817 + bool compat)
106818 +{
106819 + struct fmt_port_s *fmt_port = NULL;
106820 +
106821 + _fmt_dbg("IOCTL minor:%u "
106822 + " arg:0x%08lx ioctl cmd (0x%08x):(0x%02x:0x%02x.\n",
106823 + minor, arg, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106824 +
106825 + fmt_port = file->private_data;
106826 + if (!fmt_port) {
106827 + _fmt_err("invalid fmt port.\n");
106828 + return -ENODEV;
106829 + }
106830 +
106831 + /* set test type properly */
106832 + if (compat)
106833 + fmt_port->compat_test_type = true;
106834 + else
106835 + fmt_port->compat_test_type = false;
106836 +
106837 + switch (cmd) {
106838 + case FMT_PORT_IOC_INIT:
106839 + {
106840 + ioc_fmt_port_param_t param;
106841 +
106842 + if (fmt_port->valid) {
106843 + _fmt_wrn("port is already initialized.\n");
106844 + return -EFAULT;
106845 + }
106846 +#if defined(CONFIG_COMPAT)
106847 + if (compat) {
106848 + if (copy_from_user(&param,
106849 + (ioc_fmt_port_param_t *)compat_ptr(arg),
106850 + sizeof(ioc_fmt_port_param_t)))
106851 +
106852 + return -EFAULT;
106853 + } else
106854 +#endif
106855 + {
106856 + if (copy_from_user(&param,
106857 + (ioc_fmt_port_param_t *) arg,
106858 + sizeof(ioc_fmt_port_param_t)))
106859 +
106860 + return -EFAULT;
106861 + }
106862 +
106863 + return fmt_port_init(fmt_port, &param);
106864 + }
106865 +
106866 + case FMT_PORT_IOC_SET_DIAG_MODE:
106867 + if (get_user(fmt_port->diag, (ioc_diag_mode *)arg))
106868 + return -EFAULT;
106869 +
106870 + if (fmt_port->diag == e_IOC_DIAG_MODE_CTRL_LOOPBACK)
106871 + return set_mac_int_loopback(fmt_port, TRUE);
106872 + else
106873 + return set_mac_int_loopback(fmt_port, FALSE);
106874 + break;
106875 +
106876 + case FMT_PORT_IOC_SET_DPAECHO_MODE:
106877 + case FMT_PORT_IOC_SET_IP_HEADER_MANIP:
106878 + default:
106879 + _fmt_wrn("ioctl unimplemented minor:%u@ioctl"
106880 + " cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
106881 + minor, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106882 + return -EFAULT;
106883 + }
106884 +
106885 + return 0;
106886 +}
106887 +
106888 +#ifdef CONFIG_COMPAT
106889 +static long fmt_compat_ioctl(
106890 + struct file *file,
106891 + unsigned int cmd,
106892 + unsigned long arg)
106893 +{
106894 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106895 +
106896 + _fmt_dbg("calling...\n");
106897 + return fmt_ioctls(minor, file, cmd, arg, true);
106898 +}
106899 +#endif
106900 +
106901 +static long fmt_ioctl(
106902 + struct file *file,
106903 + unsigned int cmd,
106904 + unsigned long arg)
106905 +{
106906 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106907 + unsigned int res;
106908 +
106909 + _fmt_dbg("calling...\n");
106910 +
106911 + fm_mutex_lock();
106912 + res = fmt_ioctls(minor, file, cmd, arg, false);
106913 + fm_mutex_unlock();
106914 +
106915 + _fmt_dbg("called.\n");
106916 +
106917 + return res;
106918 +}
106919 +
106920 +#ifdef CONFIG_COMPAT
106921 +void copy_compat_test_frame_buffer(
106922 + ioc_fmt_buff_desc_t *buff,
106923 + ioc_fmt_compat_buff_desc_t *compat_buff)
106924 +{
106925 + compat_buff->qid = buff->qid;
106926 + compat_buff->p_data = ptr_to_compat(buff->p_data);
106927 + compat_buff->size = buff->size;
106928 + compat_buff->status = buff->status;
106929 +
106930 + compat_buff->buff_context.p_user_priv =
106931 + ptr_to_compat(buff->buff_context.p_user_priv);
106932 + memcpy(compat_buff->buff_context.fm_prs_res,
106933 + buff->buff_context.fm_prs_res,
106934 + FM_PRS_MAX * sizeof(uint8_t));
106935 + memcpy(compat_buff->buff_context.fm_time_stamp,
106936 + buff->buff_context.fm_time_stamp,
106937 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106938 +}
106939 +#endif
106940 +
106941 +ssize_t fmt_read(
106942 + struct file *file,
106943 + char __user *buf,
106944 + size_t size,
106945 + loff_t *ppos)
106946 +{
106947 + struct fmt_port_s *fmt_port = NULL;
106948 + struct fmt_frame_s *p_fmt_frame = NULL;
106949 + ssize_t cnt = 0;
106950 +
106951 + fmt_port = file->private_data;
106952 + if (!fmt_port || !fmt_port->valid) {
106953 + _fmt_err("fmt port not valid!\n");
106954 + return -ENODEV;
106955 + }
106956 +
106957 + p_fmt_frame = dequeue_fmt_frame(fmt_port);
106958 + if (p_fmt_frame == NULL)
106959 + return 0;
106960 +
106961 + _fmt_dbgr("calling...\n");
106962 +
106963 +#ifdef CONFIG_COMPAT
106964 + if (fmt_port->compat_test_type){
106965 + cnt = sizeof(ioc_fmt_compat_buff_desc_t);
106966 + }
106967 + else
106968 +#endif
106969 + {
106970 + cnt = sizeof(ioc_fmt_buff_desc_t);
106971 + }
106972 +
106973 + if (size < cnt) {
106974 + _fmt_err("illegal buffer-size!\n");
106975 + cnt = 0;
106976 + goto _fmt_read_return;
106977 + }
106978 +
106979 + /* Copy structure */
106980 +#ifdef CONFIG_COMPAT
106981 + if (fmt_port->compat_test_type) {
106982 + {
106983 + ioc_fmt_compat_buff_desc_t compat_buff;
106984 + copy_compat_test_frame_buffer(&p_fmt_frame->buff,
106985 + &compat_buff);
106986 +
106987 + if (copy_to_user(buf, &compat_buff, cnt)) {
106988 + _fmt_err("copy_to_user failed!\n");
106989 + goto _fmt_read_return;
106990 + }
106991 + }
106992 +
106993 + ((ioc_fmt_compat_buff_desc_t *)buf)->p_data =
106994 + ptr_to_compat(buf+sizeof(ioc_fmt_compat_buff_desc_t));
106995 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106996 + } else
106997 +#endif
106998 + {
106999 + if (copy_to_user(buf, &p_fmt_frame->buff, cnt)) {
107000 + _fmt_err("copy_to_user failed!\n");
107001 + goto _fmt_read_return;
107002 + }
107003 +
107004 + ((ioc_fmt_buff_desc_t *)buf)->p_data =
107005 + buf + sizeof(ioc_fmt_buff_desc_t);
107006 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
107007 + }
107008 +
107009 + if (size < cnt) {
107010 + _fmt_err("illegal buffer-size!\n");
107011 + goto _fmt_read_return;
107012 + }
107013 +
107014 + /* copy frame */
107015 +#ifdef CONFIG_COMPAT
107016 + if (fmt_port->compat_test_type) {
107017 + if (copy_to_user(buf+sizeof(ioc_fmt_compat_buff_desc_t),
107018 + p_fmt_frame->buff.p_data, cnt)) {
107019 + _fmt_err("copy_to_user failed!\n");
107020 + goto _fmt_read_return;
107021 + }
107022 + } else
107023 +#endif
107024 + {
107025 + if (copy_to_user(buf+sizeof(ioc_fmt_buff_desc_t),
107026 + p_fmt_frame->buff.p_data, cnt)) {
107027 + _fmt_err("copy_to_user failed!\n");
107028 + goto _fmt_read_return;
107029 + }
107030 + }
107031 +
107032 +_fmt_read_return:
107033 + kfree(p_fmt_frame->buff.p_data);
107034 + kfree(p_fmt_frame);
107035 +
107036 + _fmt_dbgr("called.\n");
107037 + return cnt;
107038 +}
107039 +
107040 +ssize_t fmt_write(
107041 + struct file *file,
107042 + const char __user *buf,
107043 + size_t size,
107044 + loff_t *ppos)
107045 +{
107046 + struct fmt_port_s *fmt_port = NULL;
107047 + ioc_fmt_buff_desc_t buff_desc;
107048 +#ifdef CONFIG_COMPAT
107049 + ioc_fmt_compat_buff_desc_t buff_desc_compat;
107050 +#endif
107051 + uint8_t *p_data = NULL;
107052 + uint32_t data_offset;
107053 + int _errno;
107054 + t_DpaaFD fd;
107055 +
107056 + _fmt_dbgr("calling...\n");
107057 +
107058 + fmt_port = file->private_data;
107059 + if (!fmt_port || !fmt_port->valid) {
107060 + _fmt_err("fmt port not valid.\n");
107061 + return -EINVAL;
107062 + }
107063 +
107064 + /* If Compat (32B UserSpace - 64B KernelSpace) */
107065 +#ifdef CONFIG_COMPAT
107066 + if (fmt_port->compat_test_type) {
107067 + if (size < sizeof(ioc_fmt_compat_buff_desc_t)) {
107068 + _fmt_err("invalid buff_desc size.\n");
107069 + return -EFAULT;
107070 + }
107071 +
107072 + if (copy_from_user(&buff_desc_compat, buf,
107073 + sizeof(ioc_fmt_compat_buff_desc_t)))
107074 + return -EFAULT;
107075 +
107076 + buff_desc.qid = buff_desc_compat.qid;
107077 + buff_desc.p_data = compat_ptr(buff_desc_compat.p_data);
107078 + buff_desc.size = buff_desc_compat.size;
107079 + buff_desc.status = buff_desc_compat.status;
107080 +
107081 + buff_desc.buff_context.p_user_priv =
107082 + compat_ptr(buff_desc_compat.buff_context.p_user_priv);
107083 + memcpy(buff_desc.buff_context.fm_prs_res,
107084 + buff_desc_compat.buff_context.fm_prs_res,
107085 + FM_PRS_MAX * sizeof(uint8_t));
107086 + memcpy(buff_desc.buff_context.fm_time_stamp,
107087 + buff_desc_compat.buff_context.fm_time_stamp,
107088 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
107089 + } else
107090 +#endif
107091 + {
107092 + if (size < sizeof(ioc_fmt_buff_desc_t)) {
107093 + _fmt_err("invalid buff_desc size.\n");
107094 + return -EFAULT;
107095 + }
107096 +
107097 + if (copy_from_user(&buff_desc, (ioc_fmt_buff_desc_t *)buf,
107098 + sizeof(ioc_fmt_buff_desc_t)))
107099 + return -EFAULT;
107100 + }
107101 +
107102 + data_offset = FM_PORT_GetBufferDataOffset(fmt_port->p_tx_fm_port_dev);
107103 + p_data = kmalloc(buff_desc.size+data_offset, GFP_KERNEL);
107104 + if (!p_data)
107105 + return -ENOMEM;
107106 +
107107 + /* If Compat (32UserSpace - 64KernelSpace) the buff_desc.p_data is ok */
107108 + if (copy_from_user((uint8_t *)PTR_MOVE(p_data, data_offset),
107109 + buff_desc.p_data,
107110 + buff_desc.size)) {
107111 + kfree(p_data);
107112 + return -EFAULT;
107113 + }
107114 +
107115 + /* TODO: dma_map_single here (cannot access the bpool struct) */
107116 +
107117 + /* prepare fd */
107118 + memset(&fd, 0, sizeof(fd));
107119 + DPAA_FD_SET_ADDR(&fd, p_data);
107120 + DPAA_FD_SET_OFFSET(&fd, data_offset);
107121 + DPAA_FD_SET_LENGTH(&fd, buff_desc.size);
107122 +
107123 + _errno = qman_enqueue(&fmt_port->p_tx_fqs[buff_desc.qid].fq_base,
107124 + (struct qm_fd *)&fd, 0);
107125 + if (_errno) {
107126 + buff_desc.status = (uint32_t)_errno;
107127 + if (copy_to_user((ioc_fmt_buff_desc_t *)buf, &buff_desc,
107128 + sizeof(ioc_fmt_buff_desc_t))) {
107129 + kfree(p_data);
107130 + return -EFAULT;
107131 + }
107132 + }
107133 +
107134 + /* for debugging */
107135 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107136 + atomic_inc(&fmt_port->enqueue_to_qman_frm);
107137 +#endif
107138 + _fmt_dbgr("called.\n");
107139 + return buff_desc.size;
107140 +}
107141 +
107142 +/* fm test character device definition */
107143 +static const struct file_operations fmt_fops =
107144 +{
107145 + .owner = THIS_MODULE,
107146 +#ifdef CONFIG_COMPAT
107147 + .compat_ioctl = fmt_compat_ioctl,
107148 +#endif
107149 + .unlocked_ioctl = fmt_ioctl,
107150 + .open = fmt_open,
107151 + .release = fmt_close,
107152 + .read = fmt_read,
107153 + .write = fmt_write,
107154 +};
107155 +
107156 +static int fmt_init(void)
107157 +{
107158 + int id;
107159 +
107160 + _fmt_dbg("calling...\n");
107161 +
107162 + /* Register to the /dev for IOCTL API */
107163 + /* Register dynamically a new major number for the character device: */
107164 + fm_test.major = register_chrdev(0, DEV_FM_TEST_NAME, &fmt_fops);
107165 + if (fm_test.major <= 0) {
107166 + _fmt_wrn("Failed to allocate major number for device %s.\n",
107167 + DEV_FM_TEST_NAME);
107168 + return -ENODEV;
107169 + }
107170 +
107171 + /* Creating class for FMan_test */
107172 + fm_test.fmt_class = class_create(THIS_MODULE, DEV_FM_TEST_NAME);
107173 + if (IS_ERR(fm_test.fmt_class)) {
107174 + unregister_chrdev(fm_test.major, DEV_FM_TEST_NAME);
107175 + _fmt_wrn("Error creating %s class.\n", DEV_FM_TEST_NAME);
107176 + return -ENODEV;
107177 + }
107178 +
107179 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
107180 + if (NULL == device_create(fm_test.fmt_class, NULL,
107181 + MKDEV(fm_test.major,
107182 + DEV_FM_TEST_PORTS_MINOR_BASE + id), NULL,
107183 + DEV_FM_TEST_NAME "%d", id)) {
107184 +
107185 + _fmt_err("Error creating %s device.\n",
107186 + DEV_FM_TEST_NAME);
107187 + return -ENODEV;
107188 + }
107189 +
107190 + return 0;
107191 +}
107192 +
107193 +static void fmt_free(void)
107194 +{
107195 + int id;
107196 +
107197 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
107198 + device_destroy(fm_test.fmt_class, MKDEV(fm_test.major,
107199 + DEV_FM_TEST_PORTS_MINOR_BASE + id));
107200 + class_destroy(fm_test.fmt_class);
107201 +}
107202 +
107203 +static int __init __cold fmt_load(void)
107204 +{
107205 + struct dpaa_eth_hooks_s priv_dpaa_eth_hooks;
107206 +
107207 + /* set dpaa hooks for default queues */
107208 + memset(&priv_dpaa_eth_hooks, 0, sizeof(priv_dpaa_eth_hooks));
107209 + priv_dpaa_eth_hooks.rx_default = fmt_rx_default_hook;
107210 + priv_dpaa_eth_hooks.rx_error = fmt_rx_error_hook;
107211 + priv_dpaa_eth_hooks.tx_confirm = fmt_tx_confirm_hook;
107212 + priv_dpaa_eth_hooks.tx_error = fmt_tx_confirm_error_hook;
107213 +
107214 + fsl_dpaa_eth_set_hooks(&priv_dpaa_eth_hooks);
107215 +
107216 + /* initialize the fman test environment */
107217 + if (fmt_init() < 0) {
107218 + _fmt_err("Failed to init FM-test modul.\n");
107219 + fmt_free();
107220 + return -ENODEV;
107221 + }
107222 +
107223 + _fmt_inf("FSL FM test module loaded.\n");
107224 +
107225 + return 0;
107226 +}
107227 +
107228 +static void __exit __cold fmt_unload(void)
107229 +{
107230 + fmt_free();
107231 + _fmt_inf("FSL FM test module unloaded.\n");
107232 +}
107233 +
107234 +module_init(fmt_load);
107235 +module_exit(fmt_unload);
107236 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
107237 new file mode 100755
107238 index 00000000..31f654b4
107239 --- /dev/null
107240 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
107241 @@ -0,0 +1,2908 @@
107242 +/*
107243 + * Copyright 2008-2012 Freescale Semiconductor Inc.
107244 + *
107245 + * Redistribution and use in source and binary forms, with or without
107246 + * modification, are permitted provided that the following conditions are met:
107247 + * * Redistributions of source code must retain the above copyright
107248 + * notice, this list of conditions and the following disclaimer.
107249 + * * Redistributions in binary form must reproduce the above copyright
107250 + * notice, this list of conditions and the following disclaimer in the
107251 + * documentation and/or other materials provided with the distribution.
107252 + * * Neither the name of Freescale Semiconductor nor the
107253 + * names of its contributors may be used to endorse or promote products
107254 + * derived from this software without specific prior written permission.
107255 + *
107256 + *
107257 + * ALTERNATIVELY, this software may be distributed under the terms of the
107258 + * GNU General Public License ("GPL") as published by the Free Software
107259 + * Foundation, either version 2 of that License or (at your option) any
107260 + * later version.
107261 + *
107262 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
107263 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
107264 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
107265 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
107266 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
107267 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
107268 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
107269 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
107270 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
107271 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
107272 + */
107273 +
107274 +/*
107275 + @File lnxwrp_fm.c
107276 + @Author Shlomi Gridish
107277 + @Description FM Linux wrapper functions.
107278 +*/
107279 +
107280 +#include <linux/version.h>
107281 +#include <linux/slab.h>
107282 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
107283 +#define MODVERSIONS
107284 +#endif
107285 +#ifdef MODVERSIONS
107286 +#include <config/modversions.h>
107287 +#endif /* MODVERSIONS */
107288 +#include <linux/kernel.h>
107289 +#include <linux/module.h>
107290 +#include <linux/fs.h>
107291 +#include <linux/cdev.h>
107292 +#include <linux/device.h>
107293 +#include <linux/irq.h>
107294 +#include <linux/interrupt.h>
107295 +#include <linux/io.h>
107296 +#include <linux/ioport.h>
107297 +#include <linux/of_platform.h>
107298 +#include <linux/of_address.h>
107299 +#include <linux/of_irq.h>
107300 +#include <linux/clk.h>
107301 +#include <asm/uaccess.h>
107302 +#include <asm/errno.h>
107303 +#ifndef CONFIG_FMAN_ARM
107304 +#include <sysdev/fsl_soc.h>
107305 +#include <linux/fsl/guts.h>
107306 +#include <linux/fsl/svr.h>
107307 +#endif
107308 +#include <linux/stat.h> /* For file access mask */
107309 +#include <linux/skbuff.h>
107310 +#include <linux/proc_fs.h>
107311 +
107312 +/* NetCommSw Headers --------------- */
107313 +#include "std_ext.h"
107314 +#include "error_ext.h"
107315 +#include "sprint_ext.h"
107316 +#include "debug_ext.h"
107317 +#include "sys_io_ext.h"
107318 +
107319 +#include "fm_ioctls.h"
107320 +
107321 +#include "lnxwrp_fm.h"
107322 +#include "lnxwrp_resources.h"
107323 +#include "lnxwrp_sysfs_fm.h"
107324 +#include "lnxwrp_sysfs_fm_port.h"
107325 +#include "lnxwrp_exp_sym.h"
107326 +#include "fm_common.h"
107327 +#include "../../sdk_fman/Peripherals/FM/fm.h"
107328 +#define __ERR_MODULE__ MODULE_FM
107329 +
107330 +extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
107331 + e_FmPortType portType,
107332 + uint8_t portId);
107333 +
107334 +#define PROC_PRINT(args...) offset += sprintf(buf+offset,args)
107335 +
107336 +#define ADD_ADV_CONFIG_NO_RET(_func, _param) \
107337 + do { \
107338 + if (i<max){ \
107339 + p_Entry = &p_Entrys[i]; \
107340 + p_Entry->p_Function = _func; \
107341 + _param \
107342 + i++; \
107343 + } \
107344 + else \
107345 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
107346 + ("Number of advanced-configuration entries exceeded"));\
107347 + } while (0)
107348 +
107349 +/* Bootarg used to override the Kconfig FSL_FM_MAX_FRAME_SIZE value */
107350 +#define FSL_FM_MAX_FRM_BOOTARG "fsl_fm_max_frm"
107351 +
107352 +/* Bootarg used to override FSL_FM_RX_EXTRA_HEADROOM Kconfig value */
107353 +#define FSL_FM_RX_EXTRA_HEADROOM_BOOTARG "fsl_fm_rx_extra_headroom"
107354 +
107355 +/* Minimum and maximum value for the fsl_fm_rx_extra_headroom bootarg */
107356 +#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16
107357 +#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384
107358 +
107359 +#define FSL_FM_PAUSE_TIME_ENABLE 0xf000
107360 +#define FSL_FM_PAUSE_TIME_DISABLE 0
107361 +#define FSL_FM_PAUSE_THRESH_DEFAULT 0
107362 +
107363 +/*
107364 + * Max frame size, across all interfaces.
107365 + * Configurable from Kconfig or bootargs, to avoid allocating
107366 + * oversized (socket) buffers when not using jumbo frames.
107367 + * Must be large enough to accommodate the network MTU, but small enough
107368 + * to avoid wasting skb memory.
107369 + *
107370 + * Could be overridden once, at boot-time, via the
107371 + * fm_set_max_frm() callback.
107372 + */
107373 +int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
107374 +
107375 +/*
107376 + * Extra headroom for Rx buffers.
107377 + * FMan is instructed to allocate, on the Rx path, this amount of
107378 + * space at the beginning of a data buffer, beside the DPA private
107379 + * data area and the IC fields.
107380 + * Does not impact Tx buffer layout.
107381 + *
107382 + * Configurable from Kconfig or bootargs. Zero by default, it's needed
107383 + * on particular forwarding scenarios that add extra headers to the
107384 + * forwarded frame.
107385 + */
107386 +int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
107387 +
107388 +#ifdef CONFIG_FMAN_PFC
107389 +static int fsl_fm_pfc_quanta[] = {
107390 + CONFIG_FMAN_PFC_QUANTA_0,
107391 + CONFIG_FMAN_PFC_QUANTA_1,
107392 + CONFIG_FMAN_PFC_QUANTA_2,
107393 + CONFIG_FMAN_PFC_QUANTA_3
107394 +};
107395 +#endif
107396 +
107397 +static t_LnxWrpFm lnxWrpFm;
107398 +
107399 +int fm_get_max_frm()
107400 +{
107401 + return fsl_fm_max_frm;
107402 +}
107403 +EXPORT_SYMBOL(fm_get_max_frm);
107404 +
107405 +int fm_get_rx_extra_headroom()
107406 +{
107407 + return ALIGN(fsl_fm_rx_extra_headroom, 16);
107408 +}
107409 +EXPORT_SYMBOL(fm_get_rx_extra_headroom);
107410 +
107411 +static int __init fm_set_max_frm(char *str)
107412 +{
107413 + int ret = 0;
107414 +
107415 + ret = get_option(&str, &fsl_fm_max_frm);
107416 + if (ret != 1) {
107417 + /*
107418 + * This will only work if CONFIG_EARLY_PRINTK is compiled in,
107419 + * and something like "earlyprintk=serial,uart0,115200" is
107420 + * specified in the bootargs
107421 + */
107422 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
107423 + "will use the default FSL_FM_MAX_FRAME_SIZE (%d) "
107424 + "from Kconfig.\n", FSL_FM_MAX_FRM_BOOTARG,
107425 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
107426 +
107427 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
107428 + return 1;
107429 + }
107430 +
107431 + /* Don't allow invalid bootargs; fallback to the Kconfig value */
107432 + if (fsl_fm_max_frm < 64 || fsl_fm_max_frm > 9600) {
107433 + printk(KERN_WARNING "Invalid %s=%d in bootargs, valid range is "
107434 + "64-9600. Falling back to the FSL_FM_MAX_FRAME_SIZE (%d) "
107435 + "from Kconfig.\n",
107436 + FSL_FM_MAX_FRM_BOOTARG, fsl_fm_max_frm,
107437 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
107438 +
107439 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
107440 + return 1;
107441 + }
107442 +
107443 + printk(KERN_INFO "Using fsl_fm_max_frm=%d from bootargs\n",
107444 + fsl_fm_max_frm);
107445 + return 0;
107446 +}
107447 +early_param(FSL_FM_MAX_FRM_BOOTARG, fm_set_max_frm);
107448 +
107449 +static int __init fm_set_rx_extra_headroom(char *str)
107450 +{
107451 + int ret;
107452 +
107453 + ret = get_option(&str, &fsl_fm_rx_extra_headroom);
107454 +
107455 + if (ret != 1) {
107456 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
107457 + "will use the default FSL_FM_RX_EXTRA_HEADROOM (%d) "
107458 + "from Kconfig.\n", FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
107459 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
107460 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
107461 +
107462 + return 1;
107463 + }
107464 +
107465 + if (fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN ||
107466 + fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) {
107467 + printk(KERN_WARNING "Invalid value for %s=%d prop in "
107468 + "bootargs; will use the default "
107469 + "FSL_FM_RX_EXTRA_HEADROOM (%d) from Kconfig.\n",
107470 + FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
107471 + fsl_fm_rx_extra_headroom,
107472 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
107473 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
107474 + }
107475 +
107476 + printk(KERN_INFO "Using fsl_fm_rx_extra_headroom=%d from bootargs\n",
107477 + fsl_fm_rx_extra_headroom);
107478 +
107479 + return 0;
107480 +}
107481 +early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom);
107482 +
107483 +static irqreturn_t fm_irq(int irq, void *_dev)
107484 +{
107485 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
107486 +#ifdef CONFIG_PM_SLEEP
107487 + t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev;
107488 +#endif
107489 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
107490 + return IRQ_NONE;
107491 +
107492 +#ifdef CONFIG_PM_SLEEP
107493 + if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP)
107494 + {
107495 + pm_wakeup_event(p_LnxWrpFmDev->dev, 200);
107496 + }
107497 +#endif
107498 + FM_EventIsr(p_LnxWrpFmDev->h_Dev);
107499 + return IRQ_HANDLED;
107500 +}
107501 +
107502 +static irqreturn_t fm_err_irq(int irq, void *_dev)
107503 +{
107504 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
107505 +
107506 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
107507 + return IRQ_NONE;
107508 +
107509 + if (FM_ErrorIsr(p_LnxWrpFmDev->h_Dev) == E_OK)
107510 + return IRQ_HANDLED;
107511 +
107512 + return IRQ_NONE;
107513 +}
107514 +
107515 +/* used to protect FMD/LLD from concurrent calls in functions fm_mutex_lock / fm_mutex_unlock */
107516 +static struct mutex lnxwrp_mutex;
107517 +
107518 +static t_LnxWrpFmDev * CreateFmDev(uint8_t id)
107519 +{
107520 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107521 + int j;
107522 +
107523 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)XX_Malloc(sizeof(t_LnxWrpFmDev));
107524 + if (!p_LnxWrpFmDev)
107525 + {
107526 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
107527 + return NULL;
107528 + }
107529 +
107530 + memset(p_LnxWrpFmDev, 0, sizeof(t_LnxWrpFmDev));
107531 + p_LnxWrpFmDev->fmDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107532 + memset(p_LnxWrpFmDev->fmDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107533 + p_LnxWrpFmDev->fmPcdDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107534 + memset(p_LnxWrpFmDev->fmPcdDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107535 + p_LnxWrpFmDev->hcPort.settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107536 + memset(p_LnxWrpFmDev->hcPort.settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107537 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
107538 + {
107539 + p_LnxWrpFmDev->rxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107540 + memset(p_LnxWrpFmDev->rxPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107541 + }
107542 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
107543 + {
107544 + p_LnxWrpFmDev->txPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107545 + memset(p_LnxWrpFmDev->txPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107546 + }
107547 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
107548 + {
107549 + p_LnxWrpFmDev->opPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107550 + memset(p_LnxWrpFmDev->opPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107551 + }
107552 +
107553 + return p_LnxWrpFmDev;
107554 +}
107555 +
107556 +static void DestroyFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107557 +{
107558 + int j;
107559 +
107560 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
107561 + if (p_LnxWrpFmDev->opPorts[j].settings.advConfig)
107562 + XX_Free(p_LnxWrpFmDev->opPorts[j].settings.advConfig);
107563 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
107564 + if (p_LnxWrpFmDev->txPorts[j].settings.advConfig)
107565 + XX_Free(p_LnxWrpFmDev->txPorts[j].settings.advConfig);
107566 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
107567 + if (p_LnxWrpFmDev->rxPorts[j].settings.advConfig)
107568 + XX_Free(p_LnxWrpFmDev->rxPorts[j].settings.advConfig);
107569 + if (p_LnxWrpFmDev->hcPort.settings.advConfig)
107570 + XX_Free(p_LnxWrpFmDev->hcPort.settings.advConfig);
107571 + if (p_LnxWrpFmDev->fmPcdDevSettings.advConfig)
107572 + XX_Free(p_LnxWrpFmDev->fmPcdDevSettings.advConfig);
107573 + if (p_LnxWrpFmDev->fmDevSettings.advConfig)
107574 + XX_Free(p_LnxWrpFmDev->fmDevSettings.advConfig);
107575 +
107576 + XX_Free(p_LnxWrpFmDev);
107577 +}
107578 +
107579 +static t_Error FillRestFmInfo(t_LnxWrpFmDev *p_LnxWrpFmDev)
107580 +{
107581 +#define FM_BMI_PPIDS_OFFSET 0x00080304
107582 +#define FM_DMA_PLR_OFFSET 0x000c2060
107583 +#define FM_FPM_IP_REV_1_OFFSET 0x000c30c4
107584 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
107585 +#define DMA_LOW_LIODN_MASK 0x00000FFF
107586 +#define DMA_LIODN_SHIFT 16
107587 +
107588 +typedef _Packed struct {
107589 + uint32_t plr[32];
107590 +} _PackedType t_Plr;
107591 +
107592 +typedef _Packed struct {
107593 + volatile uint32_t fmbm_ppid[63];
107594 +} _PackedType t_Ppids;
107595 +
107596 + t_Plr *p_Plr;
107597 + t_Ppids *p_Ppids;
107598 + int i,j;
107599 + uint32_t fmRev;
107600 +
107601 + static const uint8_t phys1GRxPortId[] = {0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
107602 + static const uint8_t phys10GRxPortId[] = {0x10,0x11};
107603 +#if (DPAA_VERSION >= 11)
107604 + static const uint8_t physOhPortId[] = {/* 0x1, */0x2,0x3,0x4,0x5,0x6,0x7};
107605 +#else
107606 + static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7};
107607 +#endif
107608 + static const uint8_t phys1GTxPortId[] = {0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
107609 + static const uint8_t phys10GTxPortId[] = {0x30,0x31};
107610 +
107611 + fmRev = (uint32_t)(*((volatile uint32_t *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_FPM_IP_REV_1_OFFSET)));
107612 + fmRev &= 0xffff;
107613 +
107614 + p_Plr = (t_Plr *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_DMA_PLR_OFFSET);
107615 +#ifdef MODULE
107616 + for (i=0;i<FM_MAX_NUM_OF_PARTITIONS/2;i++)
107617 + p_Plr->plr[i] = 0;
107618 +#endif /* MODULE */
107619 +
107620 + for (i=0; i<FM_MAX_NUM_OF_PARTITIONS; i++)
107621 + {
107622 + uint16_t liodnBase = (uint16_t)((i%2) ?
107623 + (p_Plr->plr[i/2] & DMA_LOW_LIODN_MASK) :
107624 + ((p_Plr->plr[i/2] & DMA_HIGH_LIODN_MASK) >> DMA_LIODN_SHIFT));
107625 +#ifdef FM_PARTITION_ARRAY
107626 + /* TODO: this was .liodnPerPartition[i] = liodnBase; is the index meaning the same? */
107627 + p_LnxWrpFmDev->fmDevSettings.param.liodnBasePerPort[i] = liodnBase;
107628 +#endif /* FM_PARTITION_ARRAY */
107629 +
107630 + if ((i >= phys1GRxPortId[0]) &&
107631 + (i <= phys1GRxPortId[FM_MAX_NUM_OF_1G_RX_PORTS-1]))
107632 + {
107633 + for (j=0; j<ARRAY_SIZE(phys1GRxPortId); j++)
107634 + if (phys1GRxPortId[j] == i)
107635 + break;
107636 + ASSERT_COND(j<ARRAY_SIZE(phys1GRxPortId));
107637 + p_LnxWrpFmDev->rxPorts[j].settings.param.liodnBase = liodnBase;
107638 + }
107639 + else if (FM_MAX_NUM_OF_10G_RX_PORTS &&
107640 + (i >= phys10GRxPortId[0]) &&
107641 + (i <= phys10GRxPortId[FM_MAX_NUM_OF_10G_RX_PORTS-1]))
107642 + {
107643 + for (j=0; j<ARRAY_SIZE(phys10GRxPortId); j++)
107644 + if (phys10GRxPortId[j] == i)
107645 + break;
107646 + ASSERT_COND(j<ARRAY_SIZE(phys10GRxPortId));
107647 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+j].settings.param.liodnBase = liodnBase;
107648 + }
107649 + else if ((i >= physOhPortId[0]) &&
107650 + (i <= physOhPortId[FM_MAX_NUM_OF_OH_PORTS-1]))
107651 + {
107652 + for (j=0; j<ARRAY_SIZE(physOhPortId); j++)
107653 + if (physOhPortId[j] == i)
107654 + break;
107655 + ASSERT_COND(j<ARRAY_SIZE(physOhPortId));
107656 + if (j == 0)
107657 + p_LnxWrpFmDev->hcPort.settings.param.liodnBase = liodnBase;
107658 + else
107659 + p_LnxWrpFmDev->opPorts[j - 1].settings.param.liodnBase = liodnBase;
107660 + }
107661 + else if ((i >= phys1GTxPortId[0]) &&
107662 + (i <= phys1GTxPortId[FM_MAX_NUM_OF_1G_TX_PORTS-1]))
107663 + {
107664 + for (j=0; j<ARRAY_SIZE(phys1GTxPortId); j++)
107665 + if (phys1GTxPortId[j] == i)
107666 + break;
107667 + ASSERT_COND(j<ARRAY_SIZE(phys1GTxPortId));
107668 + p_LnxWrpFmDev->txPorts[j].settings.param.liodnBase = liodnBase;
107669 + }
107670 + else if (FM_MAX_NUM_OF_10G_TX_PORTS &&
107671 + (i >= phys10GTxPortId[0]) &&
107672 + (i <= phys10GTxPortId[FM_MAX_NUM_OF_10G_TX_PORTS-1]))
107673 + {
107674 + for (j=0; j<ARRAY_SIZE(phys10GTxPortId); j++)
107675 + if (phys10GTxPortId[j] == i)
107676 + break;
107677 + ASSERT_COND(j<ARRAY_SIZE(phys10GTxPortId));
107678 + p_LnxWrpFmDev->txPorts[FM_MAX_NUM_OF_1G_TX_PORTS+j].settings.param.liodnBase = liodnBase;
107679 + }
107680 + }
107681 +
107682 + p_Ppids = (t_Ppids *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_BMI_PPIDS_OFFSET);
107683 +
107684 + for (i=0; i<FM_MAX_NUM_OF_1G_RX_PORTS; i++)
107685 + p_LnxWrpFmDev->rxPorts[i].settings.param.specificParams.rxParams.liodnOffset =
107686 + p_Ppids->fmbm_ppid[phys1GRxPortId[i]-1];
107687 +
107688 + for (i=0; i<FM_MAX_NUM_OF_10G_RX_PORTS; i++)
107689 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+i].settings.param.specificParams.rxParams.liodnOffset =
107690 + p_Ppids->fmbm_ppid[phys10GRxPortId[i]-1];
107691 +
107692 + return E_OK;
107693 +}
107694 +
107695 +/* Structure that defines QE firmware binary files.
107696 + *
107697 + * See Documentation/powerpc/qe_firmware.txt for a description of these
107698 + * fields.
107699 + */
107700 +struct qe_firmware {
107701 + struct qe_header {
107702 + __be32 length; /* Length of the entire structure, in bytes */
107703 + u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */
107704 + u8 version; /* Version of this layout. First ver is '1' */
107705 + } header;
107706 + u8 id[62]; /* Null-terminated identifier string */
107707 + u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */
107708 + u8 count; /* Number of microcode[] structures */
107709 + struct {
107710 + __be16 model; /* The SOC model */
107711 + u8 major; /* The SOC revision major */
107712 + u8 minor; /* The SOC revision minor */
107713 + } __attribute__ ((packed)) soc;
107714 + u8 padding[4]; /* Reserved, for alignment */
107715 + __be64 extended_modes; /* Extended modes */
107716 + __be32 vtraps[8]; /* Virtual trap addresses */
107717 + u8 reserved[4]; /* Reserved, for future expansion */
107718 + struct qe_microcode {
107719 + u8 id[32]; /* Null-terminated identifier */
107720 + __be32 traps[16]; /* Trap addresses, 0 == ignore */
107721 + __be32 eccr; /* The value for the ECCR register */
107722 + __be32 iram_offset; /* Offset into I-RAM for the code */
107723 + __be32 count; /* Number of 32-bit words of the code */
107724 + __be32 code_offset; /* Offset of the actual microcode */
107725 + u8 major; /* The microcode version major */
107726 + u8 minor; /* The microcode version minor */
107727 + u8 revision; /* The microcode version revision */
107728 + u8 padding; /* Reserved, for alignment */
107729 + u8 reserved[4]; /* Reserved, for future expansion */
107730 + } __attribute__ ((packed)) microcode[1];
107731 + /* All microcode binaries should be located here */
107732 + /* CRC32 should be located here, after the microcode binaries */
107733 +} __attribute__ ((packed));
107734 +
107735 +
107736 +/**
107737 + * FindFmanMicrocode - find the Fman microcode
107738 + *
107739 + * This function returns a pointer to the QE Firmware blob that holds
107740 + * the Fman microcode. We use the QE Firmware structure because Fman microcode
107741 + * is similar to QE microcode, so there's no point in defining a new layout.
107742 + *
107743 + * Current versions of U-Boot embed the Fman firmware into the device tree,
107744 + * so we check for that first. Each Fman node in the device tree contains a
107745 + * node or a pointer to node that holds the firmware. Technically, we should
107746 + * be fetching the firmware node for the current Fman, but we don't have that
107747 + * information any more, so we assume that there is only one firmware node in
107748 + * the device tree, and that all Fmen use the same firmware.
107749 + */
107750 +static const struct qe_firmware *FindFmanMicrocode(void)
107751 +{
107752 + static const struct qe_firmware *P4080_UCPatch;
107753 + struct device_node *np;
107754 +
107755 + if (P4080_UCPatch)
107756 + return P4080_UCPatch;
107757 +
107758 + /* The firmware should be inside the device tree. */
107759 + np = of_find_compatible_node(NULL, NULL, "fsl,fman-firmware");
107760 + if (np) {
107761 + P4080_UCPatch = of_get_property(np, "fsl,firmware", NULL);
107762 + of_node_put(np);
107763 + if (P4080_UCPatch)
107764 + return P4080_UCPatch;
107765 + else
107766 + REPORT_ERROR(WARNING, E_NOT_FOUND, ("firmware node is incomplete"));
107767 + }
107768 +
107769 + /* Returning NULL here forces the reuse of the IRAM content */
107770 + return NULL;
107771 +}
107772 +#define SVR_SECURITY_MASK 0x00080000
107773 +#define SVR_PERSONALITY_MASK 0x0000FF00
107774 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
107775 +#define SVR_B4860_REV1_VALUE 0x86800010
107776 +#define SVR_B4860_REV2_VALUE 0x86800020
107777 +#define SVR_T4240_VALUE 0x82400000
107778 +#define SVR_T4120_VALUE 0x82400100
107779 +#define SVR_T4160_VALUE 0x82410000
107780 +#define SVR_T4080_VALUE 0x82410200
107781 +#define SVR_T4_DEVICE_ID 0x82400000
107782 +#define SVR_DEVICE_ID_MASK 0xFFF00000
107783 +
107784 +#define OF_DEV_ID_NUM 2 /* one used, another one zeroed */
107785 +
107786 +/* searches for a subnode with the given name/compatible */
107787 +static bool HasFmPcdOfNode(struct device_node *fm_node,
107788 + struct of_device_id *ids,
107789 + const char *name,
107790 + const char *compatible)
107791 +{
107792 + struct device_node *dev_node;
107793 + bool ret = false;
107794 +
107795 + memset(ids, 0, OF_DEV_ID_NUM*sizeof(struct of_device_id));
107796 + if (WARN_ON(strlen(name) >= sizeof(ids[0].name)))
107797 + return false;
107798 + strcpy(ids[0].name, name);
107799 + if (WARN_ON(strlen(compatible) >= sizeof(ids[0].compatible)))
107800 + return false;
107801 + strcpy(ids[0].compatible, compatible);
107802 + for_each_child_of_node(fm_node, dev_node)
107803 + if (of_match_node(ids, dev_node) != NULL)
107804 + ret = true;
107805 + return ret;
107806 +}
107807 +
107808 +static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev)
107809 +{
107810 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107811 + struct device_node *fm_node, *dev_node;
107812 + struct of_device_id ids[OF_DEV_ID_NUM];
107813 + struct resource res;
107814 + struct clk *clk;
107815 + u32 clk_rate;
107816 + const uint32_t *uint32_prop;
107817 + int _errno=0, lenp;
107818 + uint32_t tmp_prop;
107819 +
107820 + fm_node = of_node_get(of_dev->dev.of_node);
107821 +
107822 + uint32_prop = (uint32_t *)of_get_property(fm_node, "cell-index", &lenp);
107823 + if (unlikely(uint32_prop == NULL)) {
107824 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, cell-index) failed", fm_node->full_name));
107825 + return NULL;
107826 + }
107827 + tmp_prop = be32_to_cpu(*uint32_prop);
107828 +
107829 + if (WARN_ON(lenp != sizeof(uint32_t)))
107830 + return NULL;
107831 +
107832 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107833 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107834 + return NULL;
107835 + }
107836 + p_LnxWrpFmDev = CreateFmDev(tmp_prop);
107837 + if (!p_LnxWrpFmDev) {
107838 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
107839 + return NULL;
107840 + }
107841 + p_LnxWrpFmDev->dev = &of_dev->dev;
107842 + p_LnxWrpFmDev->id = tmp_prop;
107843 +
107844 + /* Get the FM interrupt */
107845 + p_LnxWrpFmDev->irq = of_irq_to_resource(fm_node, 0, NULL);
107846 + if (unlikely(p_LnxWrpFmDev->irq == /*NO_IRQ*/0)) {
107847 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107848 + DestroyFmDev(p_LnxWrpFmDev);
107849 + return NULL;
107850 + }
107851 +
107852 + /* Get the FM error interrupt */
107853 + p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL);
107854 +
107855 + if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) {
107856 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107857 + DestroyFmDev(p_LnxWrpFmDev);
107858 + return NULL;
107859 + }
107860 +
107861 + /* Get the FM address */
107862 + _errno = of_address_to_resource(fm_node, 0, &res);
107863 + if (unlikely(_errno < 0)) {
107864 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107865 + DestroyFmDev(p_LnxWrpFmDev);
107866 + return NULL;
107867 + }
107868 +
107869 +
107870 + p_LnxWrpFmDev->fmBaseAddr = 0;
107871 + p_LnxWrpFmDev->fmPhysBaseAddr = res.start;
107872 + p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start;
107873 +
107874 + clk = of_clk_get(fm_node, 0);
107875 + if (IS_ERR(clk)) {
107876 + dev_err(&of_dev->dev, "%s: Failed to get FM clock structure\n",
107877 + __func__);
107878 + of_node_put(fm_node);
107879 + DestroyFmDev(p_LnxWrpFmDev);
107880 + return NULL;
107881 + }
107882 +
107883 + clk_rate = clk_get_rate(clk);
107884 + if (!clk_rate) {
107885 + dev_err(&of_dev->dev, "%s: Failed to determine FM clock rate\n",
107886 + __func__);
107887 + of_node_put(fm_node);
107888 + DestroyFmDev(p_LnxWrpFmDev);
107889 + return NULL;
107890 + }
107891 +
107892 + p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = DIV_ROUND_UP(clk_rate, 1000000); /* In MHz, rounded */
107893 + /* Get the MURAM base address and size */
107894 + memset(ids, 0, sizeof(ids));
107895 + if (WARN_ON(strlen("muram") >= sizeof(ids[0].name)))
107896 + return NULL;
107897 + strcpy(ids[0].name, "muram");
107898 + if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(ids[0].compatible)))
107899 + return NULL;
107900 + strcpy(ids[0].compatible, "fsl,fman-muram");
107901 + for_each_child_of_node(fm_node, dev_node) {
107902 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107903 + _errno = of_address_to_resource(dev_node, 0, &res);
107904 + if (unlikely(_errno < 0)) {
107905 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107906 + DestroyFmDev(p_LnxWrpFmDev);
107907 + return NULL;
107908 + }
107909 +
107910 + p_LnxWrpFmDev->fmMuramBaseAddr = 0;
107911 + p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start;
107912 + p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start;
107913 +
107914 +#ifndef CONFIG_FMAN_ARM
107915 + {
107916 + uint32_t svr;
107917 + svr = mfspr(SPRN_SVR);
107918 +
107919 + if ((svr & ~SVR_VER_IGNORE_MASK) >= SVR_B4860_REV2_VALUE)
107920 + p_LnxWrpFmDev->fmMuramMemSize = 0x80000;
107921 + }
107922 +#endif
107923 + }
107924 + }
107925 +
107926 + /* Get the RTC base address and size */
107927 + memset(ids, 0, sizeof(ids));
107928 + if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name)))
107929 + return NULL;
107930 + strcpy(ids[0].name, "ptp-timer");
107931 + if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(ids[0].compatible)))
107932 + return NULL;
107933 + strcpy(ids[0].compatible, "fsl,fman-rtc");
107934 + for_each_child_of_node(fm_node, dev_node) {
107935 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107936 + _errno = of_address_to_resource(dev_node, 0, &res);
107937 + if (unlikely(_errno < 0)) {
107938 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107939 + DestroyFmDev(p_LnxWrpFmDev);
107940 + return NULL;
107941 + }
107942 +
107943 + p_LnxWrpFmDev->fmRtcBaseAddr = 0;
107944 + p_LnxWrpFmDev->fmRtcPhysBaseAddr = res.start;
107945 + p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start;
107946 + }
107947 + }
107948 +
107949 +#if (DPAA_VERSION >= 11)
107950 + /* Get the VSP base address */
107951 + for_each_child_of_node(fm_node, dev_node) {
107952 + if (of_device_is_compatible(dev_node, "fsl,fman-vsps")) {
107953 + _errno = of_address_to_resource(dev_node, 0, &res);
107954 + if (unlikely(_errno < 0)) {
107955 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107956 + DestroyFmDev(p_LnxWrpFmDev);
107957 + return NULL;
107958 + }
107959 + p_LnxWrpFmDev->fmVspBaseAddr = 0;
107960 + p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start;
107961 + p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start;
107962 + }
107963 + }
107964 +#endif
107965 +
107966 + /* Get all PCD nodes */
107967 + p_LnxWrpFmDev->prsActive = HasFmPcdOfNode(fm_node, ids, "parser", "fsl,fman-parser");
107968 + p_LnxWrpFmDev->kgActive = HasFmPcdOfNode(fm_node, ids, "keygen", "fsl,fman-keygen");
107969 + p_LnxWrpFmDev->ccActive = HasFmPcdOfNode(fm_node, ids, "cc", "fsl,fman-cc");
107970 + p_LnxWrpFmDev->plcrActive = HasFmPcdOfNode(fm_node, ids, "policer", "fsl,fman-policer");
107971 +
107972 + if (p_LnxWrpFmDev->prsActive || p_LnxWrpFmDev->kgActive ||
107973 + p_LnxWrpFmDev->ccActive || p_LnxWrpFmDev->plcrActive)
107974 + p_LnxWrpFmDev->pcdActive = TRUE;
107975 +
107976 + if (p_LnxWrpFmDev->pcdActive)
107977 + {
107978 + const char *str_prop = (char *)of_get_property(fm_node, "fsl,default-pcd", &lenp);
107979 + if (str_prop) {
107980 + if (strncmp(str_prop, "3-tuple", strlen("3-tuple")) == 0)
107981 + p_LnxWrpFmDev->defPcd = e_FM_PCD_3_TUPLE;
107982 + }
107983 + else
107984 + p_LnxWrpFmDev->defPcd = e_NO_PCD;
107985 + }
107986 +
107987 + of_node_put(fm_node);
107988 +
107989 + p_LnxWrpFmDev->hcCh =
107990 + qman_affine_channel(cpumask_first(qman_affine_cpus()));
107991 +
107992 + p_LnxWrpFmDev->active = TRUE;
107993 +
107994 + return p_LnxWrpFmDev;
107995 +}
107996 +
107997 +struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx)
107998 +{
107999 + struct device_node *dev_node;
108000 + const uint32_t *uint32_prop;
108001 + int lenp;
108002 + uint32_t tmp_prop;
108003 +
108004 + for_each_compatible_node(dev_node, NULL, "fsl,fman-extended-args") {
108005 + uint32_prop = (uint32_t *)of_get_property(dev_node, "cell-index", &lenp);
108006 + if (unlikely(uint32_prop == NULL)) {
108007 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
108008 + ("of_get_property(%s, cell-index) failed",
108009 + dev_node->full_name));
108010 + return NULL;
108011 + }
108012 + tmp_prop = be32_to_cpu(*uint32_prop);
108013 + if (WARN_ON(lenp != sizeof(uint32_t)))
108014 + return NULL;
108015 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
108016 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
108017 + return NULL;
108018 + }
108019 + if (fmIndx == tmp_prop)
108020 + return dev_node;
108021 + }
108022 +
108023 + return NULL;
108024 +}
108025 +
108026 +static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
108027 +{
108028 + struct device_node *dev_node;
108029 + t_Error err = E_INVALID_VALUE;
108030 + const uint32_t *uint32_prop;
108031 + const char *str_prop;
108032 + int lenp;
108033 + uint32_t tmp_prop;
108034 +
108035 + dev_node = GetFmAdvArgsDevTreeNode(p_LnxWrpFmDev->id);
108036 + if (!dev_node) /* no advance parameters for FMan */
108037 + return E_OK;
108038 +
108039 + str_prop = (char *)of_get_property(dev_node, "dma-aid-mode", &lenp);
108040 + if (str_prop) {
108041 + if (strcmp(str_prop, "port") == 0)
108042 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_PORT_ID);
108043 + else if (strcmp(str_prop, "tnum") == 0)
108044 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM);
108045 +
108046 + if (err != E_OK)
108047 + RETURN_ERROR(MINOR, err, NO_MSG);
108048 + }
108049 +
108050 + uint32_prop = (uint32_t *)of_get_property(dev_node,
108051 + "total-fifo-size", &lenp);
108052 + if (uint32_prop) {
108053 + tmp_prop = be32_to_cpu(*uint32_prop);
108054 + if (WARN_ON(lenp != sizeof(uint32_t)))
108055 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
108056 +
108057 + if (FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev,
108058 + tmp_prop) != E_OK)
108059 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
108060 + }
108061 +
108062 + uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period",
108063 + &lenp);
108064 + if (uint32_prop) {
108065 + tmp_prop = be32_to_cpu(*uint32_prop);
108066 + if (WARN_ON(lenp != sizeof(uint32_t)))
108067 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
108068 +
108069 + err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev,
108070 + (uint16_t)tmp_prop/*tnumAgingPeriod*/);
108071 +
108072 + if (err != E_OK)
108073 + RETURN_ERROR(MINOR, err, NO_MSG);
108074 + }
108075 +
108076 + of_node_put(dev_node);
108077 +
108078 + return E_OK;
108079 +}
108080 +
108081 +static void LnxwrpFmDevExceptionsCb(t_Handle h_App, e_FmExceptions exception)
108082 +{
108083 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
108084 +
108085 + ASSERT_COND(p_LnxWrpFmDev);
108086 +
108087 + DBG(INFO, ("got fm exception %d", exception));
108088 +
108089 + /* do nothing */
108090 + UNUSED(exception);
108091 +}
108092 +
108093 +static void LnxwrpFmDevBusErrorCb(t_Handle h_App,
108094 + e_FmPortType portType,
108095 + uint8_t portId,
108096 + uint64_t addr,
108097 + uint8_t tnum,
108098 + uint16_t liodn)
108099 +{
108100 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
108101 +
108102 + ASSERT_COND(p_LnxWrpFmDev);
108103 +
108104 + /* do nothing */
108105 + UNUSED(portType);UNUSED(portId);UNUSED(addr);UNUSED(tnum);UNUSED(liodn);
108106 +}
108107 +
108108 +static t_Error ConfigureFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
108109 +{
108110 + struct resource *dev_res;
108111 + int _errno;
108112 +
108113 + if (!p_LnxWrpFmDev->active)
108114 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
108115 +
108116 +#ifndef MODULE
108117 + _errno = can_request_irq(p_LnxWrpFmDev->irq, 0);
108118 + if (unlikely(_errno < 0))
108119 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
108120 +#endif
108121 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, 0, "fman", p_LnxWrpFmDev);
108122 + if (unlikely(_errno < 0))
108123 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno));
108124 +
108125 + enable_irq_wake(p_LnxWrpFmDev->irq);
108126 +
108127 + if (p_LnxWrpFmDev->err_irq != 0) {
108128 +#ifndef MODULE
108129 + _errno = can_request_irq(p_LnxWrpFmDev->err_irq, 0);
108130 + if (unlikely(_errno < 0))
108131 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
108132 +#endif
108133 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, fm_err_irq, IRQF_SHARED, "fman-err", p_LnxWrpFmDev);
108134 + if (unlikely(_errno < 0))
108135 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->err_irq, _errno));
108136 +
108137 + enable_irq_wake(p_LnxWrpFmDev->err_irq);
108138 + }
108139 +
108140 + p_LnxWrpFmDev->res = devm_request_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize, "fman");
108141 + if (unlikely(p_LnxWrpFmDev->res == NULL))
108142 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_mem_region() failed"));
108143 +
108144 + p_LnxWrpFmDev->fmBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize));
108145 + if (unlikely(p_LnxWrpFmDev->fmBaseAddr == 0))
108146 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
108147 +
108148 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmBaseAddr, (uint64_t)p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize) != E_OK)
108149 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM memory map"));
108150 +
108151 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize, "fman-muram");
108152 + if (unlikely(dev_res == NULL))
108153 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
108154 +
108155 + p_LnxWrpFmDev->fmMuramBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize));
108156 + if (unlikely(p_LnxWrpFmDev->fmMuramBaseAddr == 0))
108157 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
108158 +
108159 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK)
108160 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map"));
108161 +
108162 + if (p_LnxWrpFmDev->fmRtcPhysBaseAddr)
108163 + {
108164 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-rtc");
108165 + if (unlikely(dev_res == NULL))
108166 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
108167 +
108168 + p_LnxWrpFmDev->fmRtcBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize));
108169 + if (unlikely(p_LnxWrpFmDev->fmRtcBaseAddr == 0))
108170 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
108171 +
108172 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK)
108173 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map"));
108174 + }
108175 +
108176 +#if (DPAA_VERSION >= 11)
108177 + if (p_LnxWrpFmDev->fmVspPhysBaseAddr) {
108178 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize, "fman-vsp");
108179 + if (unlikely(dev_res == NULL))
108180 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
108181 +
108182 + p_LnxWrpFmDev->fmVspBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize));
108183 + if (unlikely(p_LnxWrpFmDev->fmVspBaseAddr == 0))
108184 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
108185 + }
108186 +#endif
108187 +
108188 + p_LnxWrpFmDev->fmDevSettings.param.baseAddr = p_LnxWrpFmDev->fmBaseAddr;
108189 + p_LnxWrpFmDev->fmDevSettings.param.fmId = p_LnxWrpFmDev->id;
108190 + p_LnxWrpFmDev->fmDevSettings.param.irq = NO_IRQ;
108191 + p_LnxWrpFmDev->fmDevSettings.param.errIrq = NO_IRQ;
108192 + p_LnxWrpFmDev->fmDevSettings.param.f_Exception = LnxwrpFmDevExceptionsCb;
108193 + p_LnxWrpFmDev->fmDevSettings.param.f_BusError = LnxwrpFmDevBusErrorCb;
108194 + p_LnxWrpFmDev->fmDevSettings.param.h_App = p_LnxWrpFmDev;
108195 +
108196 + return FillRestFmInfo(p_LnxWrpFmDev);
108197 +}
108198 +
108199 +#ifndef CONFIG_FMAN_ARM
108200 +/*
108201 + * Table for matching compatible strings, for device tree
108202 + * guts node, for QorIQ SOCs.
108203 + * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
108204 + * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
108205 + * string would be used.
108206 +*/
108207 +static const struct of_device_id guts_device_ids[] = {
108208 + { .compatible = "fsl,qoriq-device-config-1.0", },
108209 + { .compatible = "fsl,qoriq-device-config-2.0", },
108210 + {}
108211 +};
108212 +
108213 +static unsigned int get_rcwsr(int regnum)
108214 +{
108215 + struct ccsr_guts __iomem *guts_regs = NULL;
108216 + struct device_node *guts_node;
108217 +
108218 + guts_node = of_find_matching_node(NULL, guts_device_ids);
108219 + if (!guts_node) {
108220 + pr_err("could not find GUTS node\n");
108221 + return 0;
108222 + }
108223 + guts_regs = of_iomap(guts_node, 0);
108224 + of_node_put(guts_node);
108225 + if (!guts_regs) {
108226 + pr_err("ioremap of GUTS node failed\n");
108227 + return 0;
108228 + }
108229 +
108230 + return ioread32be(&guts_regs->rcwsr[regnum]);
108231 +}
108232 +
108233 +#define FMAN1_ALL_MACS_MASK 0xFCC00000
108234 +#define FMAN2_ALL_MACS_MASK 0x000FCC00
108235 +
108236 +/**
108237 + * @Function ResetOnInitErrata_A007273
108238 + *
108239 + * @Description Workaround for Errata A-007273
108240 + * This workaround is required to avoid a FMan hang during reset on initialization.
108241 + * Enable all MACs in guts.devdisr2 register,
108242 + * then perform a regular FMan reset and then restore MACs to their original state.
108243 + *
108244 + * @Param[in] h_Fm - FM module descriptor
108245 + *
108246 + * @Return None.
108247 + */
108248 +void ResetOnInitErrata_A007273(t_Handle h_Fm)
108249 +{
108250 + struct ccsr_guts __iomem *guts_regs = NULL;
108251 + struct device_node *guts_node;
108252 + u32 devdisr2, enableMacs;
108253 +
108254 + /* Get guts registers */
108255 + guts_node = of_find_matching_node(NULL, guts_device_ids);
108256 + if (!guts_node) {
108257 + pr_err("could not find GUTS node\n");
108258 + return;
108259 + }
108260 + guts_regs = of_iomap(guts_node, 0);
108261 + of_node_put(guts_node);
108262 + if (!guts_regs) {
108263 + pr_err("ioremap of GUTS node failed\n");
108264 + return;
108265 + }
108266 +
108267 + /* Read current state */
108268 + devdisr2 = ioread32be(&guts_regs->devdisr2);
108269 +
108270 + if (FmGetId(h_Fm) == 0)
108271 + enableMacs = devdisr2 & ~FMAN1_ALL_MACS_MASK;
108272 + else
108273 + enableMacs = devdisr2 & ~FMAN2_ALL_MACS_MASK;
108274 +
108275 + /* Enable all MACs */
108276 + iowrite32be(enableMacs, &guts_regs->devdisr2);
108277 +
108278 + /* Perform standard FMan reset */
108279 + FmReset(h_Fm);
108280 +
108281 + /* Restore devdisr2 value */
108282 + iowrite32be(devdisr2, &guts_regs->devdisr2);
108283 +
108284 + iounmap(guts_regs);
108285 +}
108286 +#endif
108287 +
108288 +static t_Error InitFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
108289 +{
108290 + const struct qe_firmware *fw;
108291 +
108292 + if (!p_LnxWrpFmDev->active)
108293 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
108294 +
108295 + if ((p_LnxWrpFmDev->h_MuramDev = FM_MURAM_ConfigAndInit(p_LnxWrpFmDev->fmMuramBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)) == NULL)
108296 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM!"));
108297 +
108298 + /* Loading the fman-controller code */
108299 + fw = FindFmanMicrocode();
108300 +
108301 + if (!fw) {
108302 + /* this forces the reuse of the current IRAM content */
108303 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size = 0;
108304 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = NULL;
108305 + } else {
108306 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code =
108307 + (void *) fw + be32_to_cpu(fw->microcode[0].code_offset);
108308 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size =
108309 + sizeof(u32) * be32_to_cpu(fw->microcode[0].count);
108310 + DBG(INFO, ("Loading fman-controller code version %d.%d.%d",
108311 + fw->microcode[0].major,
108312 + fw->microcode[0].minor,
108313 + fw->microcode[0].revision));
108314 + }
108315 +
108316 +#ifdef CONFIG_FMAN_ARM
108317 + { /* endianness adjustments: byteswap the ucode retrieved from the f/w blob */
108318 + int i;
108319 + int usz = p_LnxWrpFmDev->fmDevSettings.param.firmware.size;
108320 + void * p_Code = p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code;
108321 + u32 *dest = kzalloc(usz, GFP_KERNEL);
108322 +
108323 + if (p_Code && dest)
108324 + for(i=0; i < usz / 4; ++i)
108325 + dest[i] = be32_to_cpu(((u32 *)p_Code)[i]);
108326 +
108327 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = dest;
108328 + }
108329 +#endif
108330 +
108331 + p_LnxWrpFmDev->fmDevSettings.param.h_FmMuram = p_LnxWrpFmDev->h_MuramDev;
108332 +
108333 +#if (DPAA_VERSION >= 11)
108334 + if (p_LnxWrpFmDev->fmVspBaseAddr) {
108335 + p_LnxWrpFmDev->fmDevSettings.param.vspBaseAddr = p_LnxWrpFmDev->fmVspBaseAddr;
108336 + p_LnxWrpFmDev->fmDevSettings.param.partVSPBase = 0;
108337 + p_LnxWrpFmDev->fmDevSettings.param.partNumOfVSPs = FM_VSP_MAX_NUM_OF_ENTRIES;
108338 + }
108339 +#endif
108340 +
108341 +#ifdef CONFIG_FMAN_ARM
108342 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
108343 +#else
108344 + if(p_LnxWrpFmDev->fmDevSettings.param.fmId == 0)
108345 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
108346 + !!(get_rcwsr(4) & 0x2); /* RCW[FM_MAC_RAT0] */
108347 + else
108348 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
108349 + !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */
108350 +
108351 + {
108352 + /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */
108353 + uint32_t svr;
108354 + svr = mfspr(SPRN_SVR);
108355 +
108356 + if ((svr & SVR_DEVICE_ID_MASK) == SVR_T4_DEVICE_ID)
108357 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
108358 + }
108359 +#endif /* CONFIG_FMAN_ARM */
108360 +
108361 + if ((p_LnxWrpFmDev->h_Dev = FM_Config(&p_LnxWrpFmDev->fmDevSettings.param)) == NULL)
108362 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM"));
108363 +
108364 +
108365 + if (FM_ConfigResetOnInit(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
108366 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108367 +
108368 +#ifndef CONFIG_FMAN_ARM
108369 +#ifdef FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
108370 + if (FM_ConfigResetOnInitOverrideCallback(p_LnxWrpFmDev->h_Dev, ResetOnInitErrata_A007273) != E_OK)
108371 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108372 +#endif /* FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 */
108373 +#endif /* CONFIG_FMAN_ARM */
108374 +
108375 +#ifdef CONFIG_FMAN_P1023
108376 + if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
108377 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108378 +#endif
108379 +
108380 +
108381 + CheckNConfigFmAdvArgs(p_LnxWrpFmDev);
108382 +
108383 + if (FM_Init(p_LnxWrpFmDev->h_Dev) != E_OK)
108384 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108385 +
108386 + /* TODO: Why we mask these interrupts? */
108387 + if (p_LnxWrpFmDev->err_irq == 0) {
108388 + FM_SetException(p_LnxWrpFmDev->h_Dev, e_FM_EX_DMA_BUS_ERROR,FALSE);
108389 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_READ_ECC,FALSE);
108390 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SYSTEM_WRITE_ECC,FALSE);
108391 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_FM_WRITE_ECC,FALSE);
108392 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SINGLE_PORT_ECC, FALSE);
108393 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_STALL_ON_TASKS , FALSE);
108394 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_SINGLE_ECC, FALSE);
108395 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_DOUBLE_ECC,FALSE);
108396 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_SINGLE_ECC, FALSE);
108397 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DOUBLE_ECC,FALSE);
108398 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,FALSE);
108399 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_LIST_RAM_ECC,FALSE);
108400 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STORAGE_PROFILE_ECC, FALSE);
108401 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STATISTICS_RAM_ECC, FALSE);
108402 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_DISPATCH_RAM_ECC, FALSE);
108403 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_IRAM_ECC,FALSE);
108404 + /* TODO: FmDisableRamsEcc assert for ramsEccOwners.
108405 + * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/
108406 + }
108407 +
108408 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
108409 + {
108410 + t_FmRtcParams fmRtcParam;
108411 +
108412 + memset(&fmRtcParam, 0, sizeof(fmRtcParam));
108413 + fmRtcParam.h_App = p_LnxWrpFmDev;
108414 + fmRtcParam.h_Fm = p_LnxWrpFmDev->h_Dev;
108415 + fmRtcParam.baseAddress = p_LnxWrpFmDev->fmRtcBaseAddr;
108416 +
108417 + if(!(p_LnxWrpFmDev->h_RtcDev = FM_RTC_Config(&fmRtcParam)))
108418 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-RTC"));
108419 +
108420 + if (FM_RTC_ConfigPeriod(p_LnxWrpFmDev->h_RtcDev, DPA_PTP_NOMINAL_FREQ_PERIOD_NS) != E_OK)
108421 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
108422 +
108423 + if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK)
108424 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
108425 + }
108426 +
108427 + return E_OK;
108428 +}
108429 +
108430 +/* TODO: to be moved back here */
108431 +extern void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev);
108432 +
108433 +static void FreeFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
108434 +{
108435 + if (!p_LnxWrpFmDev->active)
108436 + return;
108437 +
108438 + FreeFmPcdDev(p_LnxWrpFmDev);
108439 +
108440 + if (p_LnxWrpFmDev->h_RtcDev)
108441 + FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev);
108442 +
108443 + if (p_LnxWrpFmDev->h_Dev)
108444 + FM_Free(p_LnxWrpFmDev->h_Dev);
108445 +
108446 + if (p_LnxWrpFmDev->h_MuramDev)
108447 + FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev);
108448 +
108449 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
108450 + {
108451 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr);
108452 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr));
108453 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize);
108454 + }
108455 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr);
108456 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr));
108457 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize);
108458 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmBaseAddr);
108459 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr));
108460 + devm_release_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize);
108461 + if (p_LnxWrpFmDev->err_irq != 0) {
108462 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, p_LnxWrpFmDev);
108463 + }
108464 +
108465 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, p_LnxWrpFmDev);
108466 +}
108467 +
108468 +/* FMan character device file operations */
108469 +extern struct file_operations fm_fops;
108470 +
108471 +static int /*__devinit*/ fm_probe(struct platform_device *of_dev)
108472 +{
108473 + t_LnxWrpFmDev *p_LnxWrpFmDev;
108474 +
108475 + if ((p_LnxWrpFmDev = ReadFmDevTreeNode(of_dev)) == NULL)
108476 + return -EIO;
108477 + if (ConfigureFmDev(p_LnxWrpFmDev) != E_OK)
108478 + return -EIO;
108479 + if (InitFmDev(p_LnxWrpFmDev) != E_OK)
108480 + return -EIO;
108481 +
108482 + /* IOCTL ABI checking */
108483 + LnxWrpPCDIOCTLEnumChecking();
108484 + LnxWrpPCDIOCTLTypeChecking();
108485 +
108486 + Sprint (p_LnxWrpFmDev->name, "%s%d", DEV_FM_NAME, p_LnxWrpFmDev->id);
108487 +
108488 + /* Register to the /dev for IOCTL API */
108489 + /* Register dynamically a new major number for the character device: */
108490 + if ((p_LnxWrpFmDev->major = register_chrdev(0, p_LnxWrpFmDev->name, &fm_fops)) <= 0) {
108491 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Failed to allocate a major number for device \"%s\"", p_LnxWrpFmDev->name));
108492 + return -EIO;
108493 + }
108494 +
108495 + /* Creating classes for FM */
108496 + DBG(TRACE ,("class_create fm_class"));
108497 + p_LnxWrpFmDev->fm_class = class_create(THIS_MODULE, p_LnxWrpFmDev->name);
108498 + if (IS_ERR(p_LnxWrpFmDev->fm_class)) {
108499 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
108500 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("class_create error fm_class"));
108501 + return -EIO;
108502 + }
108503 +
108504 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE), NULL,
108505 + "fm%d", p_LnxWrpFmDev->id);
108506 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE), NULL,
108507 + "fm%d-pcd", p_LnxWrpFmDev->id);
108508 + dev_set_drvdata(p_LnxWrpFmDev->dev, p_LnxWrpFmDev);
108509 +
108510 + /* create sysfs entries for stats and regs */
108511 + if ( fm_sysfs_create(p_LnxWrpFmDev->dev) !=0 )
108512 + {
108513 + FreeFmDev(p_LnxWrpFmDev);
108514 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unable to create sysfs entry - fm!!!"));
108515 + return -EIO;
108516 + }
108517 +
108518 +#ifdef CONFIG_PM
108519 + device_set_wakeup_capable(p_LnxWrpFmDev->dev, true);
108520 +#endif
108521 +
108522 + DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id));
108523 +
108524 + return 0;
108525 +}
108526 +
108527 +static int fm_remove(struct platform_device *of_dev)
108528 +{
108529 + t_LnxWrpFmDev *p_LnxWrpFmDev;
108530 + struct device *dev;
108531 +
108532 + dev = &of_dev->dev;
108533 + p_LnxWrpFmDev = dev_get_drvdata(dev);
108534 +
108535 + fm_sysfs_destroy(dev);
108536 +
108537 + DBG(TRACE, ("destroy fm_class"));
108538 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE));
108539 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE));
108540 + class_destroy(p_LnxWrpFmDev->fm_class);
108541 +
108542 + /* Destroy chardev */
108543 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
108544 +
108545 + FreeFmDev(p_LnxWrpFmDev);
108546 +
108547 + DestroyFmDev(p_LnxWrpFmDev);
108548 +
108549 + dev_set_drvdata(dev, NULL);
108550 +
108551 + return 0;
108552 +}
108553 +
108554 +static const struct of_device_id fm_match[] = {
108555 + {
108556 + .compatible = "fsl,fman"
108557 + },
108558 + {}
108559 +};
108560 +#ifndef MODULE
108561 +MODULE_DEVICE_TABLE(of, fm_match);
108562 +#endif /* !MODULE */
108563 +
108564 +#ifdef CONFIG_PM
108565 +
108566 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
108567 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
108568 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
108569 +
108570 +struct device *g_fm_dev;
108571 +
108572 +static int fm_soc_suspend(struct device *dev)
108573 +{
108574 + int err = 0;
108575 + uint32_t *fmclk;
108576 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
108577 + g_fm_dev = dev;
108578 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
108579 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
108580 + if (p_LnxWrpFmDev->h_DsarRxPort)
108581 + {
108582 +#ifdef CONFIG_FSL_QORIQ_PM
108583 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1);
108584 +#endif
108585 + err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort,
108586 + p_LnxWrpFmDev->h_DsarTxPort);
108587 + }
108588 + return err;
108589 +}
108590 +
108591 +static int fm_soc_resume(struct device *dev)
108592 +{
108593 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
108594 + uint32_t *fmclk;
108595 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
108596 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
108597 + if (p_LnxWrpFmDev->h_DsarRxPort)
108598 + {
108599 +#ifdef CONFIG_FSL_QORIQ_PM
108600 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 0);
108601 +#endif
108602 + FM_PORT_ExitDsar(p_LnxWrpFmDev->h_DsarRxPort,
108603 + p_LnxWrpFmDev->h_DsarTxPort);
108604 + p_LnxWrpFmDev->h_DsarRxPort = 0;
108605 + p_LnxWrpFmDev->h_DsarTxPort = 0;
108606 + }
108607 + return 0;
108608 +}
108609 +
108610 +static const struct dev_pm_ops fm_pm_ops = {
108611 + .suspend = fm_soc_suspend,
108612 + .resume = fm_soc_resume,
108613 +};
108614 +
108615 +#define FM_PM_OPS (&fm_pm_ops)
108616 +
108617 +#else /* CONFIG_PM */
108618 +
108619 +#define FM_PM_OPS NULL
108620 +
108621 +#endif /* CONFIG_PM */
108622 +
108623 +static struct platform_driver fm_driver = {
108624 + .driver = {
108625 + .name = "fsl-fman",
108626 + .of_match_table = fm_match,
108627 + .owner = THIS_MODULE,
108628 + .pm = FM_PM_OPS,
108629 + },
108630 + .probe = fm_probe,
108631 + .remove = fm_remove
108632 +};
108633 +
108634 +t_Handle LNXWRP_FM_Init(void)
108635 +{
108636 + memset(&lnxWrpFm, 0, sizeof(lnxWrpFm));
108637 + mutex_init(&lnxwrp_mutex);
108638 +
108639 + /* Register to the DTB for basic FM API */
108640 + platform_driver_register(&fm_driver);
108641 +
108642 + return &lnxWrpFm;
108643 +}
108644 +
108645 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm)
108646 +{
108647 + platform_driver_unregister(&fm_driver);
108648 + mutex_destroy(&lnxwrp_mutex);
108649 +
108650 + return E_OK;
108651 +}
108652 +
108653 +
108654 +struct fm * fm_bind(struct device *fm_dev)
108655 +{
108656 + return (struct fm *)(dev_get_drvdata(get_device(fm_dev)));
108657 +}
108658 +EXPORT_SYMBOL(fm_bind);
108659 +
108660 +void fm_unbind(struct fm *fm)
108661 +{
108662 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108663 +
108664 + put_device(p_LnxWrpFmDev->dev);
108665 +}
108666 +EXPORT_SYMBOL(fm_unbind);
108667 +
108668 +struct resource * fm_get_mem_region(struct fm *fm)
108669 +{
108670 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108671 +
108672 + return p_LnxWrpFmDev->res;
108673 +}
108674 +EXPORT_SYMBOL(fm_get_mem_region);
108675 +
108676 +void * fm_get_handle(struct fm *fm)
108677 +{
108678 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108679 +
108680 + return (void *)p_LnxWrpFmDev->h_Dev;
108681 +}
108682 +EXPORT_SYMBOL(fm_get_handle);
108683 +
108684 +void * fm_get_rtc_handle(struct fm *fm)
108685 +{
108686 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108687 +
108688 + return (void *)p_LnxWrpFmDev->h_RtcDev;
108689 +}
108690 +EXPORT_SYMBOL(fm_get_rtc_handle);
108691 +
108692 +struct fm_port * fm_port_bind (struct device *fm_port_dev)
108693 +{
108694 + return (struct fm_port *)(dev_get_drvdata(get_device(fm_port_dev)));
108695 +}
108696 +EXPORT_SYMBOL(fm_port_bind);
108697 +
108698 +void fm_port_unbind(struct fm_port *port)
108699 +{
108700 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108701 +
108702 + put_device(p_LnxWrpFmPortDev->dev);
108703 +}
108704 +EXPORT_SYMBOL(fm_port_unbind);
108705 +
108706 +void *fm_port_get_handle(const struct fm_port *port)
108707 +{
108708 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108709 +
108710 + return (void *)p_LnxWrpFmPortDev->h_Dev;
108711 +}
108712 +EXPORT_SYMBOL(fm_port_get_handle);
108713 +
108714 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
108715 + const void *data)
108716 +{
108717 + return FM_PORT_GetBufferTimeStamp(fm_port_get_handle(port),
108718 + (void *)data);
108719 +}
108720 +EXPORT_SYMBOL(fm_port_get_buffer_time_stamp);
108721 +
108722 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr)
108723 +{
108724 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108725 +
108726 + *base_addr = p_LnxWrpFmPortDev->settings.param.baseAddr;
108727 +}
108728 +EXPORT_SYMBOL(fm_port_get_base_addr);
108729 +
108730 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params)
108731 +{
108732 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108733 +
108734 + p_LnxWrpFmPortDev->pcd_owner_params.cba = params->cba;
108735 + p_LnxWrpFmPortDev->pcd_owner_params.cbf = params->cbf;
108736 + p_LnxWrpFmPortDev->pcd_owner_params.dev = params->dev;
108737 +}
108738 +EXPORT_SYMBOL(fm_port_pcd_bind);
108739 +
108740 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params)
108741 +{
108742 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108743 + struct device_node *fm_node, *port_node;
108744 + const uint32_t *uint32_prop;
108745 + int lenp;
108746 +
108747 + params->data_align = 0;
108748 + params->manip_extra_space = 0;
108749 +
108750 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
108751 + if (!fm_node) /* no advance parameters for FMan */
108752 + return;
108753 +
108754 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
108755 + p_LnxWrpFmPortDev->settings.param.portType,
108756 + p_LnxWrpFmPortDev->settings.param.portId);
108757 + if (!port_node) /* no advance parameters for FMan-Port */
108758 + return;
108759 +
108760 + uint32_prop = (uint32_t *)of_get_property(port_node, "buffer-layout", &lenp);
108761 + if (uint32_prop) {
108762 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
108763 + return;
108764 +
108765 + params->manip_extra_space = (uint8_t)be32_to_cpu(uint32_prop[0]);
108766 + params->data_align = (uint16_t)be32_to_cpu(uint32_prop[1]);
108767 + }
108768 +
108769 + of_node_put(port_node);
108770 + of_node_put(fm_node);
108771 +}
108772 +EXPORT_SYMBOL(fm_port_get_buff_layout_ext_params);
108773 +
108774 +uint16_t fm_get_tx_port_channel(struct fm_port *port)
108775 +{
108776 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108777 +
108778 + return p_LnxWrpFmPortDev->txCh;
108779 +}
108780 +EXPORT_SYMBOL(fm_get_tx_port_channel);
108781 +
108782 +int fm_port_enable (struct fm_port *port)
108783 +{
108784 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108785 + t_Error err = FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108786 +
108787 + return GET_ERROR_TYPE(err);
108788 +}
108789 +EXPORT_SYMBOL(fm_port_enable);
108790 +
108791 +int fm_port_disable(struct fm_port *port)
108792 +{
108793 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108794 + t_Error err = FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108795 +
108796 + return GET_ERROR_TYPE(err);
108797 +}
108798 +EXPORT_SYMBOL(fm_port_disable);
108799 +
108800 +int fm_port_set_rate_limit(struct fm_port *port,
108801 + uint16_t max_burst_size,
108802 + uint32_t rate_limit)
108803 +{
108804 + t_FmPortRateLimit param;
108805 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108806 + int err = 0;
108807 +
108808 + param.maxBurstSize = max_burst_size;
108809 + param.rateLimit = rate_limit;
108810 + param.rateLimitDivider = 0;
108811 +
108812 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, &param);
108813 + return err;
108814 +}
108815 +EXPORT_SYMBOL(fm_port_set_rate_limit);
108816 +
108817 +int fm_port_del_rate_limit(struct fm_port *port)
108818 +{
108819 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108820 +
108821 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
108822 + return 0;
108823 +}
108824 +EXPORT_SYMBOL(fm_port_del_rate_limit);
108825 +
108826 +void FM_PORT_Dsar_DumpRegs(void);
108827 +int ar_showmem(struct file *file, const char __user *buffer,
108828 + unsigned long count, void *data)
108829 +{
108830 + FM_PORT_Dsar_DumpRegs();
108831 + return 2;
108832 +}
108833 +
108834 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
108835 + struct fm_port *port)
108836 +{
108837 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108838 + return &p_LnxWrpFmPortDev->dsar_table_sizes;
108839 +}
108840 +EXPORT_SYMBOL(fm_port_get_autores_maxsize);
108841 +
108842 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
108843 + struct auto_res_port_params *params)
108844 +{
108845 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108846 + t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
108847 + p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev;
108848 + p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx;
108849 +
108850 + /*Register other under /proc/autoresponse */
108851 + if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
108852 + return -EFAULT;
108853 +
108854 + FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
108855 + return 0;
108856 +}
108857 +EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
108858 +
108859 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
108860 + struct fm_port *port_tx)
108861 +{
108862 +}
108863 +EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
108864 +
108865 +int fm_port_get_autores_stats(struct fm_port *port,
108866 + struct auto_res_port_stats *stats)
108867 +{
108868 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108869 + if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats)))
108870 + return -EFAULT;
108871 + return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats);
108872 +}
108873 +EXPORT_SYMBOL(fm_port_get_autores_stats);
108874 +
108875 +int fm_port_suspend(struct fm_port *port)
108876 +{
108877 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108878 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108879 + return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108880 + else
108881 + return 0;
108882 +}
108883 +EXPORT_SYMBOL(fm_port_suspend);
108884 +
108885 +int fm_port_resume(struct fm_port *port)
108886 +{
108887 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108888 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108889 + return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108890 + else
108891 + return 0;
108892 +}
108893 +EXPORT_SYMBOL(fm_port_resume);
108894 +
108895 +bool fm_port_is_in_auto_res_mode(struct fm_port *port)
108896 +{
108897 + return FM_PORT_IsInDsar(port);
108898 +}
108899 +EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
108900 +
108901 +#ifdef CONFIG_FMAN_PFC
108902 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
108903 + uint8_t prio, uint8_t wq)
108904 +{
108905 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108906 + int err;
108907 + int _errno;
108908 +
108909 + err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev,
108910 + prio, wq);
108911 + _errno = -GET_ERROR_TYPE(err);
108912 + if (unlikely(_errno < 0))
108913 + pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err);
108914 +
108915 + return _errno;
108916 +}
108917 +EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq);
108918 +#endif
108919 +
108920 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
108921 + e_FmMacExceptions exception, bool enable)
108922 +{
108923 + int err;
108924 + int _errno;
108925 +
108926 + err = FM_MAC_SetException(fm_mac_dev, exception, enable);
108927 +
108928 + _errno = -GET_ERROR_TYPE(err);
108929 + if (unlikely(_errno < 0))
108930 + pr_err("FM_MAC_SetException() = 0x%08x\n", err);
108931 +
108932 + return _errno;
108933 +}
108934 +EXPORT_SYMBOL(fm_mac_set_exception);
108935 +
108936 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev)
108937 +{
108938 + int err;
108939 + int _error;
108940 +
108941 + err = FM_MAC_Free(fm_mac_dev);
108942 + _error = -GET_ERROR_TYPE(err);
108943 +
108944 + if (unlikely(_error < 0))
108945 + pr_err("FM_MAC_Free() = 0x%08x\n", err);
108946 +
108947 + return _error;
108948 +}
108949 +EXPORT_SYMBOL(fm_mac_free);
108950 +
108951 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params)
108952 +{
108953 + struct fm_mac_dev *fm_mac_dev;
108954 +
108955 + fm_mac_dev = FM_MAC_Config(params);
108956 + if (unlikely(fm_mac_dev == NULL))
108957 + pr_err("FM_MAC_Config() failed\n");
108958 +
108959 + return fm_mac_dev;
108960 +}
108961 +EXPORT_SYMBOL(fm_mac_config);
108962 +
108963 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
108964 + int len)
108965 +{
108966 + int err;
108967 + int _errno;
108968 +
108969 + err = FM_MAC_ConfigMaxFrameLength(fm_mac_dev, len);
108970 + _errno = -GET_ERROR_TYPE(err);
108971 + if (unlikely(_errno < 0))
108972 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
108973 +
108974 + return _errno;
108975 +}
108976 +EXPORT_SYMBOL(fm_mac_config_max_frame_length);
108977 +
108978 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable)
108979 +{
108980 + int err;
108981 + int _errno;
108982 +
108983 + err = FM_MAC_ConfigPadAndCrc(fm_mac_dev, enable);
108984 + _errno = -GET_ERROR_TYPE(err);
108985 + if (unlikely(_errno < 0))
108986 + pr_err("FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err);
108987 +
108988 + return _errno;
108989 +}
108990 +EXPORT_SYMBOL(fm_mac_config_pad_and_crc);
108991 +
108992 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable)
108993 +{
108994 + int err;
108995 + int _errno;
108996 +
108997 + err = FM_MAC_ConfigHalfDuplex(fm_mac_dev, enable);
108998 + _errno = -GET_ERROR_TYPE(err);
108999 + if (unlikely(_errno < 0))
109000 + pr_err("FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err);
109001 +
109002 + return _errno;
109003 +}
109004 +EXPORT_SYMBOL(fm_mac_config_half_duplex);
109005 +
109006 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable)
109007 +{
109008 + int err;
109009 + int _errno;
109010 +
109011 + err = FM_MAC_ConfigResetOnInit(fm_mac_dev, enable);
109012 + _errno = -GET_ERROR_TYPE(err);
109013 + if (unlikely(_errno < 0))
109014 + pr_err("FM_MAC_ConfigResetOnInit() = 0x%08x\n", err);
109015 +
109016 + return _errno;
109017 +}
109018 +EXPORT_SYMBOL(fm_mac_config_reset_on_init);
109019 +
109020 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev)
109021 +{
109022 + int err;
109023 + int _errno;
109024 +
109025 + err = FM_MAC_Init(fm_mac_dev);
109026 + _errno = -GET_ERROR_TYPE(err);
109027 + if (unlikely(_errno < 0))
109028 + pr_err("FM_MAC_Init() = 0x%08x\n", err);
109029 +
109030 + return _errno;
109031 +}
109032 +EXPORT_SYMBOL(fm_mac_init);
109033 +
109034 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version)
109035 +{
109036 + int err;
109037 + int _errno;
109038 +
109039 + err = FM_MAC_GetVesrion(fm_mac_dev, version);
109040 + _errno = -GET_ERROR_TYPE(err);
109041 + if (unlikely(_errno < 0))
109042 + pr_err("FM_MAC_GetVesrion() = 0x%08x\n", err);
109043 +
109044 + return _errno;
109045 +}
109046 +EXPORT_SYMBOL(fm_mac_get_version);
109047 +
109048 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev)
109049 +{
109050 + int _errno;
109051 + t_Error err;
109052 +
109053 + err = FM_MAC_Enable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
109054 + _errno = -GET_ERROR_TYPE(err);
109055 + if (unlikely(_errno < 0))
109056 + pr_err("FM_MAC_Enable() = 0x%08x\n", err);
109057 +
109058 + return _errno;
109059 +}
109060 +EXPORT_SYMBOL(fm_mac_enable);
109061 +
109062 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev)
109063 +{
109064 + int _errno;
109065 + t_Error err;
109066 +
109067 + err = FM_MAC_Disable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
109068 + _errno = -GET_ERROR_TYPE(err);
109069 + if (unlikely(_errno < 0))
109070 + pr_err("FM_MAC_Disable() = 0x%08x\n", err);
109071 +
109072 + return _errno;
109073 +}
109074 +EXPORT_SYMBOL(fm_mac_disable);
109075 +
109076 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev)
109077 +{
109078 + int _errno;
109079 + t_Error err;
109080 +
109081 + err = FM_MAC_Resume(fm_mac_dev);
109082 + _errno = -GET_ERROR_TYPE(err);
109083 + if (unlikely(_errno < 0))
109084 + pr_err("FM_MAC_Resume() = 0x%08x\n", err);
109085 +
109086 + return _errno;
109087 +}
109088 +EXPORT_SYMBOL(fm_mac_resume);
109089 +
109090 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
109091 + bool enable)
109092 +{
109093 + int _errno;
109094 + t_Error err;
109095 +
109096 + err = FM_MAC_SetPromiscuous(fm_mac_dev, enable);
109097 + _errno = -GET_ERROR_TYPE(err);
109098 + if (unlikely(_errno < 0))
109099 + pr_err("FM_MAC_SetPromiscuous() = 0x%08x\n", err);
109100 +
109101 + return _errno;
109102 +}
109103 +EXPORT_SYMBOL(fm_mac_set_promiscuous);
109104 +
109105 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
109106 + t_EnetAddr *mac_addr)
109107 +{
109108 + int _errno;
109109 + t_Error err;
109110 +
109111 + err = FM_MAC_RemoveHashMacAddr(fm_mac_dev, mac_addr);
109112 + _errno = -GET_ERROR_TYPE(err);
109113 + if (_errno < 0) {
109114 + pr_err("FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err);
109115 + return _errno;
109116 + }
109117 +
109118 + return 0;
109119 +}
109120 +EXPORT_SYMBOL(fm_mac_remove_hash_mac_addr);
109121 +
109122 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
109123 + t_EnetAddr *mac_addr)
109124 +{
109125 + int _errno;
109126 + t_Error err;
109127 +
109128 + err = FM_MAC_AddHashMacAddr(fm_mac_dev, mac_addr);
109129 + _errno = -GET_ERROR_TYPE(err);
109130 + if (_errno < 0) {
109131 + pr_err("FM_MAC_AddHashMacAddr() = 0x%08x\n", err);
109132 + return _errno;
109133 + }
109134 +
109135 + return 0;
109136 +}
109137 +EXPORT_SYMBOL(fm_mac_add_hash_mac_addr);
109138 +
109139 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
109140 + uint8_t *addr)
109141 +{
109142 + int _errno;
109143 + t_Error err;
109144 +
109145 + err = FM_MAC_ModifyMacAddr(fm_mac_dev, (t_EnetAddr *)addr);
109146 + _errno = -GET_ERROR_TYPE(err);
109147 + if (_errno < 0)
109148 + pr_err("FM_MAC_ModifyMacAddr() = 0x%08x\n", err);
109149 +
109150 + return _errno;
109151 +}
109152 +EXPORT_SYMBOL(fm_mac_modify_mac_addr);
109153 +
109154 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
109155 + bool link, int speed, bool duplex)
109156 +{
109157 + int _errno;
109158 + t_Error err;
109159 +
109160 + if (!link) {
109161 +#if (DPAA_VERSION < 11)
109162 + FM_MAC_RestartAutoneg(fm_mac_dev);
109163 +#endif
109164 + return 0;
109165 + }
109166 +
109167 + err = FM_MAC_AdjustLink(fm_mac_dev, speed, duplex);
109168 + _errno = -GET_ERROR_TYPE(err);
109169 + if (unlikely(_errno < 0))
109170 + pr_err("FM_MAC_AdjustLink() = 0x%08x\n", err);
109171 +
109172 + return _errno;
109173 +}
109174 +EXPORT_SYMBOL(fm_mac_adjust_link);
109175 +
109176 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
109177 +{
109178 + int _errno;
109179 + t_Error err;
109180 +
109181 + err = FM_MAC_Enable1588TimeStamp(fm_mac_dev);
109182 + _errno = -GET_ERROR_TYPE(err);
109183 + if (unlikely(_errno < 0))
109184 + pr_err("FM_MAC_Enable1588TimeStamp() = 0x%08x\n", err);
109185 + return _errno;
109186 +}
109187 +EXPORT_SYMBOL(fm_mac_enable_1588_time_stamp);
109188 +
109189 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
109190 +{
109191 + int _errno;
109192 + t_Error err;
109193 +
109194 + err = FM_MAC_Disable1588TimeStamp(fm_mac_dev);
109195 + _errno = -GET_ERROR_TYPE(err);
109196 + if (unlikely(_errno < 0))
109197 + pr_err("FM_MAC_Disable1588TimeStamp() = 0x%08x\n", err);
109198 + return _errno;
109199 +}
109200 +EXPORT_SYMBOL(fm_mac_disable_1588_time_stamp);
109201 +
109202 +int fm_mac_set_rx_pause_frames(
109203 + struct fm_mac_dev *fm_mac_dev, bool en)
109204 +{
109205 + int _errno;
109206 + t_Error err;
109207 +
109208 + /* if rx pause is enabled, do NOT ignore pause frames */
109209 + err = FM_MAC_SetRxIgnorePauseFrames(fm_mac_dev, !en);
109210 +
109211 + _errno = -GET_ERROR_TYPE(err);
109212 + if (_errno < 0)
109213 + pr_err("FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err);
109214 +
109215 + return _errno;
109216 +}
109217 +EXPORT_SYMBOL(fm_mac_set_rx_pause_frames);
109218 +
109219 +#ifdef CONFIG_FMAN_PFC
109220 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
109221 + bool en)
109222 +{
109223 + int _errno, i;
109224 + t_Error err;
109225 +
109226 + if (en)
109227 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
109228 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
109229 + i, fsl_fm_pfc_quanta[i],
109230 + FSL_FM_PAUSE_THRESH_DEFAULT);
109231 + _errno = -GET_ERROR_TYPE(err);
109232 + if (_errno < 0) {
109233 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
109234 + return _errno;
109235 + }
109236 + }
109237 + else
109238 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
109239 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
109240 + i, FSL_FM_PAUSE_TIME_DISABLE,
109241 + FSL_FM_PAUSE_THRESH_DEFAULT);
109242 + _errno = -GET_ERROR_TYPE(err);
109243 + if (_errno < 0) {
109244 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
109245 + return _errno;
109246 + }
109247 + }
109248 +
109249 + return _errno;
109250 +}
109251 +#else
109252 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
109253 + bool en)
109254 +{
109255 + int _errno;
109256 + t_Error err;
109257 +
109258 + if (en)
109259 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
109260 + FSL_FM_PAUSE_TIME_ENABLE);
109261 + else
109262 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
109263 + FSL_FM_PAUSE_TIME_DISABLE);
109264 +
109265 + _errno = -GET_ERROR_TYPE(err);
109266 + if (_errno < 0)
109267 + pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err);
109268 +
109269 + return _errno;
109270 +}
109271 +#endif
109272 +EXPORT_SYMBOL(fm_mac_set_tx_pause_frames);
109273 +
109274 +int fm_rtc_enable(struct fm *fm_dev)
109275 +{
109276 + int _errno;
109277 + t_Error err;
109278 +
109279 + err = FM_RTC_Enable(fm_get_rtc_handle(fm_dev), 0);
109280 + _errno = -GET_ERROR_TYPE(err);
109281 + if (unlikely(_errno < 0))
109282 + pr_err("FM_RTC_Enable = 0x%08x\n", err);
109283 +
109284 + return _errno;
109285 +}
109286 +EXPORT_SYMBOL(fm_rtc_enable);
109287 +
109288 +int fm_rtc_disable(struct fm *fm_dev)
109289 +{
109290 + int _errno;
109291 + t_Error err;
109292 +
109293 + err = FM_RTC_Disable(fm_get_rtc_handle(fm_dev));
109294 + _errno = -GET_ERROR_TYPE(err);
109295 + if (unlikely(_errno < 0))
109296 + pr_err("FM_RTC_Disable = 0x%08x\n", err);
109297 +
109298 + return _errno;
109299 +}
109300 +EXPORT_SYMBOL(fm_rtc_disable);
109301 +
109302 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts)
109303 +{
109304 + int _errno;
109305 + t_Error err;
109306 +
109307 + err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
109308 + _errno = -GET_ERROR_TYPE(err);
109309 + if (unlikely(_errno < 0))
109310 + pr_err("FM_RTC_GetCurrentTime = 0x%08x\n", err);
109311 +
109312 + return _errno;
109313 +}
109314 +EXPORT_SYMBOL(fm_rtc_get_cnt);
109315 +
109316 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts)
109317 +{
109318 + int _errno;
109319 + t_Error err;
109320 +
109321 + err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
109322 + _errno = -GET_ERROR_TYPE(err);
109323 + if (unlikely(_errno < 0))
109324 + pr_err("FM_RTC_SetCurrentTime = 0x%08x\n", err);
109325 +
109326 + return _errno;
109327 +}
109328 +EXPORT_SYMBOL(fm_rtc_set_cnt);
109329 +
109330 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift)
109331 +{
109332 + int _errno;
109333 + t_Error err;
109334 +
109335 + err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(fm_dev),
109336 + drift);
109337 + _errno = -GET_ERROR_TYPE(err);
109338 + if (unlikely(_errno < 0))
109339 + pr_err("FM_RTC_GetFreqCompensation = 0x%08x\n", err);
109340 +
109341 + return _errno;
109342 +}
109343 +EXPORT_SYMBOL(fm_rtc_get_drift);
109344 +
109345 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift)
109346 +{
109347 + int _errno;
109348 + t_Error err;
109349 +
109350 + err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(fm_dev),
109351 + drift);
109352 + _errno = -GET_ERROR_TYPE(err);
109353 + if (unlikely(_errno < 0))
109354 + pr_err("FM_RTC_SetFreqCompensation = 0x%08x\n", err);
109355 +
109356 + return _errno;
109357 +}
109358 +EXPORT_SYMBOL(fm_rtc_set_drift);
109359 +
109360 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
109361 + uint64_t time)
109362 +{
109363 + t_FmRtcAlarmParams alarm;
109364 + int _errno;
109365 + t_Error err;
109366 +
109367 + alarm.alarmId = id;
109368 + alarm.alarmTime = time;
109369 + alarm.f_AlarmCallback = NULL;
109370 + err = FM_RTC_SetAlarm(fm_get_rtc_handle(fm_dev),
109371 + &alarm);
109372 + _errno = -GET_ERROR_TYPE(err);
109373 + if (unlikely(_errno < 0))
109374 + pr_err("FM_RTC_SetAlarm = 0x%08x\n", err);
109375 +
109376 + return _errno;
109377 +}
109378 +EXPORT_SYMBOL(fm_rtc_set_alarm);
109379 +
109380 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
109381 + uint64_t fiper)
109382 +{
109383 + t_FmRtcPeriodicPulseParams pp;
109384 + int _errno;
109385 + t_Error err;
109386 +
109387 + pp.periodicPulseId = id;
109388 + pp.periodicPulsePeriod = fiper;
109389 + pp.f_PeriodicPulseCallback = NULL;
109390 + err = FM_RTC_SetPeriodicPulse(fm_get_rtc_handle(fm_dev), &pp);
109391 + _errno = -GET_ERROR_TYPE(err);
109392 + if (unlikely(_errno < 0))
109393 + pr_err("FM_RTC_SetPeriodicPulse = 0x%08x\n", err);
109394 +
109395 + return _errno;
109396 +}
109397 +EXPORT_SYMBOL(fm_rtc_set_fiper);
109398 +
109399 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
109400 +int fm_rtc_enable_interrupt(struct fm *fm_dev, uint32_t events)
109401 +{
109402 + int _errno;
109403 + t_Error err;
109404 +
109405 + err = FM_RTC_EnableInterrupt(fm_get_rtc_handle(fm_dev),
109406 + events);
109407 + _errno = -GET_ERROR_TYPE(err);
109408 + if (unlikely(_errno < 0))
109409 + pr_err("FM_RTC_EnableInterrupt = 0x%08x\n", err);
109410 +
109411 + return _errno;
109412 +}
109413 +EXPORT_SYMBOL(fm_rtc_enable_interrupt);
109414 +
109415 +int fm_rtc_disable_interrupt(struct fm *fm_dev, uint32_t events)
109416 +{
109417 + int _errno;
109418 + t_Error err;
109419 +
109420 + err = FM_RTC_DisableInterrupt(fm_get_rtc_handle(fm_dev),
109421 + events);
109422 + _errno = -GET_ERROR_TYPE(err);
109423 + if (unlikely(_errno < 0))
109424 + pr_err("FM_RTC_DisableInterrupt = 0x%08x\n", err);
109425 +
109426 + return _errno;
109427 +}
109428 +EXPORT_SYMBOL(fm_rtc_disable_interrupt);
109429 +#endif
109430 +
109431 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en)
109432 +{
109433 + int _errno;
109434 + t_Error err;
109435 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109436 +
109437 + /* Do not set WoL on AR ports */
109438 + if (FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) {
109439 + printk(KERN_WARNING "Port is AutoResponse enabled! WoL will not be set on this port!\n");
109440 + return 0;
109441 + }
109442 +
109443 + err = FM_MAC_SetWakeOnLan(fm_mac_dev, en);
109444 +
109445 + _errno = -GET_ERROR_TYPE(err);
109446 + if (_errno < 0)
109447 + pr_err("FM_MAC_SetWakeOnLan() = 0x%08x\n", err);
109448 +
109449 + return _errno;
109450 +}
109451 +EXPORT_SYMBOL(fm_mac_set_wol);
109452 +
109453 +void fm_mutex_lock(void)
109454 +{
109455 + mutex_lock(&lnxwrp_mutex);
109456 +}
109457 +EXPORT_SYMBOL(fm_mutex_lock);
109458 +
109459 +void fm_mutex_unlock(void)
109460 +{
109461 + mutex_unlock(&lnxwrp_mutex);
109462 +}
109463 +EXPORT_SYMBOL(fm_mutex_unlock);
109464 +
109465 +/*Macsec wrapper functions*/
109466 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params)
109467 +{
109468 + struct fm_macsec_dev *fm_macsec_dev;
109469 +
109470 + fm_macsec_dev = FM_MACSEC_Config((t_FmMacsecParams *)fm_params);
109471 + if (unlikely(fm_macsec_dev == NULL))
109472 + pr_err("FM_MACSEC_Config() failed\n");
109473 +
109474 + return fm_macsec_dev;
109475 +}
109476 +EXPORT_SYMBOL(fm_macsec_config);
109477 +
109478 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev)
109479 +{
109480 + int err;
109481 + int _errno;
109482 +
109483 + err = FM_MACSEC_Init(fm_macsec_dev);
109484 + _errno = -GET_ERROR_TYPE(err);
109485 + if (unlikely(_errno < 0))
109486 + pr_err("FM_MACSEC_Init() = 0x%08x\n", err);
109487 +
109488 + return _errno;
109489 +}
109490 +EXPORT_SYMBOL(fm_macsec_init);
109491 +
109492 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev)
109493 +{
109494 + int err;
109495 + int _error;
109496 +
109497 + err = FM_MACSEC_Free(fm_macsec_dev);
109498 + _error = -GET_ERROR_TYPE(err);
109499 +
109500 + if (unlikely(_error < 0))
109501 + pr_err("FM_MACSEC_Free() = 0x%08x\n", err);
109502 +
109503 + return _error;
109504 +}
109505 +EXPORT_SYMBOL(fm_macsec_free);
109506 +
109507 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
109508 + *fm_macsec_dev,
109509 + fm_macsec_unknown_sci_frame_treatment treat_mode)
109510 +{
109511 + int err;
109512 + int _errno;
109513 +
109514 + err = FM_MACSEC_ConfigUnknownSciFrameTreatment(fm_macsec_dev,
109515 + treat_mode);
109516 + _errno = -GET_ERROR_TYPE(err);
109517 + if (unlikely(_errno < 0))
109518 + pr_err("FM_MACSEC_ConfigUnknownSciFrameTreatmen() = 0x%08x\n", err);
109519 +
109520 + return _errno;
109521 +}
109522 +EXPORT_SYMBOL(fm_macsec_config_unknown_sci_frame_treatment);
109523 +
109524 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109525 + bool deliver_uncontrolled)
109526 +{
109527 + int err;
109528 + int _errno;
109529 +
109530 + err = FM_MACSEC_ConfigInvalidTagsFrameTreatment(fm_macsec_dev,
109531 + deliver_uncontrolled);
109532 + _errno = -GET_ERROR_TYPE(err);
109533 + if (unlikely(_errno < 0))
109534 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
109535 +
109536 + return _errno;
109537 +}
109538 +EXPORT_SYMBOL(fm_macsec_config_invalid_tags_frame_treatment);
109539 +
109540 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109541 + bool discard_uncontrolled)
109542 +{
109543 + int err;
109544 + int _errno;
109545 +
109546 + err = FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(fm_macsec_dev,
109547 + discard_uncontrolled);
109548 + _errno = -GET_ERROR_TYPE(err);
109549 + if (unlikely(_errno < 0))
109550 + pr_err("FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatmen() = 0x%08x\n", err);
109551 +
109552 + return _errno;
109553 +}
109554 +EXPORT_SYMBOL(fm_macsec_config_kay_frame_treatment);
109555 +
109556 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109557 + fm_macsec_untag_frame_treatment treat_mode)
109558 +{
109559 + int err;
109560 + int _errno;
109561 +
109562 + err = FM_MACSEC_ConfigUntagFrameTreatment(fm_macsec_dev, treat_mode);
109563 + _errno = -GET_ERROR_TYPE(err);
109564 + if (unlikely(_errno < 0))
109565 + pr_err("FM_MACSEC_ConfigUntagFrameTreatment() = 0x%08x\n", err);
109566 +
109567 + return _errno;
109568 +}
109569 +EXPORT_SYMBOL(fm_macsec_config_untag_frame_treatment);
109570 +
109571 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
109572 + uint32_t pn_exh_thr)
109573 +{
109574 + int err;
109575 + int _errno;
109576 +
109577 + err = FM_MACSEC_ConfigPnExhaustionThreshold(fm_macsec_dev, pn_exh_thr);
109578 + _errno = -GET_ERROR_TYPE(err);
109579 + if (unlikely(_errno < 0))
109580 + pr_err("FM_MACSEC_ConfigPnExhaustionThreshold() = 0x%08x\n", err);
109581 +
109582 + return _errno;
109583 +}
109584 +EXPORT_SYMBOL(fm_macsec_config_pn_exhaustion_threshold);
109585 +
109586 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev)
109587 +{
109588 + int err;
109589 + int _errno;
109590 +
109591 + err = FM_MACSEC_ConfigKeysUnreadable(fm_macsec_dev);
109592 + _errno = -GET_ERROR_TYPE(err);
109593 + if (unlikely(_errno < 0))
109594 + pr_err("FM_MACSEC_ConfigKeysUnreadable() = 0x%08x\n", err);
109595 +
109596 + return _errno;
109597 +}
109598 +EXPORT_SYMBOL(fm_macsec_config_keys_unreadable);
109599 +
109600 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev)
109601 +{
109602 + int err;
109603 + int _errno;
109604 +
109605 + err = FM_MACSEC_ConfigSectagWithoutSCI(fm_macsec_dev);
109606 + _errno = -GET_ERROR_TYPE(err);
109607 + if (unlikely(_errno < 0))
109608 + pr_err("FM_MACSEC_ConfigSectagWithoutSCI() = 0x%08x\n", err);
109609 +
109610 + return _errno;
109611 +}
109612 +EXPORT_SYMBOL(fm_macsec_config_sectag_without_sci);
109613 +
109614 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
109615 + fm_macsec_exception exception, bool enable)
109616 +{
109617 + int err;
109618 + int _errno;
109619 +
109620 + err = FM_MACSEC_ConfigException(fm_macsec_dev, exception, enable);
109621 + _errno = -GET_ERROR_TYPE(err);
109622 + if (unlikely(_errno < 0))
109623 + pr_err("FM_MACSEC_ConfigException() = 0x%08x\n", err);
109624 +
109625 + return _errno;
109626 +}
109627 +EXPORT_SYMBOL(fm_macsec_config_exception);
109628 +
109629 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
109630 + int *macsec_revision)
109631 +{
109632 + int err;
109633 + int _errno;
109634 +
109635 + err = FM_MACSEC_GetRevision(fm_macsec_dev, macsec_revision);
109636 + _errno = -GET_ERROR_TYPE(err);
109637 + if (unlikely(_errno < 0))
109638 + pr_err("FM_MACSEC_GetRevision() = 0x%08x\n", err);
109639 +
109640 + return _errno;
109641 +}
109642 +EXPORT_SYMBOL(fm_macsec_get_revision);
109643 +
109644 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev)
109645 +{
109646 + int err;
109647 + int _errno;
109648 +
109649 + err = FM_MACSEC_Enable(fm_macsec_dev);
109650 + _errno = -GET_ERROR_TYPE(err);
109651 + if (unlikely(_errno < 0))
109652 + pr_err("FM_MACSEC_Enable() = 0x%08x\n", err);
109653 +
109654 + return _errno;
109655 +}
109656 +EXPORT_SYMBOL(fm_macsec_enable);
109657 +
109658 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev)
109659 +{
109660 + int err;
109661 + int _errno;
109662 +
109663 + err = FM_MACSEC_Disable(fm_macsec_dev);
109664 + _errno = -GET_ERROR_TYPE(err);
109665 + if (unlikely(_errno < 0))
109666 + pr_err("FM_MACSEC_Disable() = 0x%08x\n", err);
109667 +
109668 + return _errno;
109669 +}
109670 +EXPORT_SYMBOL(fm_macsec_disable);
109671 +
109672 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
109673 + fm_macsec_exception exception, bool enable)
109674 +{
109675 + int err;
109676 + int _errno;
109677 +
109678 + err = FM_MACSEC_SetException(fm_macsec_dev, exception, enable);
109679 + _errno = -GET_ERROR_TYPE(err);
109680 + if (unlikely(_errno < 0))
109681 + pr_err("FM_MACSEC_SetException() = 0x%08x\n", err);
109682 +
109683 + return _errno;
109684 +}
109685 +EXPORT_SYMBOL(fm_macsec_set_exception);
109686 +
109687 +/* Macsec SECY wrapper API */
109688 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params)
109689 +{
109690 + struct fm_macsec_secy_dev *fm_macsec_secy;
109691 +
109692 + fm_macsec_secy = FM_MACSEC_SECY_Config((t_FmMacsecSecYParams *)secy_params);
109693 + if (unlikely(fm_macsec_secy < 0))
109694 + pr_err("FM_MACSEC_SECY_Config() failed\n");
109695 +
109696 + return fm_macsec_secy;
109697 +}
109698 +EXPORT_SYMBOL(fm_macsec_secy_config);
109699 +
109700 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109701 +{
109702 + int err;
109703 + int _errno;
109704 +
109705 + err = FM_MACSEC_SECY_Init(fm_macsec_secy_dev);
109706 + _errno = -GET_ERROR_TYPE(err);
109707 + if (unlikely(_errno < 0))
109708 + pr_err("FM_MACSEC_SECY_Init() = 0x%08x\n", err);
109709 +
109710 + return _errno;
109711 +}
109712 +EXPORT_SYMBOL(fm_macsec_secy_init);
109713 +
109714 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109715 +{
109716 + int err;
109717 + int _errno;
109718 +
109719 + err = FM_MACSEC_SECY_Free(fm_macsec_secy_dev);
109720 + _errno = -GET_ERROR_TYPE(err);
109721 + if (unlikely(_errno < 0))
109722 + pr_err("FM_MACSEC_SECY_Free() = 0x%08x\n", err);
109723 +
109724 + return _errno;
109725 +}
109726 +EXPORT_SYMBOL(fm_macsec_secy_free);
109727 +
109728 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109729 + fm_macsec_sci_insertion_mode sci_insertion_mode)
109730 +{
109731 + int err;
109732 + int _errno;
109733 +
109734 + err = FM_MACSEC_SECY_ConfigSciInsertionMode(fm_macsec_secy_dev,
109735 + sci_insertion_mode);
109736 + _errno = -GET_ERROR_TYPE(err);
109737 + if (unlikely(_errno < 0))
109738 + pr_err("FM_MACSEC_SECY_ConfigSciInsertionMode() = 0x%08x\n", err);
109739 +
109740 + return _errno;
109741 +}
109742 +EXPORT_SYMBOL(fm_macsec_secy_config_sci_insertion_mode);
109743 +
109744 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109745 + bool protect_frames)
109746 +{
109747 + int err;
109748 + int _errno;
109749 +
109750 + err = FM_MACSEC_SECY_ConfigProtectFrames(fm_macsec_secy_dev,
109751 + protect_frames);
109752 + _errno = -GET_ERROR_TYPE(err);
109753 + if (unlikely(_errno < 0))
109754 + pr_err("FM_MACSEC_SECY_ConfigProtectFrames() = 0x%08x\n", err);
109755 +
109756 + return _errno;
109757 +}
109758 +EXPORT_SYMBOL(fm_macsec_secy_config_protect_frames);
109759 +
109760 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109761 + bool replay_protect, uint32_t replay_window)
109762 +{
109763 + int err;
109764 + int _errno;
109765 +
109766 + err = FM_MACSEC_SECY_ConfigReplayWindow(fm_macsec_secy_dev,
109767 + replay_protect, replay_window);
109768 + _errno = -GET_ERROR_TYPE(err);
109769 + if (unlikely(_errno < 0))
109770 + pr_err("FM_MACSEC_SECY_ConfigReplayWindow() = 0x%08x\n", err);
109771 +
109772 + return _errno;
109773 +}
109774 +EXPORT_SYMBOL(fm_macsec_secy_config_replay_window);
109775 +
109776 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109777 + fm_macsec_valid_frame_behavior validate_frames)
109778 +{
109779 + int err;
109780 + int _errno;
109781 +
109782 + err = FM_MACSEC_SECY_ConfigValidationMode(fm_macsec_secy_dev,
109783 + validate_frames);
109784 + _errno = -GET_ERROR_TYPE(err);
109785 + if (unlikely(_errno < 0))
109786 + pr_err("FM_MACSEC_SECY_ConfigValidationMode() = 0x%08x\n", err);
109787 +
109788 + return _errno;
109789 +}
109790 +EXPORT_SYMBOL(fm_macsec_secy_config_validation_mode);
109791 +
109792 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109793 + bool confidentiality_enable,
109794 + uint32_t confidentiality_offset)
109795 +{
109796 + int err;
109797 + int _errno;
109798 +
109799 + err = FM_MACSEC_SECY_ConfigConfidentiality(fm_macsec_secy_dev,
109800 + confidentiality_enable,
109801 + confidentiality_offset);
109802 + _errno = -GET_ERROR_TYPE(err);
109803 + if (unlikely(_errno < 0))
109804 + pr_err("FM_MACSEC_SECY_ConfigConfidentiality() = 0x%08x\n",
109805 + err);
109806 +
109807 + return _errno;
109808 +}
109809 +EXPORT_SYMBOL(fm_macsec_secy_config_confidentiality);
109810 +
109811 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109812 +{
109813 + int err;
109814 + int _errno;
109815 +
109816 + err = FM_MACSEC_SECY_ConfigPointToPoint(fm_macsec_secy_dev);
109817 + _errno = -GET_ERROR_TYPE(err);
109818 + if (unlikely(_errno < 0))
109819 + pr_err("FM_MACSEC_SECY_ConfigPointToPoint() = 0x%08x\n",
109820 + err);
109821 +
109822 + return _errno;
109823 +}
109824 +EXPORT_SYMBOL(fm_macsec_secy_config_point_to_point);
109825 +
109826 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109827 + fm_macsec_secy_exception exception,
109828 + bool enable)
109829 +{
109830 + int err;
109831 + int _errno;
109832 +
109833 + err = FM_MACSEC_SECY_ConfigException(fm_macsec_secy_dev, exception,
109834 + enable);
109835 + _errno = -GET_ERROR_TYPE(err);
109836 + if (unlikely(_errno < 0))
109837 + pr_err("FM_MACSEC_SECY_ConfigException() = 0x%08x\n",
109838 + err);
109839 +
109840 + return _errno;
109841 +}
109842 +EXPORT_SYMBOL(fm_macsec_secy_config_exception);
109843 +
109844 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109845 + fm_macsec_secy_event event,
109846 + bool enable)
109847 +{
109848 + int err;
109849 + int _errno;
109850 +
109851 + err = FM_MACSEC_SECY_ConfigEvent(fm_macsec_secy_dev, event, enable);
109852 + _errno = -GET_ERROR_TYPE(err);
109853 + if (unlikely(_errno < 0))
109854 + pr_err("FM_MACSEC_SECY_ConfigEvent() = 0x%08x\n",
109855 + err);
109856 +
109857 + return _errno;
109858 +}
109859 +EXPORT_SYMBOL(fm_macsec_secy_config_event);
109860 +
109861 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109862 + struct fm_macsec_secy_sc_params *params)
109863 +{
109864 + struct rx_sc_dev *rx_sc_dev;
109865 +
109866 + rx_sc_dev = FM_MACSEC_SECY_CreateRxSc(fm_macsec_secy_dev, (t_FmMacsecSecYSCParams *)params);
109867 + if (unlikely(rx_sc_dev == NULL))
109868 + pr_err("FM_MACSEC_SECY_CreateRxSc() failed\n");
109869 +
109870 + return rx_sc_dev;
109871 +}
109872 +EXPORT_SYMBOL(fm_macsec_secy_create_rxsc);
109873 +
109874 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109875 + struct rx_sc_dev *sc)
109876 +{
109877 + int err;
109878 + int _errno;
109879 +
109880 + err = FM_MACSEC_SECY_DeleteRxSc(fm_macsec_secy_dev, sc);
109881 + _errno = -GET_ERROR_TYPE(err);
109882 + if (unlikely(_errno < 0))
109883 + pr_err("FM_MACSEC_SECY_DeleteRxSc() = 0x%08x\n",
109884 + err);
109885 +
109886 + return _errno;
109887 +}
109888 +EXPORT_SYMBOL(fm_macsec_secy_delete_rxsc);
109889 +
109890 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109891 + struct rx_sc_dev *sc, macsec_an_t an,
109892 + uint32_t lowest_pn, macsec_sa_key_t key)
109893 +{
109894 + int err;
109895 + int _errno;
109896 +
109897 + err = FM_MACSEC_SECY_CreateRxSa(fm_macsec_secy_dev, sc, an,
109898 + lowest_pn, key);
109899 + _errno = -GET_ERROR_TYPE(err);
109900 + if (unlikely(_errno < 0))
109901 + pr_err("FM_MACSEC_SECY_CreateRxSa() = 0x%08x\n",
109902 + err);
109903 +
109904 + return _errno;
109905 +}
109906 +EXPORT_SYMBOL(fm_macsec_secy_create_rx_sa);
109907 +
109908 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109909 + struct rx_sc_dev *sc, macsec_an_t an)
109910 +{
109911 + int err;
109912 + int _errno;
109913 +
109914 + err = FM_MACSEC_SECY_DeleteRxSa(fm_macsec_secy_dev, sc, an);
109915 + _errno = -GET_ERROR_TYPE(err);
109916 + if (unlikely(_errno < 0))
109917 + pr_err("FM_MACSEC_SECY_DeleteRxSa() = 0x%08x\n",
109918 + err);
109919 +
109920 + return _errno;
109921 +}
109922 +EXPORT_SYMBOL(fm_macsec_secy_delete_rx_sa);
109923 +
109924 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109925 + struct rx_sc_dev *sc,
109926 + macsec_an_t an)
109927 +{
109928 + int err;
109929 + int _errno;
109930 +
109931 + err = FM_MACSEC_SECY_RxSaEnableReceive(fm_macsec_secy_dev, sc, an);
109932 + _errno = -GET_ERROR_TYPE(err);
109933 + if (unlikely(_errno < 0))
109934 + pr_err("FM_MACSEC_SECY_RxSaEnableReceive() = 0x%08x\n",
109935 + err);
109936 +
109937 + return _errno;
109938 +}
109939 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_enable_receive);
109940 +
109941 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109942 + struct rx_sc_dev *sc,
109943 + macsec_an_t an)
109944 +{
109945 + int err;
109946 + int _errno;
109947 +
109948 + err = FM_MACSEC_SECY_RxSaDisableReceive(fm_macsec_secy_dev, sc, an);
109949 + _errno = -GET_ERROR_TYPE(err);
109950 + if (unlikely(_errno < 0))
109951 + pr_err("FM_MACSEC_SECY_RxSaDisableReceive() = 0x%08x\n",
109952 + err);
109953 +
109954 + return _errno;
109955 +}
109956 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_disable_receive);
109957 +
109958 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109959 + struct rx_sc_dev *sc,
109960 + macsec_an_t an, uint32_t updt_next_pn)
109961 +{
109962 + int err;
109963 + int _errno;
109964 +
109965 + err = FM_MACSEC_SECY_RxSaUpdateNextPn(fm_macsec_secy_dev, sc, an,
109966 + updt_next_pn);
109967 + _errno = -GET_ERROR_TYPE(err);
109968 + if (unlikely(_errno < 0))
109969 + pr_err("FM_MACSEC_SECY_RxSaUpdateNextPn() = 0x%08x\n", err);
109970 +
109971 + return _errno;
109972 +}
109973 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_next_pn);
109974 +
109975 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109976 + struct rx_sc_dev *sc,
109977 + macsec_an_t an, uint32_t updt_lowest_pn)
109978 +{
109979 + int err;
109980 + int _errno;
109981 +
109982 + err = FM_MACSEC_SECY_RxSaUpdateLowestPn(fm_macsec_secy_dev, sc, an,
109983 + updt_lowest_pn);
109984 + _errno = -GET_ERROR_TYPE(err);
109985 + if (unlikely(_errno < 0))
109986 + pr_err("FM_MACSEC_SECY_RxSaUpdateLowestPn() = 0x%08x\n",
109987 + err);
109988 +
109989 + return _errno;
109990 +}
109991 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_lowest_pn);
109992 +
109993 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109994 + struct rx_sc_dev *sc,
109995 + macsec_an_t an, macsec_sa_key_t key)
109996 +{
109997 + int err;
109998 + int _errno;
109999 +
110000 + err = FM_MACSEC_SECY_RxSaModifyKey(fm_macsec_secy_dev, sc, an, key);
110001 + _errno = -GET_ERROR_TYPE(err);
110002 + if (unlikely(_errno < 0))
110003 + pr_err("FM_MACSEC_SECY_RxSaModifyKey() = 0x%08x\n",
110004 + err);
110005 +
110006 + return _errno;
110007 +}
110008 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_modify_key);
110009 +
110010 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110011 + macsec_an_t an, macsec_sa_key_t key)
110012 +{
110013 + int err;
110014 + int _errno;
110015 +
110016 + err = FM_MACSEC_SECY_CreateTxSa(fm_macsec_secy_dev, an, key);
110017 + _errno = -GET_ERROR_TYPE(err);
110018 + if (unlikely(_errno < 0))
110019 + pr_err("FM_MACSEC_SECY_CreateTxSa() = 0x%08x\n",
110020 + err);
110021 +
110022 + return _errno;
110023 +}
110024 +EXPORT_SYMBOL(fm_macsec_secy_create_tx_sa);
110025 +
110026 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110027 + macsec_an_t an)
110028 +{
110029 + int err;
110030 + int _errno;
110031 +
110032 + err = FM_MACSEC_SECY_DeleteTxSa(fm_macsec_secy_dev, an);
110033 + _errno = -GET_ERROR_TYPE(err);
110034 + if (unlikely(_errno < 0))
110035 + pr_err("FM_MACSEC_SECY_DeleteTxSa() = 0x%08x\n",
110036 + err);
110037 +
110038 + return _errno;
110039 +}
110040 +EXPORT_SYMBOL(fm_macsec_secy_delete_tx_sa);
110041 +
110042 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110043 + macsec_an_t next_active_an,
110044 + macsec_sa_key_t key)
110045 +{
110046 + int err;
110047 + int _errno;
110048 +
110049 + err = FM_MACSEC_SECY_TxSaModifyKey(fm_macsec_secy_dev, next_active_an,
110050 + key);
110051 + _errno = -GET_ERROR_TYPE(err);
110052 + if (unlikely(_errno < 0))
110053 + pr_err("FM_MACSEC_SECY_TxSaModifyKey() = 0x%08x\n",
110054 + err);
110055 +
110056 + return _errno;
110057 +}
110058 +EXPORT_SYMBOL(fm_macsec_secy_txsa_modify_key);
110059 +
110060 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110061 + macsec_an_t an)
110062 +{
110063 + int err;
110064 + int _errno;
110065 +
110066 + err = FM_MACSEC_SECY_TxSaSetActive(fm_macsec_secy_dev, an);
110067 + _errno = -GET_ERROR_TYPE(err);
110068 + if (unlikely(_errno < 0))
110069 + pr_err("FM_MACSEC_SECY_TxSaSetActive() = 0x%08x\n",
110070 + err);
110071 +
110072 + return _errno;
110073 +}
110074 +EXPORT_SYMBOL(fm_macsec_secy_txsa_set_active);
110075 +
110076 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110077 + macsec_an_t *p_an)
110078 +{
110079 + int err;
110080 + int _errno;
110081 +
110082 + err = FM_MACSEC_SECY_TxSaGetActive(fm_macsec_secy_dev, p_an);
110083 + _errno = -GET_ERROR_TYPE(err);
110084 + if (unlikely(_errno < 0))
110085 + pr_err("FM_MACSEC_SECY_TxSaGetActive() = 0x%08x\n",
110086 + err);
110087 +
110088 + return _errno;
110089 +}
110090 +EXPORT_SYMBOL(fm_macsec_secy_txsa_get_active);
110091 +
110092 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110093 + struct rx_sc_dev *sc, uint32_t *sc_phys_id)
110094 +{
110095 + int err;
110096 + int _errno;
110097 +
110098 + err = FM_MACSEC_SECY_GetRxScPhysId(fm_macsec_secy_dev, sc, sc_phys_id);
110099 + _errno = -GET_ERROR_TYPE(err);
110100 + if (unlikely(_errno < 0))
110101 + pr_err("FM_MACSEC_SECY_GetRxScPhysId() = 0x%08x\n",
110102 + err);
110103 +
110104 + return _errno;
110105 +}
110106 +EXPORT_SYMBOL(fm_macsec_secy_get_rxsc_phys_id);
110107 +
110108 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110109 + uint32_t *sc_phys_id)
110110 +{
110111 + int err;
110112 + int _errno;
110113 +
110114 + err = FM_MACSEC_SECY_GetTxScPhysId(fm_macsec_secy_dev, sc_phys_id);
110115 + _errno = -GET_ERROR_TYPE(err);
110116 + if (unlikely(_errno < 0))
110117 + pr_err("FM_MACSEC_SECY_GetTxScPhysId() = 0x%08x\n",
110118 + err);
110119 +
110120 + return _errno;
110121 +}
110122 +EXPORT_SYMBOL(fm_macsec_secy_get_txsc_phys_id);
110123 +
110124 +static t_Handle h_FmLnxWrp;
110125 +
110126 +static int __init __cold fm_load (void)
110127 +{
110128 + if ((h_FmLnxWrp = LNXWRP_FM_Init()) == NULL)
110129 + {
110130 + printk("Failed to init FM wrapper!\n");
110131 + return -ENODEV;
110132 + }
110133 +
110134 + printk(KERN_CRIT "Freescale FM module," \
110135 + " FMD API version %d.%d.%d\n",
110136 + FMD_API_VERSION_MAJOR,
110137 + FMD_API_VERSION_MINOR,
110138 + FMD_API_VERSION_RESPIN);
110139 + return 0;
110140 +}
110141 +
110142 +static void __exit __cold fm_unload (void)
110143 +{
110144 + if (h_FmLnxWrp)
110145 + LNXWRP_FM_Free(h_FmLnxWrp);
110146 +}
110147 +
110148 +module_init (fm_load);
110149 +module_exit (fm_unload);
110150 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
110151 new file mode 100644
110152 index 00000000..09832563
110153 --- /dev/null
110154 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
110155 @@ -0,0 +1,294 @@
110156 +/*
110157 + * Copyright 2008-2012 Freescale Semiconductor Inc.
110158 + *
110159 + * Redistribution and use in source and binary forms, with or without
110160 + * modification, are permitted provided that the following conditions are met:
110161 + * * Redistributions of source code must retain the above copyright
110162 + * notice, this list of conditions and the following disclaimer.
110163 + * * Redistributions in binary form must reproduce the above copyright
110164 + * notice, this list of conditions and the following disclaimer in the
110165 + * documentation and/or other materials provided with the distribution.
110166 + * * Neither the name of Freescale Semiconductor nor the
110167 + * names of its contributors may be used to endorse or promote products
110168 + * derived from this software without specific prior written permission.
110169 + *
110170 + *
110171 + * ALTERNATIVELY, this software may be distributed under the terms of the
110172 + * GNU General Public License ("GPL") as published by the Free Software
110173 + * Foundation, either version 2 of that License or (at your option) any
110174 + * later version.
110175 + *
110176 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
110177 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
110178 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
110179 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
110180 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
110181 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
110182 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
110183 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
110184 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
110185 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
110186 + */
110187 +
110188 +/*
110189 + @File lnxwrp_fm.h
110190 +
110191 + @Author Shlomi Gridish
110192 +
110193 + @Description FM Linux wrapper functions.
110194 +
110195 +*/
110196 +
110197 +#ifndef __LNXWRP_FM_H__
110198 +#define __LNXWRP_FM_H__
110199 +
110200 +#include <linux/fsl_qman.h> /* struct qman_fq */
110201 +
110202 +#include "std_ext.h"
110203 +#include "error_ext.h"
110204 +#include "list_ext.h"
110205 +
110206 +#include "lnxwrp_fm_ext.h"
110207 +
110208 +#define FM_MAX_NUM_OF_ADV_SETTINGS 10
110209 +
110210 +#define LNXWRP_FM_NUM_OF_SHARED_PROFILES 16
110211 +
110212 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
110213 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
110214 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
110215 +#else
110216 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
110217 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
110218 +#endif
110219 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
110220 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
110221 +
110222 +#define FRAG_MANIP_SPACE 128
110223 +#define FRAG_DATA_ALIGN 64
110224 +
110225 +#ifndef CONFIG_FSL_FM_MAX_FRAME_SIZE
110226 +#define CONFIG_FSL_FM_MAX_FRAME_SIZE 0
110227 +#endif
110228 +
110229 +#ifndef CONFIG_FSL_FM_RX_EXTRA_HEADROOM
110230 +#define CONFIG_FSL_FM_RX_EXTRA_HEADROOM 16
110231 +#endif
110232 +
110233 +typedef enum {
110234 + e_NO_PCD = 0,
110235 + e_FM_PCD_3_TUPLE
110236 +} e_LnxWrpFmPortPcdDefUseCase;
110237 +
110238 +
110239 +typedef struct t_FmTestFq {
110240 + struct qman_fq fq_base;
110241 + t_Handle h_Arg;
110242 +} t_FmTestFq;
110243 +
110244 +typedef struct {
110245 + uint8_t id; /* sw port id, see SW_PORT_ID_TO_HW_PORT_ID() in fm_common.h */
110246 + int minor;
110247 + char name[20];
110248 + bool active;
110249 + uint64_t phys_baseAddr;
110250 + uint64_t baseAddr; /* Port's *virtual* address */
110251 + uint32_t memSize;
110252 + t_WrpFmPortDevSettings settings;
110253 + t_FmExtPools opExtPools;
110254 + uint8_t totalNumOfSchemes;
110255 + uint8_t schemesBase;
110256 + uint8_t numOfSchemesUsed;
110257 + uint32_t pcdBaseQ;
110258 + uint16_t pcdNumOfQs;
110259 + struct fm_port_pcd_param pcd_owner_params;
110260 + e_LnxWrpFmPortPcdDefUseCase defPcd;
110261 + t_Handle h_DefNetEnv;
110262 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
110263 + t_FmBufferPrefixContent buffPrefixContent;
110264 + t_Handle h_Dev;
110265 + t_Handle h_DfltVsp;
110266 + t_Handle h_LnxWrpFmDev;
110267 + uint16_t txCh;
110268 + struct device *dev;
110269 + struct device_attribute *dev_attr_stats;
110270 + struct device_attribute *dev_attr_regs;
110271 + struct device_attribute *dev_attr_bmi_regs;
110272 + struct device_attribute *dev_attr_qmi_regs;
110273 +#if (DPAA_VERSION >= 11)
110274 + struct device_attribute *dev_attr_ipv4_opt;
110275 +#endif
110276 + struct device_attribute *dev_attr_dsar_regs;
110277 + struct device_attribute *dev_attr_dsar_mem;
110278 + struct auto_res_tables_sizes dsar_table_sizes;
110279 +} t_LnxWrpFmPortDev;
110280 +
110281 +typedef struct {
110282 + uint8_t id;
110283 + bool active;
110284 + uint64_t baseAddr;
110285 + uint32_t memSize;
110286 + t_WrpFmMacDevSettings settings;
110287 + t_Handle h_Dev;
110288 + t_Handle h_LnxWrpFmDev;
110289 +} t_LnxWrpFmMacDev;
110290 +
110291 +/* information about all active ports for an FMan.
110292 + * !Some ports may be disabled by u-boot, thus will not be available */
110293 +struct fm_active_ports {
110294 + uint32_t num_oh_ports;
110295 + uint32_t num_tx_ports;
110296 + uint32_t num_rx_ports;
110297 + uint32_t num_tx25_ports;
110298 + uint32_t num_rx25_ports;
110299 + uint32_t num_tx10_ports;
110300 + uint32_t num_rx10_ports;
110301 +};
110302 +
110303 +/* FMan resources precalculated at fm probe based
110304 + * on available FMan port. */
110305 +struct fm_resource_settings {
110306 + /* buffers - fifo sizes */
110307 + uint32_t tx1g_num_buffers;
110308 + uint32_t rx1g_num_buffers;
110309 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
110310 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
110311 + uint32_t tx10g_num_buffers;
110312 + uint32_t rx10g_num_buffers;
110313 + uint32_t oh_num_buffers;
110314 + uint32_t shared_ext_buffers;
110315 +
110316 + /* open DMAs */
110317 + uint32_t tx_1g_dmas;
110318 + uint32_t rx_1g_dmas;
110319 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
110320 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
110321 + uint32_t tx_10g_dmas;
110322 + uint32_t rx_10g_dmas;
110323 + uint32_t oh_dmas;
110324 + uint32_t shared_ext_open_dma;
110325 +
110326 + /* Tnums */
110327 + uint32_t tx_1g_tnums;
110328 + uint32_t rx_1g_tnums;
110329 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
110330 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
110331 + uint32_t tx_10g_tnums;
110332 + uint32_t rx_10g_tnums;
110333 + uint32_t oh_tnums;
110334 + uint32_t shared_ext_tnums;
110335 +};
110336 +
110337 +typedef struct {
110338 + uint8_t id;
110339 + char name[10];
110340 + bool active;
110341 + bool pcdActive;
110342 + bool prsActive;
110343 + bool kgActive;
110344 + bool ccActive;
110345 + bool plcrActive;
110346 + e_LnxWrpFmPortPcdDefUseCase defPcd;
110347 + uint32_t usedSchemes;
110348 + uint8_t totalNumOfSharedSchemes;
110349 + uint8_t sharedSchemesBase;
110350 + uint8_t numOfSchemesUsed;
110351 + uint8_t defNetEnvId;
110352 + uint64_t fmPhysBaseAddr;
110353 + uint64_t fmBaseAddr;
110354 + uint32_t fmMemSize;
110355 + uint64_t fmMuramPhysBaseAddr;
110356 + uint64_t fmMuramBaseAddr;
110357 + uint32_t fmMuramMemSize;
110358 + uint64_t fmRtcPhysBaseAddr;
110359 + uint64_t fmRtcBaseAddr;
110360 + uint32_t fmRtcMemSize;
110361 + uint64_t fmVspPhysBaseAddr;
110362 + uint64_t fmVspBaseAddr;
110363 + uint32_t fmVspMemSize;
110364 + int irq;
110365 + int err_irq;
110366 + t_WrpFmDevSettings fmDevSettings;
110367 + t_WrpFmPcdDevSettings fmPcdDevSettings;
110368 + t_Handle h_Dev;
110369 + uint16_t hcCh;
110370 +
110371 + t_Handle h_MuramDev;
110372 + t_Handle h_PcdDev;
110373 + t_Handle h_RtcDev;
110374 +
110375 + t_Handle h_DsarRxPort;
110376 + t_Handle h_DsarTxPort;
110377 +
110378 + t_LnxWrpFmPortDev hcPort;
110379 + t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1];
110380 + t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS];
110381 + t_LnxWrpFmPortDev txPorts[FM_MAX_NUM_OF_TX_PORTS];
110382 + t_LnxWrpFmMacDev macs[FM_MAX_NUM_OF_MACS];
110383 + struct fm_active_ports fm_active_ports_info;
110384 + struct fm_resource_settings fm_resource_settings_info;
110385 +
110386 + struct device *dev;
110387 + struct resource *res;
110388 + int major;
110389 + struct class *fm_class;
110390 + struct device_attribute *dev_attr_stats;
110391 + struct device_attribute *dev_attr_regs;
110392 + struct device_attribute *dev_attr_risc_load;
110393 +
110394 + struct device_attribute *dev_pcd_attr_stats;
110395 + struct device_attribute *dev_plcr_attr_regs;
110396 + struct device_attribute *dev_prs_attr_regs;
110397 + struct device_attribute *dev_fm_fpm_attr_regs;
110398 + struct device_attribute *dev_fm_kg_attr_regs;
110399 + struct device_attribute *dev_fm_kg_pe_attr_regs;
110400 + struct device_attribute *dev_attr_muram_free_size;
110401 + struct device_attribute *dev_attr_fm_ctrl_code_ver;
110402 +
110403 +
110404 + struct qman_fq *hc_tx_conf_fq, *hc_tx_err_fq, *hc_tx_fq;
110405 +} t_LnxWrpFmDev;
110406 +
110407 +typedef struct {
110408 + t_LnxWrpFmDev *p_FmDevs[INTG_MAX_NUM_OF_FM];
110409 +} t_LnxWrpFm;
110410 +#define LNXWRP_FM_OBJECT(ptr) LIST_OBJECT(ptr, t_LnxWrpFm, fms[((t_LnxWrpFmDev *)ptr)->id])
110411 +
110412 +
110413 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat);
110414 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat);
110415 +
110416 +
110417 +#if 0
110418 +static __inline__ t_Error AllocSchemesForPort(t_LnxWrpFmDev *p_LnxWrpFmDev, uint8_t numSchemes, uint8_t *p_BaseSchemeNum)
110419 +{
110420 + uint32_t schemeMask;
110421 + uint8_t i;
110422 +
110423 + if (!numSchemes)
110424 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110425 +
110426 + schemeMask = 0x80000000;
110427 + *p_BaseSchemeNum = 0xff;
110428 +
110429 + for (i=0; schemeMask && numSchemes; schemeMask>>=1, i++)
110430 + if ((p_LnxWrpFmDev->usedSchemes & schemeMask) == 0)
110431 + {
110432 + p_LnxWrpFmDev->usedSchemes |= schemeMask;
110433 + numSchemes--;
110434 + if (*p_BaseSchemeNum==0xff)
110435 + *p_BaseSchemeNum = i;
110436 + }
110437 + else if (*p_BaseSchemeNum!=0xff)
110438 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Fragmentation on schemes array!!!"));
110439 +
110440 + if (numSchemes)
110441 + RETURN_ERROR(MINOR, E_FULL, ("schemes!!!"));
110442 + return E_OK;
110443 +}
110444 +#endif
110445 +
110446 +void LnxWrpPCDIOCTLTypeChecking(void);
110447 +void LnxWrpPCDIOCTLEnumChecking(void);
110448 +
110449 +#endif /* __LNXWRP_FM_H__ */
110450 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
110451 new file mode 100644
110452 index 00000000..00ab4bcb
110453 --- /dev/null
110454 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
110455 @@ -0,0 +1,1480 @@
110456 +/*
110457 + * Copyright 2008-2012 Freescale Semiconductor Inc.
110458 + *
110459 + * Redistribution and use in source and binary forms, with or without
110460 + * modification, are permitted provided that the following conditions are met:
110461 + * * Redistributions of source code must retain the above copyright
110462 + * notice, this list of conditions and the following disclaimer.
110463 + * * Redistributions in binary form must reproduce the above copyright
110464 + * notice, this list of conditions and the following disclaimer in the
110465 + * documentation and/or other materials provided with the distribution.
110466 + * * Neither the name of Freescale Semiconductor nor the
110467 + * names of its contributors may be used to endorse or promote products
110468 + * derived from this software without specific prior written permission.
110469 + *
110470 + *
110471 + * ALTERNATIVELY, this software may be distributed under the terms of the
110472 + * GNU General Public License ("GPL") as published by the Free Software
110473 + * Foundation, either version 2 of that License or (at your option) any
110474 + * later version.
110475 + *
110476 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
110477 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
110478 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
110479 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
110480 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
110481 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
110482 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
110483 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
110484 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
110485 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
110486 + */
110487 +
110488 +/*
110489 + @File lnxwrp_fm_port.c
110490 +
110491 + @Description FMD wrapper - FMan port functions.
110492 +
110493 +*/
110494 +
110495 +#include <linux/version.h>
110496 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
110497 +#define MODVERSIONS
110498 +#endif
110499 +#ifdef MODVERSIONS
110500 +#include <config/modversions.h>
110501 +#endif /* MODVERSIONS */
110502 +#include <linux/kernel.h>
110503 +#include <linux/module.h>
110504 +#include <linux/of_platform.h>
110505 +#include <linux/of_address.h>
110506 +#include <linux/cdev.h>
110507 +#include <linux/slab.h>
110508 +#include <linux/spinlock.h>
110509 +#ifndef CONFIG_FMAN_ARM
110510 +#include <linux/fsl/svr.h>
110511 +#endif
110512 +#include <linux/io.h>
110513 +
110514 +#include "sprint_ext.h"
110515 +#include "fm_common.h"
110516 +#include "lnxwrp_fsl_fman.h"
110517 +#include "fm_port_ext.h"
110518 +#if (DPAA_VERSION >= 11)
110519 +#include "fm_vsp_ext.h"
110520 +#endif /* DPAA_VERSION >= 11 */
110521 +#include "fm_ioctls.h"
110522 +#include "lnxwrp_resources.h"
110523 +#include "lnxwrp_sysfs_fm_port.h"
110524 +
110525 +#define __ERR_MODULE__ MODULE_FM
110526 +
110527 +extern struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx);
110528 +
110529 +/* TODO: duplicated, see lnxwrp_fm.c */
110530 +#define ADD_ADV_CONFIG_NO_RET(_func, _param)\
110531 +do {\
110532 + if (i < max) {\
110533 + p_Entry = &p_Entrys[i];\
110534 + p_Entry->p_Function = _func;\
110535 + _param\
110536 + i++;\
110537 + } else {\
110538 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
110539 + ("Number of advanced-configuration entries exceeded"));\
110540 + } \
110541 +} while (0)
110542 +
110543 +#ifndef CONFIG_FMAN_ARM
110544 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
110545 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
110546 +#endif
110547 +
110548 +static volatile int hcFrmRcv/* = 0 */;
110549 +static spinlock_t lock;
110550 +
110551 +static enum qman_cb_dqrr_result qm_tx_conf_dqrr_cb(struct qman_portal *portal,
110552 + struct qman_fq *fq,
110553 + const struct qm_dqrr_entry
110554 + *dq)
110555 +{
110556 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_FmTestFq *) fq)->h_Arg;
110557 + unsigned long flags;
110558 +
110559 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
110560 +{
110561 + /* extract the HC frame address */
110562 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *)&dq->fd));
110563 + int hcf_l = ((struct qm_fd *)&dq->fd)->length20;
110564 + int i;
110565 +
110566 + /* 32b byteswap of all data in the HC Frame */
110567 + for(i = 0; i < hcf_l / 4; ++i)
110568 + hcf_va[i] =
110569 + ___constant_swab32(hcf_va[i]);
110570 +}
110571 +#endif
110572 + FM_PCD_HcTxConf(p_LnxWrpFmDev->h_PcdDev, (t_DpaaFD *)&dq->fd);
110573 + spin_lock_irqsave(&lock, flags);
110574 + hcFrmRcv--;
110575 + spin_unlock_irqrestore(&lock, flags);
110576 +
110577 + return qman_cb_dqrr_consume;
110578 +}
110579 +
110580 +static enum qman_cb_dqrr_result qm_tx_dqrr_cb(struct qman_portal *portal,
110581 + struct qman_fq *fq,
110582 + const struct qm_dqrr_entry *dq)
110583 +{
110584 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
110585 + __func__);
110586 + return qman_cb_dqrr_consume;
110587 +}
110588 +
110589 +static void qm_err_cb(struct qman_portal *portal,
110590 + struct qman_fq *fq, const struct qm_mr_entry *msg)
110591 +{
110592 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
110593 + __func__);
110594 +}
110595 +
110596 +static struct qman_fq *FqAlloc(t_LnxWrpFmDev * p_LnxWrpFmDev,
110597 + uint32_t fqid,
110598 + uint32_t flags, uint16_t channel, uint8_t wq)
110599 +{
110600 + int _errno;
110601 + struct qman_fq *fq = NULL;
110602 + t_FmTestFq *p_FmtFq;
110603 + struct qm_mcc_initfq initfq;
110604 +
110605 + p_FmtFq = (t_FmTestFq *) XX_Malloc(sizeof(t_FmTestFq));
110606 + if (!p_FmtFq) {
110607 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
110608 + return NULL;
110609 + }
110610 +
110611 + p_FmtFq->fq_base.cb.dqrr = ((flags & QMAN_FQ_FLAG_NO_ENQUEUE)
110612 + ? qm_tx_conf_dqrr_cb
110613 + : qm_tx_dqrr_cb);
110614 + p_FmtFq->fq_base.cb.ern = qm_err_cb;
110615 + /* p_FmtFq->fq_base.cb.fqs = qm_err_cb; */
110616 + /* qm_err_cb wrongly called when the FQ is parked */
110617 + p_FmtFq->fq_base.cb.fqs = NULL;
110618 + p_FmtFq->h_Arg = (t_Handle) p_LnxWrpFmDev;
110619 + if (fqid == 0) {
110620 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
110621 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
110622 + } else {
110623 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
110624 + }
110625 +
110626 + if (qman_create_fq(fqid, flags, &p_FmtFq->fq_base)) {
110627 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj - qman_new_fq!!!"));
110628 + XX_Free(p_FmtFq);
110629 + return NULL;
110630 + }
110631 + fq = &p_FmtFq->fq_base;
110632 +
110633 + if (!(flags & QMAN_FQ_FLAG_NO_MODIFY)) {
110634 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
110635 + initfq.fqd.dest.channel = channel;
110636 + initfq.fqd.dest.wq = wq;
110637 +
110638 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
110639 + if (unlikely(_errno < 0)) {
110640 + REPORT_ERROR(MAJOR, E_NO_MEMORY,
110641 + ("FQ obj - qman_init_fq!!!"));
110642 + qman_destroy_fq(fq, 0);
110643 + XX_Free(p_FmtFq);
110644 + return NULL;
110645 + }
110646 + }
110647 +
110648 + DBG(TRACE,
110649 + ("fqid %d, flags 0x%08x, channel %d, wq %d", qman_fq_fqid(fq),
110650 + flags, channel, wq));
110651 +
110652 + return fq;
110653 +}
110654 +
110655 +static void FqFree(struct qman_fq *fq)
110656 +{
110657 + int _errno;
110658 +
110659 + _errno = qman_retire_fq(fq, NULL);
110660 + if (unlikely(_errno < 0))
110661 + printk(KERN_WARNING "qman_retire_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
110662 +
110663 + _errno = qman_oos_fq(fq);
110664 + if (unlikely(_errno < 0))
110665 + printk(KERN_WARNING "qman_oos_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
110666 +
110667 + qman_destroy_fq(fq, 0);
110668 + XX_Free((t_FmTestFq *) fq);
110669 +}
110670 +
110671 +static t_Error QmEnqueueCB(t_Handle h_Arg, void *p_Fd)
110672 +{
110673 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_Arg;
110674 + int _errno, timeout = 1000000;
110675 + unsigned long flags;
110676 +
110677 + ASSERT_COND(p_LnxWrpFmDev);
110678 +
110679 + spin_lock_irqsave(&lock, flags);
110680 + hcFrmRcv++;
110681 + spin_unlock_irqrestore(&lock, flags);
110682 +
110683 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
110684 +{
110685 + /* extract the HC frame address */
110686 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *) p_Fd));
110687 + int hcf_l = ((struct qm_fd *)p_Fd)->length20;
110688 + int i;
110689 +
110690 + /* 32b byteswap of all data in the HC Frame */
110691 + for(i = 0; i < hcf_l / 4; ++i)
110692 + hcf_va[i] =
110693 + ___constant_swab32(hcf_va[i]);
110694 +}
110695 +#endif
110696 +
110697 + _errno = qman_enqueue(p_LnxWrpFmDev->hc_tx_fq, (struct qm_fd *) p_Fd,
110698 + 0);
110699 + if (_errno)
110700 + RETURN_ERROR(MINOR, E_INVALID_STATE,
110701 + ("qman_enqueue() failed"));
110702 +
110703 + while (hcFrmRcv && --timeout) {
110704 + udelay(1);
110705 + cpu_relax();
110706 + }
110707 + if (timeout == 0) {
110708 + dump_stack();
110709 + RETURN_ERROR(MINOR, E_WRITE_FAILED,
110710 + ("timeout waiting for Tx confirmation"));
110711 + return E_WRITE_FAILED;
110712 + }
110713 +
110714 + return E_OK;
110715 +}
110716 +
110717 +static t_LnxWrpFmPortDev *ReadFmPortDevTreeNode(struct platform_device
110718 + *of_dev)
110719 +{
110720 + t_LnxWrpFmDev *p_LnxWrpFmDev;
110721 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
110722 + struct device_node *fm_node, *port_node;
110723 + struct resource res;
110724 + const uint32_t *uint32_prop;
110725 + int _errno = 0, lenp;
110726 + uint32_t tmp_prop;
110727 +
110728 +#ifdef CONFIG_FMAN_P1023
110729 + static unsigned char have_oh_port/* = 0 */;
110730 +#endif
110731 +
110732 + port_node = of_node_get(of_dev->dev.of_node);
110733 +
110734 + /* Get the FM node */
110735 + fm_node = of_get_parent(port_node);
110736 + if (unlikely(fm_node == NULL)) {
110737 + REPORT_ERROR(MAJOR, E_NO_DEVICE,
110738 + ("of_get_parent() = %d", _errno));
110739 + return NULL;
110740 + }
110741 +
110742 + p_LnxWrpFmDev =
110743 + dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
110744 + of_node_put(fm_node);
110745 +
110746 + /* if fm_probe() failed, no point in going further with port probing */
110747 + if (p_LnxWrpFmDev == NULL)
110748 + return NULL;
110749 +
110750 + uint32_prop =
110751 + (uint32_t *) of_get_property(port_node, "cell-index", &lenp);
110752 + if (unlikely(uint32_prop == NULL)) {
110753 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110754 + ("of_get_property(%s, cell-index) failed",
110755 + port_node->full_name));
110756 + return NULL;
110757 + }
110758 + tmp_prop = be32_to_cpu(*uint32_prop);
110759 + if (WARN_ON(lenp != sizeof(uint32_t)))
110760 + return NULL;
110761 + if (of_device_is_compatible(port_node, "fsl,fman-port-oh")) {
110762 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) {
110763 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110764 + ("of_get_property(%s, cell-index) failed",
110765 + port_node->full_name));
110766 + return NULL;
110767 + }
110768 +
110769 +#ifdef CONFIG_FMAN_P1023
110770 + /* Beware, this can be done when there is only
110771 + one FMan to be initialized */
110772 + if (!have_oh_port) {
110773 + have_oh_port = 1; /* first OP/HC port
110774 + is used for host command */
110775 +#else
110776 + /* Here it is hardcoded the use of the OH port 1
110777 + (with cell-index 0) */
110778 + if (tmp_prop == 0) {
110779 +#endif
110780 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
110781 + p_LnxWrpFmPortDev->id = 0;
110782 + /*
110783 + p_LnxWrpFmPortDev->id = *uint32_prop-1;
110784 + p_LnxWrpFmPortDev->id = *uint32_prop;
110785 + */
110786 + p_LnxWrpFmPortDev->settings.param.portType =
110787 + e_FM_PORT_TYPE_OH_HOST_COMMAND;
110788 + } else {
110789 + p_LnxWrpFmPortDev =
110790 + &p_LnxWrpFmDev->opPorts[tmp_prop - 1];
110791 + p_LnxWrpFmPortDev->id = tmp_prop- 1;
110792 + p_LnxWrpFmPortDev->settings.param.portType =
110793 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
110794 + }
110795 + p_LnxWrpFmPortDev->settings.param.portId = tmp_prop;
110796 +
110797 + uint32_prop =
110798 + (uint32_t *) of_get_property(port_node,
110799 + "fsl,qman-channel-id",
110800 + &lenp);
110801 + if (uint32_prop == NULL) {
110802 + /*
110803 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("missing fsl,qman-channel-id"));
110804 + */
110805 + XX_Print("FM warning: missing fsl,qman-channel-id"
110806 + " for OH port.\n");
110807 + return NULL;
110808 + }
110809 + tmp_prop = be32_to_cpu(*uint32_prop);
110810 + if (WARN_ON(lenp != sizeof(uint32_t)))
110811 + return NULL;
110812 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110813 +
110814 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110815 + qmChannel = p_LnxWrpFmPortDev->txCh;
110816 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) {
110817 + tmp_prop -= 0x28;
110818 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_TX_PORTS)) {
110819 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110820 + ("of_get_property(%s, cell-index) failed",
110821 + port_node->full_name));
110822 + return NULL;
110823 + }
110824 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
110825 +
110826 + p_LnxWrpFmPortDev->id = tmp_prop;
110827 + p_LnxWrpFmPortDev->settings.param.portId =
110828 + p_LnxWrpFmPortDev->id;
110829 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_TX;
110830 +
110831 + uint32_prop = (uint32_t *) of_get_property(port_node,
110832 + "fsl,qman-channel-id", &lenp);
110833 + if (uint32_prop == NULL) {
110834 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110835 + ("missing fsl,qman-channel-id"));
110836 + return NULL;
110837 + }
110838 + tmp_prop = be32_to_cpu(*uint32_prop);
110839 + if (WARN_ON(lenp != sizeof(uint32_t)))
110840 + return NULL;
110841 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110842 + p_LnxWrpFmPortDev->
110843 + settings.param.specificParams.nonRxParams.qmChannel =
110844 + p_LnxWrpFmPortDev->txCh;
110845 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) {
110846 + tmp_prop -= 0x30;
110847 + if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) {
110848 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110849 + ("of_get_property(%s, cell-index) failed",
110850 + port_node->full_name));
110851 + return NULL;
110852 + }
110853 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop +
110854 + FM_MAX_NUM_OF_1G_TX_PORTS];
110855 +#ifndef CONFIG_FMAN_ARM
110856 + if (IS_T1023_T1024)
110857 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[*uint32_prop];
110858 +#endif
110859 +
110860 + p_LnxWrpFmPortDev->id = tmp_prop;
110861 + p_LnxWrpFmPortDev->settings.param.portId =
110862 + p_LnxWrpFmPortDev->id;
110863 + p_LnxWrpFmPortDev->settings.param.portType =
110864 + e_FM_PORT_TYPE_TX_10G;
110865 + uint32_prop = (uint32_t *) of_get_property(port_node,
110866 + "fsl,qman-channel-id", &lenp);
110867 + if (uint32_prop == NULL) {
110868 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110869 + ("missing fsl,qman-channel-id"));
110870 + return NULL;
110871 + }
110872 + tmp_prop = be32_to_cpu(*uint32_prop);
110873 + if (WARN_ON(lenp != sizeof(uint32_t)))
110874 + return NULL;
110875 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110876 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110877 + qmChannel = p_LnxWrpFmPortDev->txCh;
110878 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) {
110879 + tmp_prop -= 0x08;
110880 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_RX_PORTS)) {
110881 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110882 + ("of_get_property(%s, cell-index) failed",
110883 + port_node->full_name));
110884 + return NULL;
110885 + }
110886 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
110887 +
110888 + p_LnxWrpFmPortDev->id = tmp_prop;
110889 + p_LnxWrpFmPortDev->settings.param.portId =
110890 + p_LnxWrpFmPortDev->id;
110891 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_RX;
110892 + if (p_LnxWrpFmDev->pcdActive)
110893 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110894 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) {
110895 + tmp_prop -= 0x10;
110896 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) {
110897 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110898 + ("of_get_property(%s, cell-index) failed",
110899 + port_node->full_name));
110900 + return NULL;
110901 + }
110902 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop +
110903 + FM_MAX_NUM_OF_1G_RX_PORTS];
110904 +
110905 +#ifndef CONFIG_FMAN_ARM
110906 + if (IS_T1023_T1024)
110907 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[*uint32_prop];
110908 +#endif
110909 +
110910 + p_LnxWrpFmPortDev->id = tmp_prop;
110911 + p_LnxWrpFmPortDev->settings.param.portId =
110912 + p_LnxWrpFmPortDev->id;
110913 + p_LnxWrpFmPortDev->settings.param.portType =
110914 + e_FM_PORT_TYPE_RX_10G;
110915 + if (p_LnxWrpFmDev->pcdActive)
110916 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110917 + } else {
110918 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
110919 + return NULL;
110920 + }
110921 +
110922 + _errno = of_address_to_resource(port_node, 0, &res);
110923 + if (unlikely(_errno < 0)) {
110924 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110925 + ("of_address_to_resource() = %d", _errno));
110926 + return NULL;
110927 + }
110928 +
110929 + p_LnxWrpFmPortDev->dev = &of_dev->dev;
110930 + p_LnxWrpFmPortDev->baseAddr = 0;
110931 + p_LnxWrpFmPortDev->phys_baseAddr = res.start;
110932 + p_LnxWrpFmPortDev->memSize = res.end + 1 - res.start;
110933 + p_LnxWrpFmPortDev->settings.param.h_Fm = p_LnxWrpFmDev->h_Dev;
110934 + p_LnxWrpFmPortDev->h_LnxWrpFmDev = (t_Handle) p_LnxWrpFmDev;
110935 +
110936 + of_node_put(port_node);
110937 +
110938 + p_LnxWrpFmPortDev->active = TRUE;
110939 +
110940 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
110941 + /* for performance mode no OH port available. */
110942 + if (p_LnxWrpFmPortDev->settings.param.portType ==
110943 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
110944 + p_LnxWrpFmPortDev->active = FALSE;
110945 +#endif
110946 +
110947 + return p_LnxWrpFmPortDev;
110948 +}
110949 +
110950 +struct device_node * GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
110951 + e_FmPortType portType,
110952 + uint8_t portId)
110953 +{
110954 + struct device_node *port_node;
110955 + const uint32_t *uint32_prop;
110956 + int lenp;
110957 + char *portTypeString;
110958 + uint32_t tmp_prop;
110959 +
110960 + switch(portType) {
110961 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
110962 + portTypeString = "fsl,fman-port-op-extended-args";
110963 + break;
110964 + case e_FM_PORT_TYPE_TX:
110965 + portTypeString = "fsl,fman-port-1g-tx-extended-args";
110966 + break;
110967 + case e_FM_PORT_TYPE_TX_10G:
110968 + portTypeString = "fsl,fman-port-10g-tx-extended-args";
110969 + break;
110970 + case e_FM_PORT_TYPE_RX:
110971 + portTypeString = "fsl,fman-port-1g-rx-extended-args";
110972 + break;
110973 + case e_FM_PORT_TYPE_RX_10G:
110974 + portTypeString = "fsl,fman-port-10g-rx-extended-args";
110975 + break;
110976 + default:
110977 + return NULL;
110978 + }
110979 +
110980 + for_each_child_of_node(fm_node, port_node) {
110981 + uint32_prop = (uint32_t *)of_get_property(port_node, "cell-index", &lenp);
110982 + if (unlikely(uint32_prop == NULL)) {
110983 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110984 + ("of_get_property(%s, cell-index) failed",
110985 + port_node->full_name));
110986 + return NULL;
110987 + }
110988 + tmp_prop = be32_to_cpu(*uint32_prop);
110989 + if (WARN_ON(lenp != sizeof(uint32_t)))
110990 + return NULL;
110991 + if ((portId == tmp_prop) &&
110992 + (of_device_is_compatible(port_node, portTypeString))) {
110993 + return port_node;
110994 + }
110995 + }
110996 +
110997 + return NULL;
110998 +}
110999 +
111000 +static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111001 +{
111002 + struct device_node *fm_node, *port_node;
111003 + t_Error err;
111004 + t_FmPortRsrc portRsrc;
111005 + const uint32_t *uint32_prop;
111006 + /*const char *str_prop;*/
111007 + int lenp;
111008 +#ifdef CONFIG_FMAN_PFC
111009 + uint8_t i, id, num_pools;
111010 + t_FmBufPoolDepletion poolDepletion;
111011 +
111012 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
111013 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) {
111014 + memset(&poolDepletion, 0, sizeof(t_FmBufPoolDepletion));
111015 + poolDepletion.singlePoolModeEnable = true;
111016 + num_pools = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
111017 + extBufPools.numOfPoolsUsed;
111018 + for (i = 0; i < num_pools; i++) {
111019 + id = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
111020 + extBufPools.extBufPool[i].id;
111021 + poolDepletion.poolsToConsiderForSingleMode[id] = true;
111022 + }
111023 +
111024 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++)
111025 + poolDepletion.pfcPrioritiesEn[i] = true;
111026 +
111027 + err = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev,
111028 + &poolDepletion);
111029 + if (err != E_OK)
111030 + RETURN_ERROR(MAJOR, err, ("FM_PORT_ConfigPoolDepletion() failed"));
111031 + }
111032 +#endif
111033 +
111034 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
111035 + if (!fm_node) /* no advance parameters for FMan */
111036 + return E_OK;
111037 +
111038 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
111039 + p_LnxWrpFmPortDev->settings.param.portType,
111040 + p_LnxWrpFmPortDev->settings.param.portId);
111041 + if (!port_node) /* no advance parameters for FMan-Port */
111042 + return E_OK;
111043 +
111044 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-tnums", &lenp);
111045 + if (uint32_prop) {
111046 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
111047 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
111048 +
111049 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
111050 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
111051 +
111052 + if ((err = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev,
111053 + &portRsrc)) != E_OK)
111054 + RETURN_ERROR(MINOR, err, NO_MSG);
111055 + }
111056 +
111057 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-dmas", &lenp);
111058 + if (uint32_prop) {
111059 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
111060 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
111061 +
111062 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
111063 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
111064 +
111065 + if ((err = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev,
111066 + &portRsrc)) != E_OK)
111067 + RETURN_ERROR(MINOR, err, NO_MSG);
111068 + }
111069 +
111070 + uint32_prop = (uint32_t *)of_get_property(port_node, "fifo-size", &lenp);
111071 + if (uint32_prop) {
111072 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
111073 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
111074 +
111075 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
111076 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
111077 +
111078 + if ((err = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev,
111079 + &portRsrc)) != E_OK)
111080 + RETURN_ERROR(MINOR, err, NO_MSG);
111081 + }
111082 +
111083 + uint32_prop = (uint32_t *)of_get_property(port_node, "errors-to-discard", &lenp);
111084 + if (uint32_prop) {
111085 + if (WARN_ON(lenp != sizeof(uint32_t)))
111086 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
111087 + if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev,
111088 + be32_to_cpu(uint32_prop[0]))) != E_OK)
111089 + RETURN_ERROR(MINOR, err, NO_MSG);
111090 + }
111091 +
111092 + uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes",
111093 + &lenp);
111094 + if (uint32_prop) {
111095 +
111096 + if (WARN_ON(lenp != sizeof(uint32_t)*8))
111097 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
111098 + if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType !=
111099 + e_FM_PORT_TYPE_RX) &&
111100 + (p_LnxWrpFmPortDev->settings.param.portType !=
111101 + e_FM_PORT_TYPE_RX_10G))
111102 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
111103 + ("Auto Response is an Rx port atribute."));
111104 +
111105 + memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes));
111106 +
111107 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries =
111108 + (uint16_t)be32_to_cpu(uint32_prop[0]);
111109 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries =
111110 + (uint16_t)be32_to_cpu(uint32_prop[1]);
111111 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries =
111112 + (uint16_t)be32_to_cpu(uint32_prop[2]);
111113 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries =
111114 + (uint16_t)be32_to_cpu(uint32_prop[3]);
111115 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries =
111116 + (uint16_t)be32_to_cpu(uint32_prop[4]);
111117 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries =
111118 + (uint16_t)be32_to_cpu(uint32_prop[5]);
111119 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries =
111120 + (uint16_t)be32_to_cpu(uint32_prop[6]);
111121 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char =
111122 + (uint16_t)be32_to_cpu(uint32_prop[7]);
111123 +
111124 + uint32_prop = (uint32_t *)of_get_property(port_node,
111125 + "ar-filters-sizes", &lenp);
111126 + if (uint32_prop) {
111127 + if (WARN_ON(lenp != sizeof(uint32_t)*3))
111128 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
111129 +
111130 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering =
111131 + (uint16_t)be32_to_cpu(uint32_prop[0]);
111132 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering =
111133 + (uint16_t)be32_to_cpu(uint32_prop[1]);
111134 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering =
111135 + (uint16_t)be32_to_cpu(uint32_prop[2]);
111136 + }
111137 +
111138 + if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev,
111139 + (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK)
111140 + RETURN_ERROR(MINOR, err, NO_MSG);
111141 + }
111142 +
111143 + of_node_put(port_node);
111144 + of_node_put(fm_node);
111145 +
111146 + return E_OK;
111147 +}
111148 +
111149 +static t_Error CheckNSetFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111150 +{
111151 + struct device_node *fm_node, *port_node;
111152 + t_Error err;
111153 + const uint32_t *uint32_prop;
111154 + /*const char *str_prop;*/
111155 + int lenp;
111156 +
111157 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
111158 + if (!fm_node) /* no advance parameters for FMan */
111159 + return E_OK;
111160 +
111161 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
111162 + p_LnxWrpFmPortDev->settings.param.portType,
111163 + p_LnxWrpFmPortDev->settings.param.portId);
111164 + if (!port_node) /* no advance parameters for FMan-Port */
111165 + return E_OK;
111166 +
111167 +#if (DPAA_VERSION >= 11)
111168 + uint32_prop = (uint32_t *)of_get_property(port_node, "vsp-window", &lenp);
111169 + if (uint32_prop) {
111170 + t_FmPortVSPAllocParams portVSPAllocParams;
111171 + t_FmVspParams fmVspParams;
111172 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111173 + uint8_t portId;
111174 +
111175 + p_LnxWrpFmDev = ((t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev);
111176 +
111177 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
111178 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
111179 +
111180 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) ||
111181 + (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX_10G) ||
111182 + ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
111183 + p_LnxWrpFmPortDev->settings.frag_enabled))
111184 + return E_OK;
111185 +
111186 + memset(&portVSPAllocParams, 0, sizeof(portVSPAllocParams));
111187 + memset(&fmVspParams, 0, sizeof(fmVspParams));
111188 +
111189 + portVSPAllocParams.numOfProfiles = (uint8_t)be32_to_cpu(uint32_prop[0]);
111190 + portVSPAllocParams.dfltRelativeId = (uint8_t)be32_to_cpu(uint32_prop[1]);
111191 + fmVspParams.h_Fm = p_LnxWrpFmDev->h_Dev;
111192 +
111193 + fmVspParams.portParams.portType = p_LnxWrpFmPortDev->settings.param.portType;
111194 + fmVspParams.portParams.portId = p_LnxWrpFmPortDev->settings.param.portId;
111195 + fmVspParams.relativeProfileId = portVSPAllocParams.dfltRelativeId;
111196 +
111197 + if (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
111198 + {
111199 + portId = fmVspParams.portParams.portId;
111200 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G){
111201 +#ifndef CONFIG_FMAN_ARM
111202 + if (!(IS_T1023_T1024))
111203 +#endif
111204 + portId += FM_MAX_NUM_OF_1G_RX_PORTS;
111205 + }
111206 + portVSPAllocParams.h_FmTxPort =
111207 + p_LnxWrpFmDev->txPorts[portId].h_Dev;
111208 + fmVspParams.liodnOffset =
111209 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
111210 + memcpy(&fmVspParams.extBufPools,
111211 + &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools,
111212 + sizeof(t_FmExtPools));
111213 + }
111214 + else
111215 + {
111216 + memcpy(&fmVspParams.extBufPools,
111217 + &p_LnxWrpFmPortDev->opExtPools,
111218 + sizeof(t_FmExtPools));
111219 + }
111220 +
111221 + if ((err = FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev,
111222 + &portVSPAllocParams)) != E_OK)
111223 + RETURN_ERROR(MINOR, err, NO_MSG);
111224 +
111225 + /* We're initializing only the default VSP that are being used by the Linux-Ethernet-driver */
111226 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
111227 + !p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed)
111228 + return E_OK;
111229 +
111230 + p_LnxWrpFmPortDev->h_DfltVsp = FM_VSP_Config(&fmVspParams);
111231 + if (!p_LnxWrpFmPortDev->h_DfltVsp)
111232 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("default-VSP for port!"));
111233 +
111234 + if ((err = FM_VSP_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_DfltVsp,
111235 + &p_LnxWrpFmPortDev->buffPrefixContent)) != E_OK)
111236 + RETURN_ERROR(MINOR, err, NO_MSG);
111237 +
111238 + if ((err = FM_VSP_Init(p_LnxWrpFmPortDev->h_DfltVsp)) != E_OK)
111239 + RETURN_ERROR(MINOR, err, NO_MSG);
111240 + }
111241 +#else
111242 +UNUSED(err); UNUSED(uint32_prop); UNUSED(lenp);
111243 +#endif /* (DPAA_VERSION >= 11) */
111244 +
111245 + of_node_put(port_node);
111246 + of_node_put(fm_node);
111247 +
111248 + return E_OK;
111249 +}
111250 +
111251 +static t_Error ConfigureFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111252 +{
111253 + t_LnxWrpFmDev *p_LnxWrpFmDev =
111254 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111255 + struct resource *dev_res;
111256 +
111257 + if (!p_LnxWrpFmPortDev->active)
111258 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
111259 + ("FM port not configured!!!"));
111260 +
111261 + dev_res =
111262 + __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
111263 + p_LnxWrpFmPortDev->phys_baseAddr,
111264 + p_LnxWrpFmPortDev->memSize,
111265 + "fman-port-hc");
111266 + if (unlikely(dev_res == NULL))
111267 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
111268 + ("__devm_request_region() failed"));
111269 + p_LnxWrpFmPortDev->baseAddr =
111270 + PTR_TO_UINT(devm_ioremap
111271 + (p_LnxWrpFmDev->dev,
111272 + p_LnxWrpFmPortDev->phys_baseAddr,
111273 + p_LnxWrpFmPortDev->memSize));
111274 + if (unlikely(p_LnxWrpFmPortDev->baseAddr == 0))
111275 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
111276 + ("devm_ioremap() failed"));
111277 +
111278 + p_LnxWrpFmPortDev->settings.param.baseAddr =
111279 + p_LnxWrpFmPortDev->baseAddr;
111280 +
111281 + return E_OK;
111282 +}
111283 +
111284 +static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111285 +{
111286 +#define MY_ADV_CONFIG_CHECK_END \
111287 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,\
111288 + ("Advanced configuration routine"));\
111289 + if (errCode != E_OK)\
111290 + RETURN_ERROR(MAJOR, errCode, NO_MSG);\
111291 + }
111292 +
111293 + int i = 0;
111294 +
111295 + if (!p_LnxWrpFmPortDev->active || p_LnxWrpFmPortDev->h_Dev)
111296 + return E_INVALID_STATE;
111297 +
111298 + p_LnxWrpFmPortDev->h_Dev =
111299 + FM_PORT_Config(&p_LnxWrpFmPortDev->settings.param);
111300 + if (p_LnxWrpFmPortDev->h_Dev == NULL)
111301 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-port"));
111302 +
111303 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
111304 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111305 + e_FM_PORT_TYPE_TX_10G)
111306 + || (p_LnxWrpFmPortDev->settings.param.portType ==
111307 + e_FM_PORT_TYPE_TX)) {
111308 + t_Error errCode = E_OK;
111309 + errCode =
111310 + FM_PORT_ConfigDeqHighPriority(p_LnxWrpFmPortDev->h_Dev,
111311 + TRUE);
111312 + if (errCode != E_OK)
111313 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
111314 + errCode =
111315 + FM_PORT_ConfigDeqPrefetchOption(p_LnxWrpFmPortDev->h_Dev,
111316 + e_FM_PORT_DEQ_FULL_PREFETCH);
111317 + if (errCode
111318 + != E_OK)
111319 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
111320 + }
111321 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
111322 +
111323 +#ifndef CONFIG_FMAN_ARM
111324 +#ifdef FM_BCB_ERRATA_BMI_SW001
111325 +/* Configure BCB workaround on Rx ports, only for B4860 rev1 */
111326 +#define SVR_SECURITY_MASK 0x00080000
111327 +#define SVR_PERSONALITY_MASK 0x0000FF00
111328 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
111329 +#define SVR_B4860_REV1_VALUE 0x86800010
111330 +
111331 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111332 + e_FM_PORT_TYPE_RX_10G) ||
111333 + (p_LnxWrpFmPortDev->settings.param.portType ==
111334 + e_FM_PORT_TYPE_RX)) {
111335 + unsigned int svr;
111336 +
111337 + svr = mfspr(SPRN_SVR);
111338 +
111339 + if ((svr & ~SVR_VER_IGNORE_MASK) == SVR_B4860_REV1_VALUE)
111340 + FM_PORT_ConfigBCBWorkaround(p_LnxWrpFmPortDev->h_Dev);
111341 + }
111342 +#endif /* FM_BCB_ERRATA_BMI_SW001 */
111343 +#endif /* CONFIG_FMAN_ARM */
111344 +/* Call the driver's advanced configuration routines, if requested:
111345 + Compare the function pointer of each entry to the available routines,
111346 + and invoke the matching routine with proper casting of arguments. */
111347 + while (p_LnxWrpFmPortDev->settings.advConfig[i].p_Function
111348 + && (i < FM_MAX_NUM_OF_ADV_SETTINGS)) {
111349 +
111350 +/* TODO: Change this MACRO */
111351 + ADV_CONFIG_CHECK_START(
111352 + &(p_LnxWrpFmPortDev->settings.advConfig[i]))
111353 +
111354 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
111355 + FM_PORT_ConfigBufferPrefixContent,
111356 + NCSW_PARAMS(1,
111357 + (t_FmBufferPrefixContent *)))
111358 +
111359 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111360 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
111361 + (p_LnxWrpFmPortDev->settings.frag_enabled == TRUE)) {
111362 +
111363 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
111364 + FM_PORT_ConfigExtBufPools,
111365 + NCSW_PARAMS(1, (t_FmExtPools *)))
111366 +
111367 + /* this define contains an else */
111368 + MY_ADV_CONFIG_CHECK_END
111369 + }
111370 +
111371 + /* Advance to next advanced configuration entry */
111372 + i++;
111373 + }
111374 +
111375 +
111376 + if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) &&
111377 + (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) {
111378 + if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE |
111379 + FM_PORT_FRM_ERR_IPR_NCSP |
111380 + FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK)
111381 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111382 + }
111383 +
111384 + if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
111385 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111386 +
111387 + if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != E_OK)
111388 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111389 +
111390 + if (CheckNSetFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
111391 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111392 +
111393 +/* FMan Fifo sizes behind the scene":
111394 + * Using the following formulae (*), under a set of simplifying assumptions (.):
111395 + * . all ports are configured in Normal Mode (rather than Independent Mode)
111396 + * . the DPAA Eth driver allocates buffers of size:
111397 + * . MAXFRM + NET_IP_ALIGN + DPA_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE
111398 + * + DPA_HASH_RESULTS_SIZE, i.e.:
111399 + * MAXFRM + 2 + 16 + sizeof(t_FmPrsResult) + 16, i.e.:
111400 + * MAXFRM + 66
111401 + * . excessive buffer pools not accounted for
111402 + *
111403 + * * for Rx ports on P4080:
111404 + * . IFSZ = ceil(max(FMBM_EBMPI[PBS]) / 256) * 256 + 7 * 256
111405 + * . no internal frame offset (FMBM_RIM[FOF] == 0) - otherwise,
111406 + * add up to 256 to the above
111407 + *
111408 + * * for Rx ports on P1023:
111409 + * . IFSZ = ceil(second_largest(FMBM_EBMPI[PBS] / 256)) * 256 + 7 * 256,
111410 + * if at least 2 bpools are configured
111411 + * . IFSZ = 8 * 256, if only a single bpool is configured
111412 + *
111413 + * * for Tx ports:
111414 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256
111415 + * + FMBM_TFP[DPDE] * 256, i.e.:
111416 + * IFSZ = ceil(MAXFRM / 256) * 256 + 3 x 256 + FMBM_TFP[DPDE] * 256
111417 + *
111418 + * * for OH ports on P4080:
111419 + * . IFSZ = ceil(frame_size / 256) * 256 + 1 * 256 + FMBM_PP[MXT] * 256
111420 + * * for OH ports on P1023:
111421 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 + FMBM_TFP[DPDE] * 256
111422 + * * for both P4080 and P1023:
111423 + * . (conservative decisions, assuming that BMI must bring the entire
111424 + * frame, not only the frame header)
111425 + * . no internal frame offset (FMBM_OIM[FOF] == 0) - otherwise,
111426 + * add up to 256 to the above
111427 + *
111428 + * . for P4080/P5020/P3041/P2040, DPDE is:
111429 + * > 0 or 1, for 1Gb ports, HW default: 0
111430 + * > 2..7 (recommended: 3..7) for 10Gb ports, HW default: 3
111431 + * . for P1023, DPDE should be 1
111432 + *
111433 + * . for P1023, MXT is in range (0..31)
111434 + * . for P4080, MXT is in range (0..63)
111435 + *
111436 + */
111437 +#if 0
111438 + if ((p_LnxWrpFmPortDev->defPcd != e_NO_PCD) &&
111439 + (InitFmPort3TupleDefPcd(p_LnxWrpFmPortDev) != E_OK))
111440 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111441 +#endif
111442 + return E_OK;
111443 +}
111444 +
111445 +void fm_set_rx_port_params(struct fm_port *port,
111446 + struct fm_port_params *params)
111447 +{
111448 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
111449 + int i;
111450 +
111451 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid =
111452 + params->errq;
111453 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.dfltFqid =
111454 + params->defq;
111455 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
111456 + numOfPoolsUsed = params->num_pools;
111457 + for (i = 0; i < params->num_pools; i++) {
111458 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
111459 + extBufPools.extBufPool[i].id =
111460 + params->pool_param[i].id;
111461 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
111462 + extBufPools.extBufPool[i].size =
111463 + params->pool_param[i].size;
111464 + }
111465 +
111466 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
111467 + params->priv_data_size;
111468 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
111469 + params->parse_results;
111470 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
111471 + params->hash_results;
111472 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
111473 + params->time_stamp;
111474 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
111475 + params->data_align;
111476 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
111477 + params->manip_extra_space;
111478 +
111479 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
111480 + FM_MAX_NUM_OF_ADV_SETTINGS)
111481 +
111482 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
111483 + ARGS(1,
111484 + (&p_LnxWrpFmPortDev->
111485 + buffPrefixContent)));
111486 +
111487 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
111488 +}
111489 +EXPORT_SYMBOL(fm_set_rx_port_params);
111490 +
111491 +/* this function is called from oh_probe as well, thus it contains oh port
111492 + * specific parameters (make sure everything is checked) */
111493 +void fm_set_tx_port_params(struct fm_port *port,
111494 + struct fm_port_params *params)
111495 +{
111496 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
111497 +
111498 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.errFqid =
111499 + params->errq;
111500 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
111501 + dfltFqid = params->defq;
111502 +
111503 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
111504 + params->priv_data_size;
111505 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
111506 + params->parse_results;
111507 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
111508 + params->hash_results;
111509 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
111510 + params->time_stamp;
111511 + p_LnxWrpFmPortDev->settings.frag_enabled =
111512 + params->frag_enable;
111513 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
111514 + params->data_align;
111515 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
111516 + params->manip_extra_space;
111517 +
111518 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
111519 + FM_MAX_NUM_OF_ADV_SETTINGS)
111520 +
111521 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
111522 + ARGS(1,
111523 + (&p_LnxWrpFmPortDev->
111524 + buffPrefixContent)));
111525 +
111526 + /* oh port specific parameter (for fragmentation only) */
111527 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111528 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
111529 + params->num_pools) {
111530 + int i;
111531 +
111532 + p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed = params->num_pools;
111533 + for (i = 0; i < params->num_pools; i++) {
111534 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].id = params->pool_param[i].id;
111535 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].size = params->pool_param[i].size;
111536 + }
111537 +
111538 + if (p_LnxWrpFmPortDev->settings.frag_enabled)
111539 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools,
111540 + ARGS(1, (&p_LnxWrpFmPortDev->opExtPools)));
111541 + }
111542 +
111543 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
111544 +}
111545 +EXPORT_SYMBOL(fm_set_tx_port_params);
111546 +
111547 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev,
111548 + t_Handle h_fm_mac,
111549 + int mac_id)
111550 +{
111551 + t_LnxWrpFmDev *p_lnx_wrp_fm_dev = (t_LnxWrpFmDev *)h_lnx_wrp_fm_dev;
111552 +
111553 + p_lnx_wrp_fm_dev->macs[mac_id].h_Dev = h_fm_mac;
111554 + p_lnx_wrp_fm_dev->macs[mac_id].h_LnxWrpFmDev = h_lnx_wrp_fm_dev;
111555 +}
111556 +EXPORT_SYMBOL(fm_mac_set_handle);
111557 +
111558 +static void LnxwrpFmPcdDevExceptionsCb(t_Handle h_App,
111559 + e_FmPcdExceptions exception)
111560 +{
111561 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
111562 +
111563 + ASSERT_COND(p_LnxWrpFmDev);
111564 +
111565 + DBG(INFO, ("got fm-pcd exception %d", exception));
111566 +
111567 + /* do nothing */
111568 + UNUSED(exception);
111569 +}
111570 +
111571 +static void LnxwrpFmPcdDevIndexedExceptionsCb(t_Handle h_App,
111572 + e_FmPcdExceptions exception,
111573 + uint16_t index)
111574 +{
111575 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
111576 +
111577 + ASSERT_COND(p_LnxWrpFmDev);
111578 +
111579 + DBG(INFO,
111580 + ("got fm-pcd-indexed exception %d, indx %d", exception, index));
111581 +
111582 + /* do nothing */
111583 + UNUSED(exception);
111584 + UNUSED(index);
111585 +}
111586 +
111587 +static t_Error InitFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
111588 +{
111589 + spin_lock_init(&lock);
111590 +
111591 + if (p_LnxWrpFmDev->pcdActive) {
111592 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
111593 + t_FmPcdParams fmPcdParams;
111594 + t_Error err;
111595 +
111596 + memset(&fmPcdParams, 0, sizeof(fmPcdParams));
111597 + fmPcdParams.h_Fm = p_LnxWrpFmDev->h_Dev;
111598 + fmPcdParams.prsSupport = p_LnxWrpFmDev->prsActive;
111599 + fmPcdParams.kgSupport = p_LnxWrpFmDev->kgActive;
111600 + fmPcdParams.plcrSupport = p_LnxWrpFmDev->plcrActive;
111601 + fmPcdParams.ccSupport = p_LnxWrpFmDev->ccActive;
111602 + fmPcdParams.numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
111603 +
111604 +#ifndef CONFIG_GUEST_PARTITION
111605 + fmPcdParams.f_Exception = LnxwrpFmPcdDevExceptionsCb;
111606 + if (fmPcdParams.kgSupport)
111607 + fmPcdParams.f_ExceptionId =
111608 + LnxwrpFmPcdDevIndexedExceptionsCb;
111609 + fmPcdParams.h_App = p_LnxWrpFmDev;
111610 +#endif /* !CONFIG_GUEST_PARTITION */
111611 +
111612 +#ifdef CONFIG_MULTI_PARTITION_SUPPORT
111613 + fmPcdParams.numOfSchemes = 0;
111614 + fmPcdParams.numOfClsPlanEntries = 0;
111615 + fmPcdParams.partitionId = 0;
111616 +#endif /* CONFIG_MULTI_PARTITION_SUPPORT */
111617 + fmPcdParams.useHostCommand = TRUE;
111618 +
111619 + p_LnxWrpFmDev->hc_tx_fq =
111620 + FqAlloc(p_LnxWrpFmDev,
111621 + 0,
111622 + QMAN_FQ_FLAG_TO_DCPORTAL,
111623 + p_LnxWrpFmPortDev->txCh, 0);
111624 + if (!p_LnxWrpFmDev->hc_tx_fq)
111625 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111626 + ("Frame queue allocation failed..."));
111627 +
111628 + p_LnxWrpFmDev->hc_tx_conf_fq =
111629 + FqAlloc(p_LnxWrpFmDev,
111630 + 0,
111631 + QMAN_FQ_FLAG_NO_ENQUEUE,
111632 + p_LnxWrpFmDev->hcCh, 1);
111633 + if (!p_LnxWrpFmDev->hc_tx_conf_fq)
111634 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111635 + ("Frame queue allocation failed..."));
111636 +
111637 + p_LnxWrpFmDev->hc_tx_err_fq =
111638 + FqAlloc(p_LnxWrpFmDev,
111639 + 0,
111640 + QMAN_FQ_FLAG_NO_ENQUEUE,
111641 + p_LnxWrpFmDev->hcCh, 2);
111642 + if (!p_LnxWrpFmDev->hc_tx_err_fq)
111643 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111644 + ("Frame queue allocation failed..."));
111645 +
111646 + fmPcdParams.hc.portBaseAddr = p_LnxWrpFmPortDev->baseAddr;
111647 + fmPcdParams.hc.portId =
111648 + p_LnxWrpFmPortDev->settings.param.portId;
111649 + fmPcdParams.hc.liodnBase =
111650 + p_LnxWrpFmPortDev->settings.param.liodnBase;
111651 + fmPcdParams.hc.errFqid =
111652 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_err_fq);
111653 + fmPcdParams.hc.confFqid =
111654 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_conf_fq);
111655 + fmPcdParams.hc.qmChannel = p_LnxWrpFmPortDev->txCh;
111656 + fmPcdParams.hc.f_QmEnqueue = QmEnqueueCB;
111657 + fmPcdParams.hc.h_QmArg = (t_Handle) p_LnxWrpFmDev;
111658 +
111659 + p_LnxWrpFmDev->h_PcdDev = FM_PCD_Config(&fmPcdParams);
111660 + if (!p_LnxWrpFmDev->h_PcdDev)
111661 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM PCD!"));
111662 +
111663 + err =
111664 + FM_PCD_ConfigPlcrNumOfSharedProfiles(p_LnxWrpFmDev->h_PcdDev,
111665 + LNXWRP_FM_NUM_OF_SHARED_PROFILES);
111666 + if (err != E_OK)
111667 + RETURN_ERROR(MAJOR, err, NO_MSG);
111668 +
111669 + err = FM_PCD_Init(p_LnxWrpFmDev->h_PcdDev);
111670 + if (err != E_OK)
111671 + RETURN_ERROR(MAJOR, err, NO_MSG);
111672 +
111673 + if (p_LnxWrpFmDev->err_irq == 0) {
111674 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111675 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC,
111676 + FALSE);
111677 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111678 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW,
111679 + FALSE);
111680 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111681 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,
111682 + FALSE);
111683 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111684 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC,
111685 + FALSE);
111686 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111687 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC,
111688 + FALSE);
111689 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111690 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE,
111691 + FALSE);
111692 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111693 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE,
111694 + FALSE);
111695 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111696 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC,
111697 + FALSE);
111698 + }
111699 + }
111700 +
111701 + return E_OK;
111702 +}
111703 +
111704 +void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
111705 +{
111706 +
111707 + if (p_LnxWrpFmDev->h_PcdDev)
111708 + FM_PCD_Free(p_LnxWrpFmDev->h_PcdDev);
111709 +
111710 + if (p_LnxWrpFmDev->hc_tx_err_fq)
111711 + FqFree(p_LnxWrpFmDev->hc_tx_err_fq);
111712 +
111713 + if (p_LnxWrpFmDev->hc_tx_conf_fq)
111714 + FqFree(p_LnxWrpFmDev->hc_tx_conf_fq);
111715 +
111716 + if (p_LnxWrpFmDev->hc_tx_fq)
111717 + FqFree(p_LnxWrpFmDev->hc_tx_fq);
111718 +}
111719 +
111720 +static void FreeFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111721 +{
111722 + t_LnxWrpFmDev *p_LnxWrpFmDev =
111723 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111724 +
111725 + if (!p_LnxWrpFmPortDev->active)
111726 + return;
111727 +
111728 + if (p_LnxWrpFmPortDev->h_Dev)
111729 + FM_PORT_Free(p_LnxWrpFmPortDev->h_Dev);
111730 +
111731 + devm_iounmap(p_LnxWrpFmDev->dev,
111732 + UINT_TO_PTR(p_LnxWrpFmPortDev->baseAddr));
111733 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
111734 + p_LnxWrpFmPortDev->phys_baseAddr,
111735 + p_LnxWrpFmPortDev->memSize);
111736 +}
111737 +
111738 +static int /*__devinit*/ fm_port_probe(struct platform_device *of_dev)
111739 +{
111740 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111741 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111742 + struct device *dev;
111743 +
111744 + dev = &of_dev->dev;
111745 +
111746 + p_LnxWrpFmPortDev = ReadFmPortDevTreeNode(of_dev);
111747 + if (p_LnxWrpFmPortDev == NULL)
111748 + return -EIO;
111749 + /* Port can be inactive, thus will not be probed:
111750 + - in performance mode, OH ports are disabled
111751 + ...
111752 + */
111753 + if (!p_LnxWrpFmPortDev->active)
111754 + return 0;
111755 +
111756 + if (ConfigureFmPortDev(p_LnxWrpFmPortDev) != E_OK)
111757 + return -EIO;
111758 +
111759 + dev_set_drvdata(dev, p_LnxWrpFmPortDev);
111760 +
111761 + if (p_LnxWrpFmPortDev->settings.param.portType ==
111762 + e_FM_PORT_TYPE_OH_HOST_COMMAND)
111763 + InitFmPcdDev((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev);
111764 +
111765 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111766 +
111767 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX) {
111768 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111769 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111770 + p_LnxWrpFmPortDev->minor =
111771 + p_LnxWrpFmPortDev->id + DEV_FM_RX_PORTS_MINOR_BASE;
111772 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111773 + e_FM_PORT_TYPE_RX_10G) {
111774 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111775 + p_LnxWrpFmDev->name,
111776 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS);
111777 + p_LnxWrpFmPortDev->minor =
111778 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS +
111779 + DEV_FM_RX_PORTS_MINOR_BASE;
111780 +#ifndef CONFIG_FMAN_ARM
111781 + if (IS_T1023_T1024) {
111782 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111783 + p_LnxWrpFmDev->name,
111784 + p_LnxWrpFmPortDev->id);
111785 + p_LnxWrpFmPortDev->minor =
111786 + p_LnxWrpFmPortDev->id +
111787 + DEV_FM_RX_PORTS_MINOR_BASE;
111788 + }
111789 +#endif
111790 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111791 + e_FM_PORT_TYPE_TX) {
111792 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111793 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111794 + p_LnxWrpFmPortDev->minor =
111795 + p_LnxWrpFmPortDev->id + DEV_FM_TX_PORTS_MINOR_BASE;
111796 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111797 + e_FM_PORT_TYPE_TX_10G) {
111798 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111799 + p_LnxWrpFmDev->name,
111800 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS);
111801 + p_LnxWrpFmPortDev->minor =
111802 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS +
111803 + DEV_FM_TX_PORTS_MINOR_BASE;
111804 +#ifndef CONFIG_FMAN_ARM
111805 + if (IS_T1023_T1024) {
111806 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111807 + p_LnxWrpFmDev->name,
111808 + p_LnxWrpFmPortDev->id);
111809 + p_LnxWrpFmPortDev->minor =
111810 + p_LnxWrpFmPortDev->id +
111811 + DEV_FM_TX_PORTS_MINOR_BASE;
111812 + }
111813 +#endif
111814 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111815 + e_FM_PORT_TYPE_OH_HOST_COMMAND) {
111816 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111817 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111818 + p_LnxWrpFmPortDev->minor =
111819 + p_LnxWrpFmPortDev->id + DEV_FM_OH_PORTS_MINOR_BASE;
111820 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111821 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
111822 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111823 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id + 1);
111824 + p_LnxWrpFmPortDev->minor =
111825 + p_LnxWrpFmPortDev->id + 1 +
111826 + DEV_FM_OH_PORTS_MINOR_BASE;
111827 + }
111828 +
111829 + device_create(p_LnxWrpFmDev->fm_class, NULL,
111830 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor),
111831 + NULL, p_LnxWrpFmPortDev->name);
111832 +
111833 + /* create sysfs entries for stats and regs */
111834 +
111835 + if (fm_port_sysfs_create(dev) != 0) {
111836 + FreeFmPortDev(p_LnxWrpFmPortDev);
111837 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
111838 + ("Unable to create sys entry - fm port!!!"));
111839 + return -EIO;
111840 + }
111841 +
111842 +#ifdef FM_TX_INVALID_ECC_ERRATA_10GMAC_A009
111843 + FM_DisableRamsEcc(p_LnxWrpFmDev->h_Dev);
111844 +#endif /* FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 */
111845 +
111846 + DBG(TRACE, ("%s probed", p_LnxWrpFmPortDev->name));
111847 +
111848 + return 0;
111849 +}
111850 +
111851 +static int fm_port_remove(struct platform_device *of_dev)
111852 +{
111853 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111854 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111855 + struct device *dev;
111856 +
111857 + dev = &of_dev->dev;
111858 + p_LnxWrpFmPortDev = dev_get_drvdata(dev);
111859 +
111860 + fm_port_sysfs_destroy(dev);
111861 +
111862 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111863 + device_destroy(p_LnxWrpFmDev->fm_class,
111864 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor));
111865 +
111866 + FreeFmPortDev(p_LnxWrpFmPortDev);
111867 +
111868 + dev_set_drvdata(dev, NULL);
111869 +
111870 + return 0;
111871 +}
111872 +
111873 +static const struct of_device_id fm_port_match[] = {
111874 + {
111875 + .compatible = "fsl,fman-port-oh"},
111876 + {
111877 + .compatible = "fsl,fman-port-1g-rx"},
111878 + {
111879 + .compatible = "fsl,fman-port-10g-rx"},
111880 + {
111881 + .compatible = "fsl,fman-port-1g-tx"},
111882 + {
111883 + .compatible = "fsl,fman-port-10g-tx"},
111884 + {}
111885 +};
111886 +
111887 +#ifndef MODULE
111888 +MODULE_DEVICE_TABLE(of, fm_port_match);
111889 +#endif /* !MODULE */
111890 +
111891 +static struct platform_driver fm_port_driver = {
111892 +
111893 + .driver = {
111894 + .name = "fsl-fman-port",
111895 + .of_match_table = fm_port_match,
111896 + .owner = THIS_MODULE,
111897 + },
111898 + .probe = fm_port_probe,
111899 + .remove = fm_port_remove
111900 +};
111901 +
111902 +
111903 +t_Error LNXWRP_FM_Port_Init(void)
111904 +{
111905 + /* Register to the DTB for basic FM port API */
111906 + if (platform_driver_register(&fm_port_driver))
111907 + return E_NO_DEVICE;
111908 +
111909 + return E_OK;
111910 +}
111911 +
111912 +void LNXWRP_FM_Port_Free(void)
111913 +{
111914 + platform_driver_unregister(&fm_port_driver);
111915 +}
111916 +
111917 +static int __init __cold fm_port_load(void)
111918 +{
111919 + if (LNXWRP_FM_Port_Init() != E_OK) {
111920 + printk(KERN_CRIT "Failed to init FM Ports wrapper!\n");
111921 + return -ENODEV;
111922 + }
111923 +
111924 + printk(KERN_CRIT "Freescale FM Ports module\n");
111925 +
111926 + return 0;
111927 +}
111928 +
111929 +static void __exit __cold fm_port_unload(void)
111930 +{
111931 + LNXWRP_FM_Port_Free();
111932 +}
111933 +
111934 +module_init(fm_port_load);
111935 +module_exit(fm_port_unload);
111936 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
111937 new file mode 100644
111938 index 00000000..06833ba8
111939 --- /dev/null
111940 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
111941 @@ -0,0 +1,4854 @@
111942 +/*
111943 + * Copyright 2008-2012 Freescale Semiconductor Inc.
111944 + *
111945 + * Redistribution and use in source and binary forms, with or without
111946 + * modification, are permitted provided that the following conditions are met:
111947 + * * Redistributions of source code must retain the above copyright
111948 + * notice, this list of conditions and the following disclaimer.
111949 + * * Redistributions in binary form must reproduce the above copyright
111950 + * notice, this list of conditions and the following disclaimer in the
111951 + * documentation and/or other materials provided with the distribution.
111952 + * * Neither the name of Freescale Semiconductor nor the
111953 + * names of its contributors may be used to endorse or promote products
111954 + * derived from this software without specific prior written permission.
111955 + *
111956 + *
111957 + * ALTERNATIVELY, this software may be distributed under the terms of the
111958 + * GNU General Public License ("GPL") as published by the Free Software
111959 + * Foundation, either version 2 of that License or (at your option) any
111960 + * later version.
111961 + *
111962 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
111963 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
111964 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
111965 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
111966 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
111967 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
111968 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
111969 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111970 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
111971 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111972 + */
111973 +
111974 +/*
111975 + @File lnxwrp_ioctls_fm.c
111976 + @Author Shlomi Gridish
111977 + @Description FM Linux wrapper functions.
111978 +*/
111979 +
111980 +/* Linux Headers ------------------- */
111981 +#include <linux/version.h>
111982 +
111983 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
111984 +#define MODVERSIONS
111985 +#endif
111986 +#ifdef MODVERSIONS
111987 +#include <config/modversions.h>
111988 +#endif /* MODVERSIONS */
111989 +
111990 +#include <linux/kernel.h>
111991 +#include <linux/module.h>
111992 +#include <linux/slab.h>
111993 +#include <linux/fs.h>
111994 +#include <linux/cdev.h>
111995 +#include <linux/device.h>
111996 +#include <linux/irq.h>
111997 +#include <linux/interrupt.h>
111998 +#include <linux/io.h>
111999 +#include <linux/ioport.h>
112000 +#include <linux/of_platform.h>
112001 +#include <linux/uaccess.h>
112002 +#include <asm/errno.h>
112003 +#ifndef CONFIG_FMAN_ARM
112004 +#include <sysdev/fsl_soc.h>
112005 +#include <linux/fsl/svr.h>
112006 +#endif
112007 +
112008 +#if defined(CONFIG_COMPAT)
112009 +#include <linux/compat.h>
112010 +#endif
112011 +
112012 +#include "part_ext.h"
112013 +#include "fm_ioctls.h"
112014 +#include "fm_pcd_ioctls.h"
112015 +#include "fm_port_ioctls.h"
112016 +#include "fm_vsp_ext.h"
112017 +
112018 +#ifndef CONFIG_FMAN_ARM
112019 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
112020 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
112021 +#endif
112022 +
112023 +#define __ERR_MODULE__ MODULE_FM
112024 +
112025 +#if defined(CONFIG_COMPAT)
112026 +#include "lnxwrp_ioctls_fm_compat.h"
112027 +#endif
112028 +
112029 +#include "lnxwrp_fm.h"
112030 +
112031 +#define CMP_IOC_DEFINE(def) (IOC_##def != def)
112032 +
112033 +/* fm_pcd_ioctls.h === fm_pcd_ext.h assertions */
112034 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
112035 +#error Error: please synchronize IOC_ defines!
112036 +#endif
112037 +
112038 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_HDRS)
112039 +#error Error: please synchronize IOC_ defines!
112040 +#endif
112041 +
112042 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
112043 +#error Error: please synchronize IOC_ defines!
112044 +#endif
112045 +
112046 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
112047 +#error Error: please synchronize IOC_ defines!
112048 +#endif
112049 +
112050 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_GENERIC_REGS)
112051 +#error Error: please synchronize IOC_ defines!
112052 +#endif
112053 +
112054 +#if CMP_IOC_DEFINE(FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
112055 +#error Error: please synchronize IOC_ defines!
112056 +#endif
112057 +
112058 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
112059 +#error Error: please synchronize IOC_ defines!
112060 +#endif
112061 +
112062 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_DEFAULT_GROUPS)
112063 +#error Error: please synchronize IOC_ defines!
112064 +#endif
112065 +
112066 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_LABELS)
112067 +#error Error: please synchronize IOC_ defines!
112068 +#endif
112069 +
112070 +#if CMP_IOC_DEFINE(FM_PCD_SW_PRS_SIZE)
112071 +#error Error: please synchronize IOC_ defines!
112072 +#endif
112073 +
112074 +#if CMP_IOC_DEFINE(FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE)
112075 +#error Error: please synchronize IOC_ defines!
112076 +#endif
112077 +
112078 +#if DPAA_VERSION >= 11
112079 +#if CMP_IOC_DEFINE(FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
112080 +#error Error: please synchronize IOC_ defines!
112081 +#endif
112082 +#endif
112083 +
112084 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_TREES)
112085 +#error Error: please synchronize IOC_ defines!
112086 +#endif
112087 +
112088 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_GROUPS)
112089 +#error Error: please synchronize IOC_ defines!
112090 +#endif
112091 +
112092 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_UNITS)
112093 +#error Error: please synchronize IOC_ defines!
112094 +#endif
112095 +
112096 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_KEYS)
112097 +#error Error: please synchronize IOC_ defines!
112098 +#endif
112099 +
112100 +#if CMP_IOC_DEFINE(FM_PCD_MAX_SIZE_OF_KEY)
112101 +#error Error: please synchronize IOC_ defines!
112102 +#endif
112103 +
112104 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP)
112105 +#error Error: please synchronize IOC_ defines!
112106 +#endif
112107 +
112108 +#if CMP_IOC_DEFINE(FM_PCD_LAST_KEY_INDEX)
112109 +#error Error: please synchronize IOC_ defines!
112110 +#endif
112111 +
112112 +/* net_ioctls.h === net_ext.h assertions */
112113 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_PID)
112114 +#error Error: please synchronize IOC_ defines!
112115 +#endif
112116 +
112117 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_COMPRESSED)
112118 +#error Error: please synchronize IOC_ defines!
112119 +#endif
112120 +
112121 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_ALL_FIELDS)
112122 +#error Error: please synchronize IOC_ defines!
112123 +#endif
112124 +
112125 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPoE_ALL_FIELDS)
112126 +#error Error: please synchronize IOC_ defines!
112127 +#endif
112128 +
112129 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_ALL_FIELDS)
112130 +#error Error: please synchronize IOC_ defines!
112131 +#endif
112132 +
112133 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS)
112134 +#error Error: please synchronize IOC_ defines!
112135 +#endif
112136 +
112137 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ETH_ALL_FIELDS)
112138 +#error Error: please synchronize IOC_ defines!
112139 +#endif
112140 +
112141 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv4_ALL_FIELDS)
112142 +#error Error: please synchronize IOC_ defines!
112143 +#endif
112144 +
112145 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv6_ALL_FIELDS)
112146 +#error Error: please synchronize IOC_ defines!
112147 +#endif
112148 +
112149 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ICMP_ALL_FIELDS)
112150 +#error Error: please synchronize IOC_ defines!
112151 +#endif
112152 +
112153 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IGMP_ALL_FIELDS)
112154 +#error Error: please synchronize IOC_ defines!
112155 +#endif
112156 +
112157 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_TCP_ALL_FIELDS)
112158 +#error Error: please synchronize IOC_ defines!
112159 +#endif
112160 +
112161 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_ALL_FIELDS)
112162 +#error Error: please synchronize IOC_ defines!
112163 +#endif
112164 +
112165 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_DCCP_ALL_FIELDS)
112166 +#error Error: please synchronize IOC_ defines!
112167 +#endif
112168 +
112169 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ALL_FIELDS)
112170 +#error Error: please synchronize IOC_ defines!
112171 +#endif
112172 +
112173 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS)
112174 +#error Error: please synchronize IOC_ defines!
112175 +#endif
112176 +
112177 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPHC_ALL_FIELDS)
112178 +#error Error: please synchronize IOC_ defines!
112179 +#endif
112180 +
112181 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS)
112182 +#error Error: please synchronize IOC_ defines!
112183 +#endif
112184 +
112185 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv2_ALL_FIELDS)
112186 +#error Error: please synchronize IOC_ defines!
112187 +#endif
112188 +
112189 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS)
112190 +#error Error: please synchronize IOC_ defines!
112191 +#endif
112192 +
112193 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS)
112194 +#error Error: please synchronize IOC_ defines!
112195 +#endif
112196 +
112197 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_VLAN_ALL_FIELDS)
112198 +#error Error: please synchronize IOC_ defines!
112199 +#endif
112200 +
112201 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_ALL_FIELDS)
112202 +#error Error: please synchronize IOC_ defines!
112203 +#endif
112204 +
112205 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_NLPID_ALL_FIELDS)
112206 +#error Error: please synchronize IOC_ defines!
112207 +#endif
112208 +
112209 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SNAP_ALL_FIELDS)
112210 +#error Error: please synchronize IOC_ defines!
112211 +#endif
112212 +
112213 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS)
112214 +#warning Error: please synchronize IOC_ defines!
112215 +#endif
112216 +
112217 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ARP_ALL_FIELDS)
112218 +#error Error: please synchronize IOC_ defines!
112219 +#endif
112220 +
112221 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_RFC2684_ALL_FIELDS)
112222 +#error Error: please synchronize IOC_ defines!
112223 +#endif
112224 +
112225 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS)
112226 +#error Error: please synchronize IOC_ defines!
112227 +#endif
112228 +
112229 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS)
112230 +#error Error: please synchronize IOC_ defines!
112231 +#endif
112232 +
112233 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_GRE_ALL_FIELDS)
112234 +#error Error: please synchronize IOC_ defines!
112235 +#endif
112236 +
112237 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MINENCAP_ALL_FIELDS)
112238 +#error Error: please synchronize IOC_ defines!
112239 +#endif
112240 +
112241 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS)
112242 +#error Error: please synchronize IOC_ defines!
112243 +#endif
112244 +
112245 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS)
112246 +#error Error: please synchronize IOC_ defines!
112247 +#endif
112248 +
112249 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS)
112250 +#error Error: please synchronize IOC_ defines!
112251 +#endif
112252 +
112253 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MACSEC_ALL_FIELDS)
112254 +#error Error: please synchronize IOC_ defines!
112255 +#endif
112256 +
112257 +/* fm_ioctls.h === fm_ext.h assertions */
112258 +#if CMP_IOC_DEFINE(FM_MAX_NUM_OF_VALID_PORTS)
112259 +#error Error: please synchronize IOC_ defines!
112260 +#endif
112261 +
112262 +void LnxWrpPCDIOCTLTypeChecking(void)
112263 +{
112264 + /* fm_ext.h == fm_ioctls.h */
112265 + ASSERT_COND(sizeof(ioc_fm_port_bandwidth_params) == sizeof(t_FmPortsBandwidthParams));
112266 + ASSERT_COND(sizeof(ioc_fm_revision_info_t) == sizeof(t_FmRevisionInfo));
112267 +
112268 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
112269 + /*ioc_fm_pcd_counters_params_t : NOT USED */
112270 + /*ioc_fm_pcd_exception_params_t : private */
112271 +#if (DPAA_VERSION >= 11)
112272 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_params_t) == sizeof(t_FmPcdManipFragCapwapParams));
112273 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_params_t) == sizeof(t_FmPcdManipReassemCapwapParams));
112274 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t) == sizeof(t_FmPcdManipHdrInsrtByHdrParams));
112275 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_ip_params_t) == sizeof(t_FmPcdManipHdrInsrtIpParams));
112276 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_t) == sizeof(t_FmPcdManipHdrInsrt));
112277 + ASSERT_COND(sizeof(ioc_fm_manip_hdr_info_t) == sizeof(t_FmManipHdrInfo));
112278 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t) == sizeof(t_FmPcdManipHdrRmvByHdrParams));
112279 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_capwap_params_t) == sizeof(t_FmPcdManipSpecialOffloadCapwapParams));
112280 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_stats_t) == sizeof(t_FmPcdManipFragCapwapStats));
112281 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_stats_t) == sizeof(t_FmPcdManipReassemCapwapStats));
112282 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
112283 +#endif /* (DPAA_VERSION >= 11) */
112284 +
112285 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_label_params_t) == sizeof(t_FmPcdPrsLabelParams));
112286 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_sw_params_t) == sizeof(t_FmPcdPrsSwParams));
112287 + /*ioc_fm_pcd_kg_dflt_value_params_t : private */
112288 + ASSERT_COND(sizeof(ioc_fm_pcd_hdr_protocol_opt_u) == sizeof(u_FmPcdHdrProtocolOpt));
112289 + ASSERT_COND(sizeof(ioc_fm_pcd_fields_u) == sizeof(t_FmPcdFields));
112290 + ASSERT_COND(sizeof(ioc_fm_pcd_from_hdr_t) == sizeof(t_FmPcdFromHdr));
112291 + ASSERT_COND(sizeof(ioc_fm_pcd_from_field_t) == sizeof(t_FmPcdFromField));
112292 + ASSERT_COND(sizeof(ioc_fm_pcd_distinction_unit_t) == sizeof(t_FmPcdDistinctionUnit));
112293 +
112294 +#if defined(CONFIG_ARM64)
112295 + /* different alignment */
112296 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *) + 4);
112297 +#else
112298 +#if !defined(CONFIG_COMPAT)
112299 + /* different alignment */
112300 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *));
112301 +#endif
112302 +#endif
112303 + ASSERT_COND(sizeof(ioc_fm_pcd_extract_entry_t) == sizeof(t_FmPcdExtractEntry));
112304 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_mask_t) == sizeof(t_FmPcdKgExtractMask));
112305 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_dflt_t) == sizeof(t_FmPcdKgExtractDflt));
112306 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t) == sizeof(t_FmPcdKgKeyExtractAndHashParams));
112307 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extracted_or_params_t) == sizeof(t_FmPcdKgExtractedOrParams));
112308 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_counter_t) == sizeof(t_FmPcdKgSchemeCounter));
112309 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_plcr_profile_t) == sizeof(t_FmPcdKgPlcrProfile));
112310 +#if (DPAA_VERSION >= 11)
112311 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_storage_profile_t) == sizeof(t_FmPcdKgStorageProfile));
112312 +#endif
112313 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_cc_t) == sizeof(t_FmPcdKgCc));
112314 +#if !defined(CONFIG_COMPAT)
112315 + /* different alignment */
112316 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_params_t) == sizeof(t_FmPcdKgSchemeParams) + sizeof(void *));
112317 +#endif
112318 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_cc_params_t) == sizeof(t_FmPcdCcNextCcParams));
112319 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_plcr_params_t) == sizeof(t_FmPcdCcNextPlcrParams));
112320 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_enqueue_params_t) == sizeof(t_FmPcdCcNextEnqueueParams));
112321 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_kg_params_t) == sizeof(t_FmPcdCcNextKgParams));
112322 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_engine_params_t) == sizeof(t_FmPcdCcNextEngineParams));
112323 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_key_params_t) == sizeof(t_FmPcdCcKeyParams));
112324 + ASSERT_COND(sizeof(ioc_keys_params_t) == sizeof(t_KeysParams));
112325 +#if !defined(CONFIG_COMPAT)
112326 + /* different alignment */
112327 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_node_params_t) == sizeof(t_FmPcdCcNodeParams) + sizeof(void *));
112328 + ASSERT_COND(sizeof(ioc_fm_pcd_hash_table_params_t) == sizeof(t_FmPcdHashTableParams) + sizeof(void *));
112329 +#endif
112330 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_grp_params_t) == sizeof(t_FmPcdCcGrpParams));
112331 +#if !defined(CONFIG_COMPAT)
112332 + /* different alignment */
112333 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_tree_params_t) == sizeof(t_FmPcdCcTreeParams) + sizeof(void *));
112334 +#endif
112335 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_byte_rate_mode_param_t) == sizeof(t_FmPcdPlcrByteRateModeParams));
112336 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t) == sizeof(t_FmPcdPlcrNonPassthroughAlgParams));
112337 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_next_engine_params_u) == sizeof(u_FmPcdPlcrNextEngineParams));
112338 + /*ioc_fm_pcd_port_params_t : private */
112339 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_profile_params_t) == sizeof(t_FmPcdPlcrProfileParams) + sizeof(void *));
112340 + /*ioc_fm_pcd_cc_tree_modify_next_engine_params_t : private */
112341 +
112342 +#ifdef FM_CAPWAP_SUPPORT
112343 +#error TODO: unsupported feature
112344 +/*
112345 + ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrInsrtByTemplateParams));
112346 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapFragmentationParams));
112347 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapReassemblyParams));
112348 +*/
112349 +#endif
112350 +
112351 + /*ioc_fm_pcd_cc_node_modify_next_engine_params_t : private */
112352 + /*ioc_fm_pcd_cc_node_remove_key_params_t : private */
112353 + /*ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t : private */
112354 + /*ioc_fm_pcd_cc_node_modify_key_params_t : private */
112355 + /*ioc_fm_manip_hdr_info_t : private */
112356 + /*ioc_fm_pcd_hash_table_set_t : private */
112357 +
112358 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_params_t) == sizeof(t_FmPcdManipFragIpParams));
112359 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_params_t) == sizeof(t_FmPcdManipReassemIpParams));
112360 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_ipsec_params_t) == sizeof(t_FmPcdManipSpecialOffloadIPSecParams));
112361 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_params_t) == sizeof(t_FmPcdManipSpecialOffloadParams));
112362 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_generic_params_t) == sizeof(t_FmPcdManipHdrRmvGenericParams));
112363 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_generic_params_t) == sizeof(t_FmPcdManipHdrInsrtGenericParams));
112364 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_params_t) == sizeof(t_FmPcdManipHdrInsrtParams));
112365 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_params_t) == sizeof(t_FmPcdManipHdrRmvParams));
112366 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_params_t) == sizeof(t_FmPcdManipHdrParams));
112367 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
112368 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_params_t) == sizeof(t_FmPcdManipReassemParams));
112369 +#if !defined(CONFIG_COMPAT)
112370 + /* different alignment */
112371 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_params_t) == sizeof(t_FmPcdManipParams) + sizeof(void *));
112372 +#endif
112373 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_stats_t) == sizeof(t_FmPcdManipReassemIpStats));
112374 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_stats_t) == sizeof(t_FmPcdManipFragIpStats));
112375 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_stats_t) == sizeof(t_FmPcdManipReassemStats));
112376 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_stats_t) == sizeof(t_FmPcdManipFragStats));
112377 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_stats_t) == sizeof(t_FmPcdManipStats));
112378 +#if DPAA_VERSION >= 11
112379 + ASSERT_COND(sizeof(ioc_fm_pcd_frm_replic_group_params_t) == sizeof(t_FmPcdFrmReplicGroupParams) + sizeof(void *));
112380 +#endif
112381 +
112382 + /* fm_port_ext.h == fm_port_ioctls.h */
112383 + ASSERT_COND(sizeof(ioc_fm_port_rate_limit_t) == sizeof(t_FmPortRateLimit));
112384 + ASSERT_COND(sizeof(ioc_fm_port_pcd_params_t) == sizeof(t_FmPortPcdParams));
112385 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_select_t) == sizeof(t_FmPcdKgSchemeSelect));
112386 + ASSERT_COND(sizeof(ioc_fm_pcd_port_schemes_params_t) == sizeof(t_FmPcdPortSchemesParams));
112387 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_start_t) == sizeof(t_FmPcdPrsStart));
112388 +
112389 + return;
112390 +}
112391 +
112392 +#define ASSERT_IOC_NET_ENUM(def) ASSERT_COND((unsigned long)e_IOC_NET_##def == (unsigned long)def)
112393 +
112394 +void LnxWrpPCDIOCTLEnumChecking(void)
112395 +{
112396 + /* net_ext.h == net_ioctls.h : sampling checks */
112397 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_MACSEC);
112398 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_PPP);
112399 + ASSERT_IOC_NET_ENUM(MAX_HEADER_TYPE_COUNT);
112400 +
112401 + /* fm_ext.h == fm_ioctls.h */
112402 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_TYPE_DUMMY == (unsigned long)e_FM_PORT_TYPE_DUMMY);
112403 + ASSERT_COND((unsigned long)e_IOC_EX_MURAM_ECC == (unsigned long)e_FM_EX_MURAM_ECC);
112404 + ASSERT_COND((unsigned long)e_IOC_FM_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_COUNTERS_DEQ_CONFIRM);
112405 +
112406 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
112407 + 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);
112408 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC == (unsigned long)e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
112409 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS == (unsigned long)e_FM_PCD_PRS);
112410 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FULL_FIELD == (unsigned long)e_FM_PCD_EXTRACT_FULL_FIELD);
112411 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID == (unsigned long)e_FM_PCD_EXTRACT_FROM_FLOW_ID);
112412 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO == (unsigned long)e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO);
112413 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_DFLT_ILLEGAL == (unsigned long)e_FM_PCD_KG_DFLT_ILLEGAL);
112414 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA == (unsigned long)e_FM_PCD_KG_GENERIC_NOT_FROM_DATA);
112415 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_HDR_INDEX_LAST == (unsigned long)e_FM_PCD_HDR_INDEX_LAST);
112416 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_SHARED == (unsigned long)e_FM_PCD_PLCR_SHARED);
112417 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_RFC_4115 == (unsigned long)e_FM_PCD_PLCR_RFC_4115);
112418 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_COLOR_AWARE == (unsigned long)e_FM_PCD_PLCR_COLOR_AWARE);
112419 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_OVERRIDE == (unsigned long)e_FM_PCD_PLCR_OVERRIDE);
112420 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_FULL_FRM_LEN);
112421 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN);
112422 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PACKET_MODE == (unsigned long)e_FM_PCD_PLCR_PACKET_MODE);
112423 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_DROP_FRAME == (unsigned long)e_FM_PCD_DROP_FRAME);
112424 + 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);
112425 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP == (unsigned long)e_FM_PCD_ACTION_INDEXED_LOOKUP);
112426 + 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);
112427 +#if !defined(FM_CAPWAP_SUPPORT)
112428 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_GENERIC == (unsigned long)e_FM_PCD_MANIP_INSRT_GENERIC);
112429 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_GENERIC == (unsigned long)e_FM_PCD_MANIP_RMV_GENERIC);
112430 +#else
112431 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE == (unsigned long)e_FM_PCD_MANIP_INSRT_BY_TEMPLATE);
112432 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR);
112433 + 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);
112434 +#endif
112435 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG == (unsigned long)e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG);
112436 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH == (unsigned long)e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
112437 +
112438 +#ifdef FM_CAPWAP_SUPPORT
112439 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_STATS_PER_FLOWID == (unsigned long)e_FM_PCD_STATS_PER_FLOWID);
112440 +#endif
112441 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD);
112442 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_CC_STATS_MODE_FRAME == (unsigned long)e_FM_PCD_CC_STATS_MODE_FRAME);
112443 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG == (unsigned long)e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG);
112444 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC);
112445 +
112446 + /* fm_port_ext.h == fm_port_ioctls.h */
112447 +#if !defined(FM_CAPWAP_SUPPORT)
112448 + 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);
112449 +#else
112450 + 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);
112451 +#endif
112452 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_PORT_COUNTERS_DEQ_CONFIRM);
112453 + 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);
112454 +
112455 + return;
112456 +}
112457 +
112458 +static t_Error LnxwrpFmPcdIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
112459 +{
112460 + t_Error err = E_OK;
112461 +
112462 +/*
112463 +Status: PCD API to fmlib (file: drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h):
112464 +
112465 + FM_PCD_PrsLoadSw
112466 + FM_PCD_SetAdvancedOffloadSupport
112467 + FM_PCD_Enable
112468 + FM_PCD_Disable
112469 + FM_PCD_ForceIntr
112470 + FM_PCD_SetException
112471 + FM_PCD_KgSetAdditionalDataAfterParsing
112472 + FM_PCD_KgSetDfltValue
112473 + FM_PCD_NetEnvCharacteristicsSet
112474 + FM_PCD_NetEnvCharacteristicsDelete
112475 + FM_PCD_KgSchemeSet
112476 + FM_PCD_KgSchemeDelete
112477 + FM_PCD_MatchTableSet
112478 + FM_PCD_MatchTableDelete
112479 + FM_PCD_CcRootBuild
112480 + FM_PCD_CcRootDelete
112481 + FM_PCD_PlcrProfileSet
112482 + FM_PCD_PlcrProfileDelete
112483 + FM_PCD_CcRootModifyNextEngine
112484 + FM_PCD_MatchTableModifyNextEngine
112485 + FM_PCD_MatchTableModifyMissNextEngine
112486 + FM_PCD_MatchTableRemoveKey
112487 + FM_PCD_MatchTableAddKey
112488 + FM_PCD_MatchTableModifyKeyAndNextEngine
112489 + FM_PCD_HashTableSet
112490 + FM_PCD_HashTableDelete
112491 + FM_PCD_HashTableAddKey
112492 + FM_PCD_HashTableRemoveKey
112493 + FM_PCD_MatchTableModifyKey
112494 + FM_PCD_ManipNodeReplace
112495 + FM_PCD_ManipNodeSet
112496 + FM_PCD_ManipNodeDelete
112497 +
112498 +Status: not exported, should be thru sysfs
112499 + FM_PCD_KgSchemeGetCounter
112500 + FM_PCD_KgSchemeSetCounter
112501 + FM_PCD_PlcrProfileGetCounter
112502 + FM_PCD_PlcrProfileSetCounter
112503 +
112504 +Status: not exported
112505 + FM_PCD_MatchTableFindNRemoveKey
112506 + FM_PCD_MatchTableFindNModifyNextEngine
112507 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine
112508 + FM_PCD_MatchTableFindNModifyKey
112509 + FM_PCD_MatchTableGetIndexedHashBucket
112510 + FM_PCD_MatchTableGetNextEngine
112511 + FM_PCD_MatchTableGetKeyCounter
112512 +
112513 +Status: not exported, would be nice to have
112514 + FM_PCD_HashTableModifyNextEngine
112515 + FM_PCD_HashTableModifyMissNextEngine
112516 + FM_PCD_HashTableGetMissNextEngine
112517 + FM_PCD_ManipGetStatistics
112518 +
112519 +Status: not exported
112520 +#if DPAA_VERSION >= 11
112521 +
112522 + FM_VSP_GetStatistics -- it's not available yet
112523 +#endif
112524 +
112525 +Status: feature not supported
112526 +#ifdef FM_CAPWAP_SUPPORT
112527 +#error unsupported feature
112528 + FM_PCD_StatisticsSetNode
112529 +#endif
112530 +
112531 + */
112532 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
112533 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 20);
112534 +
112535 + switch (cmd)
112536 + {
112537 +#if defined(CONFIG_COMPAT)
112538 + case FM_PCD_IOC_PRS_LOAD_SW_COMPAT:
112539 +#endif
112540 + case FM_PCD_IOC_PRS_LOAD_SW:
112541 + {
112542 + ioc_fm_pcd_prs_sw_params_t *param;
112543 + uint8_t *p_code;
112544 +
112545 + param = (ioc_fm_pcd_prs_sw_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_sw_params_t));
112546 + if (!param)
112547 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112548 +
112549 + memset(param, 0, sizeof(ioc_fm_pcd_prs_sw_params_t));
112550 +
112551 +#if defined(CONFIG_COMPAT)
112552 + if (compat)
112553 + {
112554 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param;
112555 +
112556 + compat_param = (ioc_compat_fm_pcd_prs_sw_params_t *) XX_Malloc(
112557 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
112558 + if (!compat_param)
112559 + {
112560 + XX_Free(param);
112561 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112562 + }
112563 +
112564 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
112565 + if (copy_from_user(compat_param,
112566 + (ioc_compat_fm_pcd_prs_sw_params_t *) compat_ptr(arg),
112567 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t)))
112568 + {
112569 + XX_Free(compat_param);
112570 + XX_Free(param);
112571 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112572 + }
112573 +
112574 + compat_fm_pcd_prs_sw(compat_param, param, COMPAT_US_TO_K);
112575 +
112576 + XX_Free(compat_param);
112577 + }
112578 + else
112579 +#endif
112580 + {
112581 + if (copy_from_user(param, (ioc_fm_pcd_prs_sw_params_t *)arg,
112582 + sizeof(ioc_fm_pcd_prs_sw_params_t)))
112583 + {
112584 + XX_Free(param);
112585 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112586 + }
112587 + }
112588 +
112589 + if (!param->p_code || !param->size)
112590 + {
112591 + XX_Free(param);
112592 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112593 + }
112594 +
112595 + p_code = (uint8_t *) XX_Malloc(param->size);
112596 + if (!p_code)
112597 + {
112598 + XX_Free(param);
112599 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112600 + }
112601 +
112602 + memset(p_code, 0, param->size);
112603 + if (copy_from_user(p_code, param->p_code, param->size))
112604 + {
112605 + XX_Free(p_code);
112606 + XX_Free(param);
112607 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112608 + }
112609 +
112610 + param->p_code = p_code;
112611 +
112612 + err = FM_PCD_PrsLoadSw(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPrsSwParams*)param);
112613 +
112614 + XX_Free(p_code);
112615 + XX_Free(param);
112616 + break;
112617 + }
112618 +
112619 + case FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT:
112620 + err = FM_PCD_SetAdvancedOffloadSupport(p_LnxWrpFmDev->h_PcdDev);
112621 + break;
112622 +
112623 + case FM_PCD_IOC_ENABLE:
112624 + err = FM_PCD_Enable(p_LnxWrpFmDev->h_PcdDev);
112625 + break;
112626 +
112627 + case FM_PCD_IOC_DISABLE:
112628 + err = FM_PCD_Disable(p_LnxWrpFmDev->h_PcdDev);
112629 + break;
112630 +
112631 + case FM_PCD_IOC_FORCE_INTR:
112632 + {
112633 + int exception;
112634 +
112635 +#if defined(CONFIG_COMPAT)
112636 + if (compat)
112637 + {
112638 + if (get_user(exception, (int *) compat_ptr(arg)))
112639 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112640 + }
112641 + else
112642 +#endif
112643 + {
112644 + if (get_user(exception, (int *)arg))
112645 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112646 + }
112647 +
112648 + err = FM_PCD_ForceIntr(p_LnxWrpFmDev->h_PcdDev, (e_FmPcdExceptions)exception);
112649 + break;
112650 + }
112651 +
112652 + case FM_PCD_IOC_SET_EXCEPTION:
112653 + {
112654 + ioc_fm_pcd_exception_params_t *param;
112655 +
112656 + param = (ioc_fm_pcd_exception_params_t *) XX_Malloc(
112657 + sizeof(ioc_fm_pcd_exception_params_t));
112658 + if (!param)
112659 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112660 +
112661 + memset(param, 0, sizeof(ioc_fm_pcd_exception_params_t));
112662 +
112663 +#if defined(CONFIG_COMPAT)
112664 + if (compat)
112665 + {
112666 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)compat_ptr(arg),
112667 + sizeof(ioc_fm_pcd_exception_params_t)))
112668 + {
112669 + XX_Free(param);
112670 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112671 + }
112672 + }
112673 + else
112674 +#endif
112675 + {
112676 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)arg,
112677 + sizeof(ioc_fm_pcd_exception_params_t)))
112678 + {
112679 + XX_Free(param);
112680 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112681 + }
112682 + }
112683 +
112684 + err = FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, param->exception, param->enable);
112685 +
112686 + XX_Free(param);
112687 + break;
112688 + }
112689 +
112690 + case FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING:
112691 + {
112692 + uint8_t payloadOffset;
112693 +
112694 +#if defined(CONFIG_COMPAT)
112695 + if (compat)
112696 + {
112697 + if (get_user(payloadOffset, (uint8_t*) compat_ptr(arg)))
112698 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112699 + }
112700 + else
112701 +#endif
112702 + {
112703 + if (get_user(payloadOffset, (uint8_t*) arg))
112704 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112705 + }
112706 +
112707 + err = FM_PCD_KgSetAdditionalDataAfterParsing(p_LnxWrpFmDev->h_PcdDev, payloadOffset);
112708 + break;
112709 + }
112710 +
112711 + case FM_PCD_IOC_KG_SET_DFLT_VALUE:
112712 + {
112713 + ioc_fm_pcd_kg_dflt_value_params_t *param;
112714 +
112715 + param = (ioc_fm_pcd_kg_dflt_value_params_t *) XX_Malloc(
112716 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
112717 + if (!param)
112718 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112719 +
112720 + memset(param, 0, sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
112721 +
112722 +#if defined(CONFIG_COMPAT)
112723 + if (compat)
112724 + {
112725 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)compat_ptr(arg),
112726 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
112727 + {
112728 + XX_Free(param);
112729 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112730 + }
112731 + }
112732 + else
112733 +#endif
112734 + {
112735 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)arg,
112736 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
112737 + {
112738 + XX_Free(param);
112739 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112740 + }
112741 + }
112742 +
112743 + err = FM_PCD_KgSetDfltValue(p_LnxWrpFmDev->h_PcdDev, param->valueId, param->value);
112744 +
112745 + XX_Free(param);
112746 + break;
112747 + }
112748 +
112749 +#if defined(CONFIG_COMPAT)
112750 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT:
112751 +#endif
112752 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET:
112753 + {
112754 + ioc_fm_pcd_net_env_params_t *param;
112755 +
112756 + param = (ioc_fm_pcd_net_env_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_net_env_params_t));
112757 + if (!param)
112758 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112759 +
112760 + memset(param, 0, sizeof(ioc_fm_pcd_net_env_params_t));
112761 +
112762 +#if defined(CONFIG_COMPAT)
112763 + if (compat)
112764 + {
112765 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112766 +
112767 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112768 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112769 + if (!compat_param)
112770 + {
112771 + XX_Free(param);
112772 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112773 + }
112774 +
112775 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112776 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112777 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112778 + {
112779 + XX_Free(compat_param);
112780 + XX_Free(param);
112781 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112782 + }
112783 +
112784 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_US_TO_K);
112785 + XX_Free(compat_param);
112786 + }
112787 + else
112788 +#endif
112789 + {
112790 + if (copy_from_user(param, (ioc_fm_pcd_net_env_params_t *) arg,
112791 + sizeof(ioc_fm_pcd_net_env_params_t)))
112792 + {
112793 + XX_Free(param);
112794 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112795 + }
112796 + }
112797 +
112798 + param->id = FM_PCD_NetEnvCharacteristicsSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdNetEnvParams*)param);
112799 +
112800 + if (!param->id)
112801 + {
112802 + XX_Free(param);
112803 + err = E_INVALID_VALUE;
112804 + /* Since the LLD has no errno-style error reporting,
112805 + we're left here with no other option than to report
112806 + a generic E_INVALID_VALUE */
112807 + break;
112808 + }
112809 +
112810 +#if defined(CONFIG_COMPAT)
112811 + if (compat)
112812 + {
112813 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112814 +
112815 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112816 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112817 + if (!compat_param)
112818 + {
112819 + XX_Free(param);
112820 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112821 + }
112822 +
112823 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112824 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_K_TO_US);
112825 +
112826 + if (copy_to_user((ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112827 + compat_param,
112828 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112829 + err = E_READ_FAILED;
112830 +
112831 + XX_Free(compat_param);
112832 + }
112833 + else
112834 +#endif
112835 + {
112836 + if (copy_to_user((ioc_fm_pcd_net_env_params_t *)arg,
112837 + param,
112838 + sizeof(ioc_fm_pcd_net_env_params_t)))
112839 + err = E_READ_FAILED;
112840 + }
112841 +
112842 + XX_Free(param);
112843 + break;
112844 + }
112845 +
112846 +#if defined(CONFIG_COMPAT)
112847 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT:
112848 +#endif
112849 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE:
112850 + {
112851 + ioc_fm_obj_t id;
112852 +
112853 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112854 +
112855 +#if defined(CONFIG_COMPAT)
112856 + if (compat)
112857 + {
112858 + ioc_compat_fm_obj_t compat_id;
112859 +
112860 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112861 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112862 +
112863 + compat_obj_delete(&compat_id, &id);
112864 + }
112865 + else
112866 +#endif
112867 + {
112868 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112869 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112870 + }
112871 +
112872 + err = FM_PCD_NetEnvCharacteristicsDelete(id.obj);
112873 + break;
112874 + }
112875 +
112876 +#if defined(CONFIG_COMPAT)
112877 + case FM_PCD_IOC_KG_SCHEME_SET_COMPAT:
112878 +#endif
112879 + case FM_PCD_IOC_KG_SCHEME_SET:
112880 + {
112881 + ioc_fm_pcd_kg_scheme_params_t *param;
112882 +
112883 + param = (ioc_fm_pcd_kg_scheme_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_params_t));
112884 + if (!param)
112885 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112886 +
112887 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_params_t));
112888 +
112889 +#if defined(CONFIG_COMPAT)
112890 + if (compat)
112891 + {
112892 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param = NULL;
112893 +
112894 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112895 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112896 + if (!compat_param)
112897 + {
112898 + XX_Free(param);
112899 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112900 + }
112901 +
112902 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112903 +
112904 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_params_t *) compat_ptr(arg),
112905 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112906 + {
112907 + XX_Free(compat_param);
112908 + XX_Free(param);
112909 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112910 + }
112911 +
112912 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_US_TO_K);
112913 +
112914 + XX_Free(compat_param);
112915 + }
112916 + else
112917 +#endif
112918 + {
112919 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_params_t *)arg,
112920 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112921 + {
112922 + XX_Free(param);
112923 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112924 + }
112925 + }
112926 +
112927 + param->id = FM_PCD_KgSchemeSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdKgSchemeParams*)param);
112928 +
112929 + if (!param->id)
112930 + {
112931 + XX_Free(param);
112932 + err = E_INVALID_VALUE;
112933 + /* Since the LLD has no errno-style error reporting,
112934 + we're left here with no other option than to report
112935 + a generic E_INVALID_VALUE */
112936 + break;
112937 + }
112938 +
112939 +#if defined(CONFIG_COMPAT)
112940 + if (compat)
112941 + {
112942 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param;
112943 +
112944 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112945 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112946 + if (!compat_param)
112947 + {
112948 + XX_Free(param);
112949 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112950 + }
112951 +
112952 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112953 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_K_TO_US);
112954 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_params_t *)compat_ptr(arg),
112955 + compat_param,
112956 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112957 + err = E_READ_FAILED;
112958 +
112959 + XX_Free(compat_param);
112960 + }
112961 + else
112962 +#endif
112963 + {
112964 + if (copy_to_user((ioc_fm_pcd_kg_scheme_params_t *)arg,
112965 + param,
112966 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112967 + err = E_READ_FAILED;
112968 + }
112969 +
112970 + XX_Free(param);
112971 + break;
112972 + }
112973 +
112974 +#if defined(CONFIG_COMPAT)
112975 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT:
112976 +#endif
112977 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR:
112978 + {
112979 + ioc_fm_pcd_kg_scheme_spc_t *param;
112980 +
112981 + param = (ioc_fm_pcd_kg_scheme_spc_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112982 + if (!param)
112983 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112984 +
112985 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112986 +
112987 +#if defined(CONFIG_COMPAT)
112988 + if (compat)
112989 + {
112990 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param = NULL;
112991 +
112992 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112993 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112994 + if (!compat_param)
112995 + {
112996 + XX_Free(param);
112997 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112998 + }
112999 +
113000 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
113001 +
113002 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_spc_t *) compat_ptr(arg),
113003 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
113004 + {
113005 + XX_Free(compat_param);
113006 + XX_Free(param);
113007 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113008 + }
113009 +
113010 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_US_TO_K);
113011 +
113012 + XX_Free(compat_param);
113013 + }
113014 + else
113015 +#endif
113016 + {
113017 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_spc_t *)arg,
113018 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
113019 + {
113020 + XX_Free(param);
113021 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113022 + }
113023 + }
113024 +
113025 + param->val = FM_PCD_KgSchemeGetCounter((t_Handle)param->id);
113026 +
113027 +#if defined(CONFIG_COMPAT)
113028 + if (compat)
113029 + {
113030 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param;
113031 +
113032 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
113033 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
113034 + if (!compat_param)
113035 + {
113036 + XX_Free(param);
113037 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113038 + }
113039 +
113040 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
113041 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_K_TO_US);
113042 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_spc_t *)compat_ptr(arg),
113043 + compat_param,
113044 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
113045 + err = E_READ_FAILED;
113046 +
113047 + XX_Free(compat_param);
113048 + }
113049 + else
113050 +#endif
113051 + {
113052 + if (copy_to_user((ioc_fm_pcd_kg_scheme_spc_t *)arg,
113053 + param,
113054 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
113055 + err = E_READ_FAILED;
113056 + }
113057 +
113058 + XX_Free(param);
113059 + break;
113060 + }
113061 +
113062 +#if defined(CONFIG_COMPAT)
113063 + case FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT:
113064 +#endif
113065 + case FM_PCD_IOC_KG_SCHEME_DELETE:
113066 + {
113067 + ioc_fm_obj_t id;
113068 +
113069 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113070 +
113071 +#if defined(CONFIG_COMPAT)
113072 + if (compat)
113073 + {
113074 + ioc_compat_fm_obj_t compat_id;
113075 +
113076 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113077 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113078 +
113079 + compat_obj_delete(&compat_id, &id);
113080 + }
113081 + else
113082 +#endif
113083 + {
113084 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113085 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113086 + }
113087 +
113088 + err = FM_PCD_KgSchemeDelete(id.obj);
113089 + break;
113090 + }
113091 +
113092 +#if defined(CONFIG_COMPAT)
113093 + case FM_PCD_IOC_MATCH_TABLE_SET_COMPAT:
113094 +#endif
113095 + case FM_PCD_IOC_MATCH_TABLE_SET:
113096 + {
113097 + ioc_fm_pcd_cc_node_params_t *param;
113098 + uint8_t *keys;
113099 + uint8_t *masks;
113100 + int i,k;
113101 +
113102 + param = (ioc_fm_pcd_cc_node_params_t *) XX_Malloc(
113103 + sizeof(ioc_fm_pcd_cc_node_params_t) +
113104 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
113105 + if (!param)
113106 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113107 +
113108 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_params_t) +
113109 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
113110 +
113111 + keys = (uint8_t *) (param + 1);
113112 + masks = keys + IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY;
113113 +
113114 +#if defined(CONFIG_COMPAT)
113115 + if (compat)
113116 + {
113117 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
113118 +
113119 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
113120 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
113121 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
113122 + if (!compat_param)
113123 + {
113124 + XX_Free(param);
113125 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113126 + }
113127 +
113128 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
113129 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
113130 +
113131 + if (copy_from_user(compat_param,
113132 + (ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
113133 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
113134 + {
113135 + XX_Free(compat_param);
113136 + XX_Free(param);
113137 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113138 + }
113139 +
113140 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_US_TO_K);
113141 +
113142 + XX_Free(compat_param);
113143 + }
113144 + else
113145 +#endif
113146 + {
113147 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_params_t *)arg, sizeof(ioc_fm_pcd_cc_node_params_t)))
113148 + {
113149 + XX_Free(param);
113150 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113151 + }
113152 + }
113153 +
113154 + ASSERT_COND(param->keys_params.num_of_keys <= IOC_FM_PCD_MAX_NUM_OF_KEYS);
113155 + ASSERT_COND(param->keys_params.key_size <= IOC_FM_PCD_MAX_SIZE_OF_KEY);
113156 +
113157 + /* support for indexed lookup */
113158 + if( !(param->extract_cc_params.type == e_IOC_FM_PCD_EXTRACT_NON_HDR &&
113159 + param->extract_cc_params.extract_params.extract_non_hdr.src == e_IOC_FM_PCD_EXTRACT_FROM_HASH &&
113160 + param->extract_cc_params.extract_params.extract_non_hdr.action == e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP))
113161 + {
113162 + for (i=0, k=0;
113163 + i < param->keys_params.num_of_keys;
113164 + i++, k += IOC_FM_PCD_MAX_SIZE_OF_KEY)
113165 + {
113166 + if (param->keys_params.key_params[i].p_key &&
113167 + param->keys_params.key_size)
113168 + {
113169 + if (copy_from_user(&keys[k],
113170 + param->keys_params.key_params[i].p_key,
113171 + param->keys_params.key_size))
113172 + {
113173 + XX_Free(param);
113174 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113175 + }
113176 +
113177 + param->keys_params.key_params[i].p_key = &keys[k];
113178 + }
113179 +
113180 + if (param->keys_params.key_params[i].p_mask)
113181 + {
113182 + if (copy_from_user(&masks[k],
113183 + param->keys_params.key_params[i].p_mask,
113184 + param->keys_params.key_size))
113185 + {
113186 + XX_Free(param);
113187 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113188 + }
113189 +
113190 + param->keys_params.key_params[i].p_mask = &masks[k];
113191 + }
113192 + }
113193 + }
113194 +
113195 + param->id = FM_PCD_MatchTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcNodeParams*)param);
113196 +
113197 + if (!param->id) {
113198 + XX_Free(param);
113199 + err = E_INVALID_VALUE;
113200 + /* Since the LLD has no errno-style error reporting,
113201 + we're left here with no other option than to report
113202 + a generic E_INVALID_VALUE */
113203 + break;
113204 + }
113205 +
113206 +#if defined(CONFIG_COMPAT)
113207 + if (compat)
113208 + {
113209 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
113210 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
113211 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
113212 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
113213 + if (!compat_param)
113214 + {
113215 + XX_Free(param);
113216 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113217 + }
113218 +
113219 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
113220 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
113221 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_K_TO_US);
113222 +
113223 + if (copy_to_user((ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
113224 + compat_param,
113225 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
113226 + err = E_READ_FAILED;
113227 +
113228 + XX_Free(compat_param);
113229 + }
113230 + else
113231 +#endif
113232 + {
113233 + if (copy_to_user((ioc_fm_pcd_cc_node_params_t *)arg,
113234 + param,
113235 + sizeof(ioc_fm_pcd_cc_node_params_t)))
113236 + err = E_READ_FAILED;
113237 + }
113238 +
113239 + XX_Free(param);
113240 + break;
113241 + }
113242 +
113243 +#if defined(CONFIG_COMPAT)
113244 + case FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT:
113245 +#endif
113246 + case FM_PCD_IOC_MATCH_TABLE_DELETE:
113247 + {
113248 + ioc_fm_obj_t id;
113249 +
113250 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113251 +
113252 +#if defined(CONFIG_COMPAT)
113253 + if (compat)
113254 + {
113255 + ioc_compat_fm_obj_t compat_id;
113256 +
113257 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113258 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113259 +
113260 + compat_obj_delete(&compat_id, &id);
113261 + }
113262 + else
113263 +#endif
113264 + {
113265 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113266 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113267 + }
113268 +
113269 + err = FM_PCD_MatchTableDelete(id.obj);
113270 + break;
113271 + }
113272 +
113273 +#if defined(CONFIG_COMPAT)
113274 + case FM_PCD_IOC_CC_ROOT_BUILD_COMPAT:
113275 +#endif
113276 + case FM_PCD_IOC_CC_ROOT_BUILD:
113277 + {
113278 + ioc_fm_pcd_cc_tree_params_t *param;
113279 +
113280 + param = (ioc_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_cc_tree_params_t));
113281 + if (!param)
113282 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113283 +
113284 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_params_t));
113285 +
113286 +#if defined(CONFIG_COMPAT)
113287 + if (compat)
113288 + {
113289 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
113290 +
113291 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(
113292 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
113293 + if (!compat_param)
113294 + {
113295 + XX_Free(param);
113296 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113297 + }
113298 +
113299 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
113300 + if (copy_from_user(compat_param,
113301 + (ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
113302 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
113303 + {
113304 + XX_Free(compat_param);
113305 + XX_Free(param);
113306 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113307 + }
113308 +
113309 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_US_TO_K);
113310 +
113311 + XX_Free(compat_param);
113312 + }
113313 + else
113314 +#endif
113315 + {
113316 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_params_t *)arg,
113317 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
113318 + {
113319 + XX_Free(param);
113320 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113321 + }
113322 + }
113323 +
113324 + param->id = FM_PCD_CcRootBuild(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcTreeParams*)param);
113325 +
113326 + if (!param->id) {
113327 + XX_Free(param);
113328 + err = E_INVALID_VALUE;
113329 + /* Since the LLD has no errno-style error reporting,
113330 + we're left here with no other option than to report
113331 + a generic E_INVALID_VALUE */
113332 + break;
113333 + }
113334 +
113335 +#if defined(CONFIG_COMPAT)
113336 + if (compat)
113337 + {
113338 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
113339 +
113340 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
113341 + if (!compat_param)
113342 + {
113343 + XX_Free(param);
113344 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113345 + }
113346 +
113347 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
113348 +
113349 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_K_TO_US);
113350 +
113351 + if (copy_to_user((ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
113352 + compat_param,
113353 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
113354 + err = E_READ_FAILED;
113355 +
113356 + XX_Free(compat_param);
113357 + }
113358 + else
113359 +#endif
113360 + {
113361 + if (copy_to_user((ioc_fm_pcd_cc_tree_params_t *)arg,
113362 + param,
113363 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
113364 + err = E_READ_FAILED;
113365 + }
113366 +
113367 + XX_Free(param);
113368 + break;
113369 + }
113370 +
113371 +#if defined(CONFIG_COMPAT)
113372 + case FM_PCD_IOC_CC_ROOT_DELETE_COMPAT:
113373 +#endif
113374 + case FM_PCD_IOC_CC_ROOT_DELETE:
113375 + {
113376 + ioc_fm_obj_t id;
113377 +
113378 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113379 +
113380 +#if defined(CONFIG_COMPAT)
113381 + if (compat)
113382 + {
113383 + ioc_compat_fm_obj_t compat_id;
113384 +
113385 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113386 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113387 +
113388 + compat_obj_delete(&compat_id, &id);
113389 + }
113390 + else
113391 +#endif
113392 + {
113393 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113394 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113395 + }
113396 +
113397 + err = FM_PCD_CcRootDelete(id.obj);
113398 + break;
113399 + }
113400 +
113401 +#if defined(CONFIG_COMPAT)
113402 + case FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT:
113403 +#endif
113404 + case FM_PCD_IOC_PLCR_PROFILE_SET:
113405 + {
113406 + ioc_fm_pcd_plcr_profile_params_t *param;
113407 +
113408 + param = (ioc_fm_pcd_plcr_profile_params_t *) XX_Malloc(
113409 + sizeof(ioc_fm_pcd_plcr_profile_params_t));
113410 + if (!param)
113411 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113412 +
113413 + memset(param, 0, sizeof(ioc_fm_pcd_plcr_profile_params_t));
113414 +
113415 +#if defined(CONFIG_COMPAT)
113416 + if (compat)
113417 + {
113418 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
113419 +
113420 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
113421 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113422 + if (!compat_param)
113423 + {
113424 + XX_Free(param);
113425 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113426 + }
113427 +
113428 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113429 + if (copy_from_user(compat_param, (
113430 + ioc_compat_fm_pcd_plcr_profile_params_t *)compat_ptr(arg),
113431 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
113432 + {
113433 + XX_Free(compat_param);
113434 + XX_Free(param);
113435 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113436 + }
113437 +
113438 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_US_TO_K);
113439 +
113440 + XX_Free(compat_param);
113441 + }
113442 + else
113443 +#endif
113444 + {
113445 + if (copy_from_user(param, (ioc_fm_pcd_plcr_profile_params_t *)arg,
113446 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
113447 + {
113448 + XX_Free(param);
113449 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113450 + }
113451 + }
113452 +
113453 + if (!param->modify &&
113454 + (((t_FmPcdPlcrProfileParams*)param)->id.newParams.profileType != e_FM_PCD_PLCR_SHARED))
113455 + {
113456 + t_Handle h_Port;
113457 + ioc_fm_pcd_port_params_t *port_params;
113458 +
113459 + port_params = (ioc_fm_pcd_port_params_t*) XX_Malloc(sizeof(ioc_fm_pcd_port_params_t));
113460 + if (!port_params)
113461 + {
113462 + XX_Free(param);
113463 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113464 + }
113465 +
113466 + memset(port_params, 0, sizeof(ioc_fm_pcd_port_params_t));
113467 + if (copy_from_user(port_params, (ioc_fm_pcd_port_params_t*)((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort,
113468 + sizeof(ioc_fm_pcd_port_params_t)))
113469 + {
113470 + XX_Free(port_params);
113471 + XX_Free(param);
113472 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113473 + }
113474 +
113475 + switch(port_params->port_type)
113476 + {
113477 + case (e_IOC_FM_PORT_TYPE_RX):
113478 + if (port_params->port_id < FM_MAX_NUM_OF_1G_RX_PORTS) {
113479 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
113480 + break;
113481 + }
113482 + goto invalid_port_id;
113483 +
113484 + case (e_IOC_FM_PORT_TYPE_RX_10G):
113485 + if (port_params->port_id < FM_MAX_NUM_OF_10G_RX_PORTS) {
113486 +#ifndef CONFIG_FMAN_ARM
113487 + if (IS_T1023_T1024) {
113488 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
113489 + } else {
113490 +#else
113491 + {
113492 +#endif
113493 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id + FM_MAX_NUM_OF_1G_RX_PORTS].h_Dev;
113494 + }
113495 + break;
113496 + }
113497 + goto invalid_port_id;
113498 +
113499 + case (e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING):
113500 + if (port_params->port_id && port_params->port_id < FM_MAX_NUM_OF_OH_PORTS) {
113501 + h_Port = p_LnxWrpFmDev->opPorts[port_params->port_id - 1].h_Dev;
113502 + break;
113503 + }
113504 + goto invalid_port_id;
113505 +
113506 + default:
113507 +invalid_port_id:
113508 + XX_Free(port_params);
113509 + XX_Free(param);
113510 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
113511 + }
113512 +
113513 + ((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort = h_Port;
113514 + XX_Free(port_params);
113515 + }
113516 +
113517 + param->id = FM_PCD_PlcrProfileSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPlcrProfileParams*)param);
113518 +
113519 + if (!param->id) {
113520 + XX_Free(param);
113521 + err = E_INVALID_VALUE;
113522 + /* Since the LLD has no errno-style error reporting,
113523 + we're left here with no other option than to report
113524 + a generic E_INVALID_VALUE */
113525 + break;
113526 + }
113527 +
113528 +#if defined(CONFIG_COMPAT)
113529 + if (compat)
113530 + {
113531 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
113532 +
113533 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
113534 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113535 + if (!compat_param)
113536 + {
113537 + XX_Free(param);
113538 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113539 + }
113540 +
113541 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113542 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_K_TO_US);
113543 + if (copy_to_user((ioc_compat_fm_pcd_plcr_profile_params_t *) compat_ptr(arg),
113544 + compat_param,
113545 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
113546 + err = E_READ_FAILED;
113547 +
113548 + XX_Free(compat_param);
113549 + }
113550 + else
113551 +#endif
113552 + {
113553 + if (copy_to_user((ioc_fm_pcd_plcr_profile_params_t *)arg,
113554 + param,
113555 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
113556 + err = E_READ_FAILED;
113557 + }
113558 +
113559 + XX_Free(param);
113560 + break;
113561 + }
113562 +
113563 +#if defined(CONFIG_COMPAT)
113564 + case FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT:
113565 +#endif
113566 + case FM_PCD_IOC_PLCR_PROFILE_DELETE:
113567 + {
113568 + ioc_fm_obj_t id;
113569 +
113570 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113571 +
113572 +#if defined(CONFIG_COMPAT)
113573 + if (compat)
113574 + {
113575 + ioc_compat_fm_obj_t compat_id;
113576 +
113577 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113578 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113579 +
113580 + compat_obj_delete(&compat_id, &id);
113581 + }
113582 + else
113583 +#endif
113584 + {
113585 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113586 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113587 + }
113588 +
113589 + err = FM_PCD_PlcrProfileDelete(id.obj);
113590 + break;
113591 + }
113592 +
113593 +#if defined(CONFIG_COMPAT)
113594 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT:
113595 +#endif
113596 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE:
113597 + {
113598 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param;
113599 +
113600 + param = (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
113601 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
113602 + if (!param)
113603 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113604 +
113605 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
113606 +
113607 +#if defined(CONFIG_COMPAT)
113608 + if (compat)
113609 + {
113610 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param;
113611 +
113612 + compat_param = (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
113613 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
113614 + if (!compat_param)
113615 + {
113616 + XX_Free(param);
113617 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113618 + }
113619 +
113620 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
113621 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) compat_ptr(arg),
113622 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)))
113623 + {
113624 + XX_Free(compat_param);
113625 + XX_Free(param);
113626 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113627 + }
113628 +
113629 + compat_fm_pcd_cc_tree_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113630 +
113631 + XX_Free(compat_param);
113632 + }
113633 + else
113634 +#endif
113635 + {
113636 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *)arg,
113637 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)))
113638 + {
113639 + XX_Free(param);
113640 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113641 + }
113642 + }
113643 +
113644 + err = FM_PCD_CcRootModifyNextEngine(param->id,
113645 + param->grp_indx,
113646 + param->indx,
113647 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113648 +
113649 + XX_Free(param);
113650 + break;
113651 + }
113652 +
113653 +#if defined(CONFIG_COMPAT)
113654 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT:
113655 +#endif
113656 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE:
113657 + {
113658 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
113659 +
113660 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113661 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113662 + if (!param)
113663 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113664 +
113665 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113666 +
113667 +#if defined(CONFIG_COMPAT)
113668 + if (compat)
113669 + {
113670 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
113671 +
113672 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113673 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113674 + if (!compat_param)
113675 + {
113676 + XX_Free(param);
113677 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113678 + }
113679 +
113680 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113681 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
113682 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
113683 + {
113684 + XX_Free(compat_param);
113685 + XX_Free(param);
113686 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113687 + }
113688 +
113689 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113690 +
113691 + XX_Free(compat_param);
113692 + }
113693 + else
113694 +#endif
113695 + {
113696 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *)arg,
113697 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113698 + {
113699 + XX_Free(param);
113700 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113701 + }
113702 + }
113703 +
113704 + err = FM_PCD_MatchTableModifyNextEngine(param->id,
113705 + param->key_indx,
113706 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113707 +
113708 + XX_Free(param);
113709 + break;
113710 + }
113711 +
113712 +#if defined(CONFIG_COMPAT)
113713 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT:
113714 +#endif
113715 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE:
113716 + {
113717 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
113718 +
113719 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113720 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113721 + if (!param)
113722 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113723 +
113724 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113725 +
113726 +#if defined(CONFIG_COMPAT)
113727 + if (compat)
113728 + {
113729 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
113730 +
113731 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113732 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113733 + if (!compat_param)
113734 + {
113735 + XX_Free(param);
113736 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113737 + }
113738 +
113739 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113740 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
113741 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
113742 + {
113743 + XX_Free(compat_param);
113744 + XX_Free(param);
113745 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113746 + }
113747 +
113748 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113749 +
113750 + XX_Free(compat_param);
113751 + }
113752 + else
113753 +#endif
113754 + {
113755 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) arg,
113756 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113757 + {
113758 + XX_Free(param);
113759 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113760 + }
113761 + }
113762 +
113763 + err = FM_PCD_MatchTableModifyMissNextEngine(param->id,
113764 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113765 +
113766 + XX_Free(param);
113767 + break;
113768 + }
113769 +
113770 +#if defined(CONFIG_COMPAT)
113771 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT:
113772 +#endif
113773 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY:
113774 + {
113775 + ioc_fm_pcd_cc_node_remove_key_params_t *param;
113776 +
113777 + param = (ioc_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113778 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113779 + if (!param)
113780 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113781 +
113782 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113783 +
113784 +#if defined(CONFIG_COMPAT)
113785 + if (compat)
113786 + {
113787 + ioc_compat_fm_pcd_cc_node_remove_key_params_t *compat_param;
113788 +
113789 + compat_param = (ioc_compat_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113790 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113791 + if (!compat_param)
113792 + {
113793 + XX_Free(param);
113794 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113795 + }
113796 +
113797 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113798 + if (copy_from_user(compat_param,
113799 + (ioc_compat_fm_pcd_cc_node_remove_key_params_t *)compat_ptr(arg),
113800 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)))
113801 + {
113802 + XX_Free(compat_param);
113803 + XX_Free(param);
113804 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113805 + }
113806 +
113807 + param->id = compat_ptr(compat_param->id);
113808 + param->key_indx = compat_param->key_indx;
113809 +
113810 + XX_Free(compat_param);
113811 + }
113812 + else
113813 +#endif
113814 + {
113815 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_remove_key_params_t *) arg,
113816 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)))
113817 + {
113818 + XX_Free(param);
113819 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113820 + }
113821 + }
113822 +
113823 + err = FM_PCD_MatchTableRemoveKey(param->id, param->key_indx);
113824 +
113825 + XX_Free(param);
113826 + break;
113827 + }
113828 +#if defined(CONFIG_COMPAT)
113829 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT:
113830 +#endif
113831 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY:
113832 + {
113833 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113834 +
113835 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113836 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113837 + if (!param)
113838 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113839 +
113840 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113841 +
113842 +#if defined(CONFIG_COMPAT)
113843 + if (compat)
113844 + {
113845 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113846 +
113847 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113848 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113849 + if (!compat_param)
113850 + {
113851 + XX_Free(param);
113852 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113853 + }
113854 +
113855 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113856 + if (copy_from_user(compat_param,
113857 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113858 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113859 + {
113860 + XX_Free(compat_param);
113861 + XX_Free(param);
113862 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113863 + }
113864 +
113865 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113866 +
113867 + XX_Free(compat_param);
113868 + }
113869 + else
113870 +#endif
113871 + {
113872 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113873 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113874 + {
113875 + XX_Free(param);
113876 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113877 + }
113878 + }
113879 +
113880 + if (param->key_size)
113881 + {
113882 + int size = 0;
113883 +
113884 + if (param->key_params.p_key) size += param->key_size;
113885 + if (param->key_params.p_mask) size += param->key_size;
113886 +
113887 + if (size)
113888 + {
113889 + uint8_t *p_tmp;
113890 +
113891 + p_tmp = (uint8_t*) XX_Malloc(size);
113892 + if (!p_tmp)
113893 + {
113894 + XX_Free(param);
113895 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
113896 + }
113897 +
113898 + if (param->key_params.p_key)
113899 + {
113900 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
113901 + {
113902 + XX_Free(p_tmp);
113903 + XX_Free(param);
113904 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113905 + }
113906 +
113907 + param->key_params.p_key = p_tmp;
113908 + }
113909 +
113910 + if (param->key_params.p_mask)
113911 + {
113912 + p_tmp += param->key_size;
113913 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
113914 + {
113915 + XX_Free(p_tmp - param->key_size);
113916 + XX_Free(param);
113917 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113918 + }
113919 +
113920 + param->key_params.p_mask = p_tmp;
113921 + }
113922 + }
113923 + }
113924 +
113925 + err = FM_PCD_MatchTableAddKey(
113926 + param->id,
113927 + param->key_indx,
113928 + param->key_size,
113929 + (t_FmPcdCcKeyParams*)&param->key_params);
113930 +
113931 + if (param->key_params.p_key)
113932 + XX_Free(param->key_params.p_key);
113933 + XX_Free(param);
113934 + break;
113935 + }
113936 +
113937 +#if defined(CONFIG_COMPAT)
113938 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT:
113939 +#endif
113940 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE:
113941 + {
113942 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113943 +
113944 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113945 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113946 + if (!param)
113947 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113948 +
113949 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113950 +
113951 +#if defined(CONFIG_COMPAT)
113952 + if (compat)
113953 + {
113954 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113955 +
113956 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113957 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113958 + if (!compat_param)
113959 + {
113960 + XX_Free(param);
113961 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113962 + }
113963 +
113964 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113965 + if (copy_from_user(compat_param,
113966 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113967 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113968 + {
113969 + XX_Free(compat_param);
113970 + XX_Free(param);
113971 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113972 + }
113973 +
113974 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113975 +
113976 + XX_Free(compat_param);
113977 + }
113978 + else
113979 +#endif
113980 + {
113981 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113982 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113983 + {
113984 + XX_Free(param);
113985 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113986 + }
113987 + }
113988 +
113989 + err = FM_PCD_MatchTableModifyKeyAndNextEngine(param->id,
113990 + param->key_indx,
113991 + param->key_size,
113992 + (t_FmPcdCcKeyParams*)(&param->key_params));
113993 +
113994 + XX_Free(param);
113995 + break;
113996 + }
113997 +
113998 +
113999 +#if defined(CONFIG_COMPAT)
114000 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT:
114001 +#endif
114002 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT:
114003 + {
114004 + ioc_fm_pcd_cc_tbl_get_stats_t param;
114005 +
114006 +#if defined(CONFIG_COMPAT)
114007 + if (compat)
114008 + {
114009 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
114010 +
114011 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
114012 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114013 + if (!compat_param)
114014 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114015 +
114016 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114017 + if (copy_from_user(compat_param,
114018 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
114019 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
114020 + {
114021 + XX_Free(compat_param);
114022 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114023 + }
114024 +
114025 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
114026 +
114027 + XX_Free(compat_param);
114028 + }
114029 + else
114030 +#endif
114031 + {
114032 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
114033 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
114034 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114035 + }
114036 +
114037 +
114038 + err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id,
114039 + param.key_index,
114040 + (t_FmPcdCcKeyStatistics *) &param.statistics);
114041 +
114042 +#if defined(CONFIG_COMPAT)
114043 + if (compat)
114044 + {
114045 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
114046 +
114047 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
114048 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114049 + if (!compat_param)
114050 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114051 +
114052 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114053 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
114054 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
114055 + compat_param,
114056 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
114057 + XX_Free(compat_param);
114058 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114059 + }
114060 + XX_Free(compat_param);
114061 + }
114062 + else
114063 +#endif
114064 + {
114065 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
114066 + &param,
114067 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
114068 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114069 + }
114070 +
114071 + break;
114072 + }
114073 +
114074 +
114075 +#if defined(CONFIG_COMPAT)
114076 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT:
114077 +#endif
114078 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT:
114079 + {
114080 + ioc_fm_pcd_cc_tbl_get_stats_t param;
114081 +
114082 +#if defined(CONFIG_COMPAT)
114083 + if (compat)
114084 + {
114085 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
114086 +
114087 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
114088 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114089 + if (!compat_param)
114090 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114091 +
114092 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114093 + if (copy_from_user(compat_param,
114094 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
114095 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
114096 + {
114097 + XX_Free(compat_param);
114098 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114099 + }
114100 +
114101 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
114102 +
114103 + XX_Free(compat_param);
114104 + }
114105 + else
114106 +#endif
114107 + {
114108 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
114109 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
114110 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114111 + }
114112 +
114113 +
114114 + err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id,
114115 + (t_FmPcdCcKeyStatistics *) &param.statistics);
114116 +
114117 +#if defined(CONFIG_COMPAT)
114118 + if (compat)
114119 + {
114120 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
114121 +
114122 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
114123 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114124 + if (!compat_param)
114125 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114126 +
114127 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114128 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
114129 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
114130 + compat_param,
114131 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
114132 + XX_Free(compat_param);
114133 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114134 + }
114135 + XX_Free(compat_param);
114136 + }
114137 + else
114138 +#endif
114139 + {
114140 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
114141 + &param,
114142 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
114143 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114144 + }
114145 +
114146 + break;
114147 + }
114148 +
114149 +
114150 +#if defined(CONFIG_COMPAT)
114151 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT:
114152 +#endif
114153 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT:
114154 + {
114155 + ioc_fm_pcd_cc_tbl_get_stats_t param;
114156 +
114157 +#if defined(CONFIG_COMPAT)
114158 + if (compat)
114159 + {
114160 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
114161 +
114162 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
114163 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114164 + if (!compat_param)
114165 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114166 +
114167 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114168 + if (copy_from_user(compat_param,
114169 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
114170 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
114171 + {
114172 + XX_Free(compat_param);
114173 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114174 + }
114175 +
114176 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
114177 +
114178 + XX_Free(compat_param);
114179 + }
114180 + else
114181 +#endif
114182 + {
114183 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
114184 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
114185 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114186 + }
114187 +
114188 +
114189 + err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id,
114190 + (t_FmPcdCcKeyStatistics *) &param.statistics);
114191 +
114192 +#if defined(CONFIG_COMPAT)
114193 + if (compat)
114194 + {
114195 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
114196 +
114197 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
114198 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114199 + if (!compat_param)
114200 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114201 +
114202 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114203 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
114204 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
114205 + compat_param,
114206 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
114207 + XX_Free(compat_param);
114208 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114209 + }
114210 + XX_Free(compat_param);
114211 + }
114212 + else
114213 +#endif
114214 + {
114215 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
114216 + &param,
114217 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
114218 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114219 + }
114220 +
114221 + break;
114222 + }
114223 +
114224 +#if defined(CONFIG_COMPAT)
114225 + case FM_PCD_IOC_HASH_TABLE_SET_COMPAT:
114226 +#endif
114227 + case FM_PCD_IOC_HASH_TABLE_SET:
114228 + {
114229 + ioc_fm_pcd_hash_table_params_t *param;
114230 +
114231 + param = (ioc_fm_pcd_hash_table_params_t*) XX_Malloc(
114232 + sizeof(ioc_fm_pcd_hash_table_params_t));
114233 + if (!param)
114234 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114235 +
114236 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_params_t));
114237 +
114238 +#if defined(CONFIG_COMPAT)
114239 + if (compat)
114240 + {
114241 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
114242 +
114243 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
114244 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
114245 + if (!compat_param)
114246 + {
114247 + XX_Free(param);
114248 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114249 + }
114250 +
114251 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
114252 + if (copy_from_user(compat_param,
114253 + (ioc_compat_fm_pcd_hash_table_params_t*)compat_ptr(arg),
114254 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
114255 + {
114256 + XX_Free(compat_param);
114257 + XX_Free(param);
114258 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114259 + }
114260 +
114261 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_US_TO_K);
114262 +
114263 + XX_Free(compat_param);
114264 + }
114265 + else
114266 +#endif
114267 + {
114268 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_params_t *)arg,
114269 + sizeof(ioc_fm_pcd_hash_table_params_t)))
114270 + {
114271 + XX_Free(param);
114272 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114273 + }
114274 + }
114275 +
114276 + param->id = FM_PCD_HashTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdHashTableParams *) param);
114277 +
114278 + if (!param->id)
114279 + {
114280 + XX_Free(param);
114281 + err = E_INVALID_VALUE;
114282 + /* Since the LLD has no errno-style error reporting,
114283 + we're left here with no other option than to report
114284 + a generic E_INVALID_VALUE */
114285 + break;
114286 + }
114287 +
114288 +#if defined(CONFIG_COMPAT)
114289 + if (compat)
114290 + {
114291 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
114292 +
114293 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
114294 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
114295 + if (!compat_param)
114296 + {
114297 + XX_Free(param);
114298 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114299 + }
114300 +
114301 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
114302 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_K_TO_US);
114303 + if (copy_to_user((ioc_compat_fm_pcd_hash_table_params_t*) compat_ptr(arg),
114304 + compat_param,
114305 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
114306 + err = E_READ_FAILED;
114307 +
114308 + XX_Free(compat_param);
114309 + }
114310 + else
114311 +#endif
114312 + {
114313 + if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
114314 + param,
114315 + sizeof(ioc_fm_pcd_hash_table_params_t)))
114316 + err = E_READ_FAILED;
114317 + }
114318 +
114319 + XX_Free(param);
114320 + break;
114321 + }
114322 +
114323 +#if defined(CONFIG_COMPAT)
114324 + case FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT:
114325 +#endif
114326 + case FM_PCD_IOC_HASH_TABLE_DELETE:
114327 + {
114328 + ioc_fm_obj_t id;
114329 +
114330 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114331 +
114332 +#if defined(CONFIG_COMPAT)
114333 + if (compat)
114334 + {
114335 + ioc_compat_fm_obj_t compat_id;
114336 +
114337 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114338 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114339 +
114340 + id.obj = compat_pcd_id2ptr(compat_id.obj);
114341 + }
114342 + else
114343 +#endif
114344 + {
114345 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114346 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114347 + }
114348 +
114349 + err = FM_PCD_HashTableDelete(id.obj);
114350 + break;
114351 + }
114352 +
114353 +#if defined(CONFIG_COMPAT)
114354 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT:
114355 +#endif
114356 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY:
114357 + {
114358 + ioc_fm_pcd_hash_table_add_key_params_t *param = NULL;
114359 +
114360 + param = (ioc_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
114361 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
114362 + if (!param)
114363 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114364 +
114365 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
114366 +
114367 +#if defined(CONFIG_COMPAT)
114368 + if (compat)
114369 + {
114370 + ioc_compat_fm_pcd_hash_table_add_key_params_t *compat_param;
114371 +
114372 + compat_param = (ioc_compat_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
114373 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
114374 + if (!compat_param)
114375 + {
114376 + XX_Free(param);
114377 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114378 + }
114379 +
114380 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
114381 + if (copy_from_user(compat_param,
114382 + (ioc_compat_fm_pcd_hash_table_add_key_params_t*) compat_ptr(arg),
114383 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)))
114384 + {
114385 + XX_Free(compat_param);
114386 + XX_Free(param);
114387 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114388 + }
114389 +
114390 + if (compat_param->key_size)
114391 + {
114392 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
114393 + param->key_size = compat_param->key_size;
114394 +
114395 + compat_copy_fm_pcd_cc_key(&compat_param->key_params, &param->key_params, COMPAT_US_TO_K);
114396 + }
114397 + else
114398 + {
114399 + XX_Free(compat_param);
114400 + XX_Free(param);
114401 + err = E_INVALID_VALUE;
114402 + break;
114403 + }
114404 +
114405 + XX_Free(compat_param);
114406 + }
114407 + else
114408 +#endif
114409 + {
114410 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_add_key_params_t*) arg,
114411 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t)))
114412 + {
114413 + XX_Free(param);
114414 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114415 + }
114416 + }
114417 +
114418 + if (param->key_size)
114419 + {
114420 + int size = 0;
114421 +
114422 + if (param->key_params.p_key) size += param->key_size;
114423 + if (param->key_params.p_mask) size += param->key_size;
114424 +
114425 + if (size)
114426 + {
114427 + uint8_t *p_tmp;
114428 +
114429 + p_tmp = (uint8_t*) XX_Malloc(size);
114430 + if (!p_tmp)
114431 + {
114432 + XX_Free(param);
114433 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
114434 + }
114435 +
114436 + if (param->key_params.p_key)
114437 + {
114438 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
114439 + {
114440 + XX_Free(p_tmp);
114441 + XX_Free(param);
114442 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114443 + }
114444 +
114445 + param->key_params.p_key = p_tmp;
114446 + }
114447 +
114448 + if (param->key_params.p_mask)
114449 + {
114450 + p_tmp += param->key_size;
114451 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
114452 + {
114453 + XX_Free(p_tmp - param->key_size);
114454 + XX_Free(param);
114455 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114456 + }
114457 +
114458 + param->key_params.p_mask = p_tmp;
114459 + }
114460 + }
114461 + }
114462 +
114463 + err = FM_PCD_HashTableAddKey(
114464 + param->p_hash_tbl,
114465 + param->key_size,
114466 + (t_FmPcdCcKeyParams*)&param->key_params);
114467 +
114468 + if (param->key_params.p_key)
114469 + XX_Free(param->key_params.p_key);
114470 + XX_Free(param);
114471 + break;
114472 + }
114473 +
114474 +#if defined(CONFIG_COMPAT)
114475 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT:
114476 +#endif
114477 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY:
114478 + {
114479 + ioc_fm_pcd_hash_table_remove_key_params_t *param = NULL;
114480 +
114481 + param = (ioc_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
114482 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
114483 + if (!param)
114484 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114485 +
114486 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
114487 +
114488 +#if defined(CONFIG_COMPAT)
114489 + if (compat)
114490 + {
114491 + ioc_compat_fm_pcd_hash_table_remove_key_params_t *compat_param;
114492 +
114493 + compat_param = (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
114494 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
114495 + if (!compat_param)
114496 + {
114497 + XX_Free(param);
114498 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114499 + }
114500 +
114501 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
114502 + if (copy_from_user(compat_param,
114503 + (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) compat_ptr(arg),
114504 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)))
114505 + {
114506 + XX_Free(compat_param);
114507 + XX_Free(param);
114508 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114509 + }
114510 +
114511 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
114512 + param->key_size = compat_param->key_size;
114513 +
114514 + XX_Free(compat_param);
114515 + }
114516 + else
114517 +#endif
114518 + {
114519 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_remove_key_params_t*)arg,
114520 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)))
114521 + {
114522 + XX_Free(param);
114523 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114524 + }
114525 + }
114526 +
114527 + if (param->key_size)
114528 + {
114529 + uint8_t *p_key;
114530 +
114531 + p_key = (uint8_t*) XX_Malloc(param->key_size);
114532 + if (!p_key)
114533 + {
114534 + XX_Free(param);
114535 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114536 + }
114537 +
114538 + if (param->p_key && copy_from_user(p_key, param->p_key, param->key_size))
114539 + {
114540 + XX_Free(p_key);
114541 + XX_Free(param);
114542 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114543 + }
114544 + param->p_key = p_key;
114545 + }
114546 +
114547 + err = FM_PCD_HashTableRemoveKey(
114548 + param->p_hash_tbl,
114549 + param->key_size,
114550 + param->p_key);
114551 +
114552 + if (param->p_key)
114553 + XX_Free(param->p_key);
114554 + XX_Free(param);
114555 + break;
114556 + }
114557 +
114558 +#if defined(CONFIG_COMPAT)
114559 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT:
114560 +#endif
114561 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY:
114562 + {
114563 + ioc_fm_pcd_cc_node_modify_key_params_t *param;
114564 +
114565 + param = (ioc_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
114566 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
114567 + if (!param)
114568 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114569 +
114570 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
114571 +
114572 +#if defined(CONFIG_COMPAT)
114573 + if (compat)
114574 + {
114575 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param;
114576 +
114577 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
114578 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
114579 + if (!compat_param)
114580 + {
114581 + XX_Free(param);
114582 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114583 + }
114584 +
114585 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
114586 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_key_params_t *)compat_ptr(arg),
114587 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)))
114588 + {
114589 + XX_Free(compat_param);
114590 + XX_Free(param);
114591 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114592 + }
114593 +
114594 + compat_copy_fm_pcd_cc_node_modify_key(compat_param, param, COMPAT_US_TO_K);
114595 +
114596 + XX_Free(compat_param);
114597 + }
114598 + else
114599 +#endif
114600 + {
114601 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_params_t *)arg,
114602 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)))
114603 + {
114604 + XX_Free(param);
114605 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114606 + }
114607 + }
114608 +
114609 + if (param->key_size)
114610 + {
114611 + int size = 0;
114612 +
114613 + if (param->p_key) size += param->key_size;
114614 + if (param->p_mask) size += param->key_size;
114615 +
114616 + if (size)
114617 + {
114618 + uint8_t *p_tmp;
114619 +
114620 + p_tmp = (uint8_t*) XX_Malloc(size);
114621 + if (!p_tmp)
114622 + {
114623 + XX_Free(param);
114624 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
114625 + }
114626 +
114627 + if (param->p_key)
114628 + {
114629 + if (copy_from_user(p_tmp, param->p_key, param->key_size))
114630 + {
114631 + XX_Free(p_tmp);
114632 + XX_Free(param);
114633 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114634 + }
114635 +
114636 + param->p_key = p_tmp;
114637 + }
114638 +
114639 + if (param->p_mask)
114640 + {
114641 + p_tmp += param->key_size;
114642 + if (copy_from_user(p_tmp, param->p_mask, param->key_size))
114643 + {
114644 + XX_Free(p_tmp - param->key_size);
114645 + XX_Free(param);
114646 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114647 + }
114648 +
114649 + param->p_mask = p_tmp;
114650 + }
114651 + }
114652 + }
114653 +
114654 + err = FM_PCD_MatchTableModifyKey(param->id,
114655 + param->key_indx,
114656 + param->key_size,
114657 + param->p_key,
114658 + param->p_mask);
114659 +
114660 + if (param->p_key)
114661 + XX_Free(param->p_key);
114662 + else if (param->p_mask)
114663 + XX_Free(param->p_mask);
114664 + XX_Free(param);
114665 + break;
114666 + }
114667 +
114668 +#if defined(CONFIG_COMPAT)
114669 + case FM_PCD_IOC_MANIP_NODE_SET_COMPAT:
114670 +#endif
114671 + case FM_PCD_IOC_MANIP_NODE_SET:
114672 + {
114673 + ioc_fm_pcd_manip_params_t *param;
114674 + uint8_t *p_data = NULL;
114675 + uint8_t size;
114676 +
114677 + param = (ioc_fm_pcd_manip_params_t *) XX_Malloc(
114678 + sizeof(ioc_fm_pcd_manip_params_t));
114679 +
114680 + if (!param)
114681 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114682 +
114683 + memset(param, 0, sizeof(ioc_fm_pcd_manip_params_t));
114684 +
114685 +#if defined(CONFIG_COMPAT)
114686 + if (compat)
114687 + {
114688 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114689 +
114690 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114691 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114692 + if (!compat_param)
114693 + {
114694 + XX_Free(param);
114695 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114696 + }
114697 +
114698 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114699 + if (copy_from_user(compat_param,
114700 + (ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114701 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114702 + {
114703 + XX_Free(compat_param);
114704 + XX_Free(param);
114705 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114706 + }
114707 +
114708 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_US_TO_K);
114709 +
114710 + XX_Free(compat_param);
114711 + }
114712 + else
114713 +#endif
114714 + {
114715 + if (copy_from_user(param, (ioc_fm_pcd_manip_params_t *)arg,
114716 + sizeof(ioc_fm_pcd_manip_params_t)))
114717 + {
114718 + XX_Free(param);
114719 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114720 + }
114721 + }
114722 +
114723 + if (param->type == e_IOC_FM_PCD_MANIP_HDR)
114724 + {
114725 + size = param->u.hdr.insrt_params.u.generic.size;
114726 + p_data = (uint8_t *) XX_Malloc(size);
114727 + if (!p_data )
114728 + {
114729 + XX_Free(param);
114730 + RETURN_ERROR(MINOR, E_NO_MEMORY, NO_MSG);
114731 + }
114732 +
114733 + if (param->u.hdr.insrt_params.u.generic.p_data &&
114734 + copy_from_user(p_data,
114735 + param->u.hdr.insrt_params.u.generic.p_data, size))
114736 + {
114737 + XX_Free(p_data);
114738 + XX_Free(param);
114739 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114740 + }
114741 +
114742 + param->u.hdr.insrt_params.u.generic.p_data = p_data;
114743 + }
114744 +
114745 + if (param->id)
114746 + {
114747 + /* Security Hole: the user can pass any piece of garbage
114748 + in 'param->id', and that will go straight through to the LLD,
114749 + no checks being done by the wrapper! */
114750 + err = FM_PCD_ManipNodeReplace(
114751 + (t_Handle) param->id,
114752 + (t_FmPcdManipParams*) param);
114753 + if (err)
114754 + {
114755 + if (p_data)
114756 + XX_Free(p_data);
114757 + XX_Free(param);
114758 + break;
114759 + }
114760 + }
114761 + else
114762 + {
114763 + param->id = FM_PCD_ManipNodeSet(
114764 + p_LnxWrpFmDev->h_PcdDev,
114765 + (t_FmPcdManipParams*) param);
114766 + if (!param->id)
114767 + {
114768 + if (p_data)
114769 + XX_Free(p_data);
114770 + XX_Free(param);
114771 + err = E_INVALID_VALUE;
114772 + /* Since the LLD has no errno-style error reporting,
114773 + we're left here with no other option than to report
114774 + a generic E_INVALID_VALUE */
114775 + break;
114776 + }
114777 + }
114778 +
114779 +#if defined(CONFIG_COMPAT)
114780 + if (compat)
114781 + {
114782 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114783 +
114784 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114785 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114786 + if (!compat_param)
114787 + {
114788 + if (p_data)
114789 + XX_Free(p_data);
114790 + XX_Free(param);
114791 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114792 + }
114793 +
114794 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114795 +
114796 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_K_TO_US);
114797 +
114798 + if (copy_to_user((ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114799 + compat_param,
114800 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114801 + err = E_READ_FAILED;
114802 +
114803 + XX_Free(compat_param);
114804 + }
114805 + else
114806 +#endif
114807 + {
114808 + if (copy_to_user((ioc_fm_pcd_manip_params_t *)arg,
114809 + param, sizeof(ioc_fm_pcd_manip_params_t)))
114810 + err = E_READ_FAILED;
114811 + }
114812 +
114813 + if (p_data)
114814 + XX_Free(p_data);
114815 + XX_Free(param);
114816 + break;
114817 + }
114818 +
114819 +#if defined(CONFIG_COMPAT)
114820 + case FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT:
114821 +#endif
114822 + case FM_PCD_IOC_MANIP_NODE_DELETE:
114823 + {
114824 + ioc_fm_obj_t id;
114825 +
114826 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114827 +#if defined(CONFIG_COMPAT)
114828 + if (compat)
114829 + {
114830 + ioc_compat_fm_obj_t compat_id;
114831 +
114832 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114833 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114834 +
114835 + compat_obj_delete(&compat_id, &id);
114836 + }
114837 + else
114838 +#endif
114839 + {
114840 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114841 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114842 + }
114843 +
114844 + err = FM_PCD_ManipNodeDelete(id.obj);
114845 + break;
114846 + }
114847 +
114848 +#if defined(CONFIG_COMPAT)
114849 + case FM_PCD_IOC_MANIP_GET_STATS_COMPAT:
114850 +#endif
114851 + case FM_PCD_IOC_MANIP_GET_STATS:
114852 + {
114853 + ioc_fm_pcd_manip_get_stats_t param;
114854 +
114855 +#if defined(CONFIG_COMPAT)
114856 + if (compat)
114857 + {
114858 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114859 +
114860 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t *) XX_Malloc(
114861 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114862 + if (!compat_param)
114863 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114864 +
114865 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114866 + if (copy_from_user(compat_param,
114867 + (ioc_compat_fm_pcd_manip_get_stats_t *)compat_ptr(arg),
114868 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t)))
114869 + {
114870 + XX_Free(compat_param);
114871 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114872 + }
114873 +
114874 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_US_TO_K);
114875 +
114876 + XX_Free(compat_param);
114877 + }
114878 + else
114879 +#endif
114880 + {
114881 + if (copy_from_user(&param, (ioc_fm_pcd_manip_get_stats_t *)arg,
114882 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114883 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114884 + }
114885 +
114886 + err = FM_PCD_ManipGetStatistics((t_Handle) param.id,
114887 + (t_FmPcdManipStats*) &param.stats);
114888 +
114889 +#if defined(CONFIG_COMPAT)
114890 + if (compat)
114891 + {
114892 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114893 +
114894 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t*) XX_Malloc(
114895 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114896 + if (!compat_param)
114897 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114898 +
114899 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114900 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_K_TO_US);
114901 + if (copy_to_user((ioc_compat_fm_pcd_manip_get_stats_t*) compat_ptr(arg),
114902 + compat_param,
114903 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t))){
114904 + XX_Free(compat_param);
114905 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114906 + }
114907 + XX_Free(compat_param);
114908 + }
114909 + else
114910 +#endif
114911 + if (copy_to_user((ioc_fm_pcd_manip_get_stats_t *)arg,
114912 + &param,
114913 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114914 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114915 +
114916 + break;
114917 + }
114918 +
114919 +#if (DPAA_VERSION >= 11)
114920 +#if defined(CONFIG_COMPAT)
114921 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT:
114922 +#endif
114923 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET:
114924 + {
114925 + ioc_fm_pcd_frm_replic_group_params_t *param;
114926 +
114927 + param = (ioc_fm_pcd_frm_replic_group_params_t *) XX_Malloc(
114928 + sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114929 + if (!param)
114930 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114931 +
114932 + memset(param, 0, sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114933 +
114934 +#if defined(CONFIG_COMPAT)
114935 + if (compat)
114936 + {
114937 + ioc_compat_fm_pcd_frm_replic_group_params_t
114938 + *compat_param;
114939 +
114940 + compat_param =
114941 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114942 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114943 + if (!compat_param)
114944 + {
114945 + XX_Free(param);
114946 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114947 + ("IOCTL FM PCD"));
114948 + }
114949 +
114950 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114951 + if (copy_from_user(compat_param,
114952 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114953 + compat_ptr(arg),
114954 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) {
114955 + XX_Free(compat_param);
114956 + XX_Free(param);
114957 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114958 + }
114959 +
114960 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114961 + param, COMPAT_US_TO_K);
114962 +
114963 + XX_Free(compat_param);
114964 + }
114965 + else
114966 +#endif
114967 + {
114968 + if (copy_from_user(param,
114969 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114970 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114971 + {
114972 + XX_Free(param);
114973 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114974 + }
114975 + }
114976 +
114977 + param->id = FM_PCD_FrmReplicSetGroup(p_LnxWrpFmDev->h_PcdDev,
114978 + (t_FmPcdFrmReplicGroupParams*)param);
114979 +
114980 + if (!param->id) {
114981 + XX_Free(param);
114982 + err = E_INVALID_VALUE;
114983 + /*
114984 + * Since the LLD has no errno-style error reporting,
114985 + * we're left here with no other option than to report
114986 + * a generic E_INVALID_VALUE
114987 + */
114988 + break;
114989 + }
114990 +
114991 +#if defined(CONFIG_COMPAT)
114992 + if (compat)
114993 + {
114994 + ioc_compat_fm_pcd_frm_replic_group_params_t
114995 + *compat_param;
114996 +
114997 + compat_param =
114998 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114999 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
115000 + if (!compat_param)
115001 + {
115002 + XX_Free(param);
115003 + RETURN_ERROR(MINOR, E_NO_MEMORY,
115004 + ("IOCTL FM PCD"));
115005 + }
115006 +
115007 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
115008 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
115009 + param, COMPAT_K_TO_US);
115010 + if (copy_to_user(
115011 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
115012 + compat_ptr(arg),
115013 + compat_param,
115014 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)))
115015 + err = E_WRITE_FAILED;
115016 +
115017 + XX_Free(compat_param);
115018 + }
115019 + else
115020 +#endif
115021 + {
115022 + if (copy_to_user(
115023 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
115024 + param,
115025 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
115026 + err = E_WRITE_FAILED;
115027 + }
115028 +
115029 + XX_Free(param);
115030 + break;
115031 + }
115032 + break;
115033 +
115034 +#if defined(CONFIG_COMPAT)
115035 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT:
115036 +#endif
115037 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE:
115038 + {
115039 + ioc_fm_obj_t id;
115040 +
115041 + memset(&id, 0, sizeof(ioc_fm_obj_t));
115042 +#if defined(CONFIG_COMPAT)
115043 + if (compat)
115044 + {
115045 + ioc_compat_fm_obj_t compat_id;
115046 +
115047 + if (copy_from_user(&compat_id,
115048 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
115049 + sizeof(ioc_compat_fm_obj_t)))
115050 + break;
115051 + compat_obj_delete(&compat_id, &id);
115052 + }
115053 + else
115054 +#endif
115055 + {
115056 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
115057 + sizeof(ioc_fm_obj_t)))
115058 + break;
115059 + }
115060 +
115061 + return FM_PCD_FrmReplicDeleteGroup(id.obj);
115062 + }
115063 + break;
115064 +
115065 +#if defined(CONFIG_COMPAT)
115066 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT:
115067 +#endif
115068 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD:
115069 + {
115070 + ioc_fm_pcd_frm_replic_member_params_t param;
115071 +
115072 +#if defined(CONFIG_COMPAT)
115073 + if (compat)
115074 + {
115075 + ioc_compat_fm_pcd_frm_replic_member_params_t compat_param;
115076 +
115077 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115078 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115079 +
115080 + compat_copy_fm_pcd_frm_replic_member_params(&compat_param, &param, COMPAT_US_TO_K);
115081 + }
115082 + else
115083 +#endif
115084 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115085 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115086 +
115087 + return FM_PCD_FrmReplicAddMember(param.member.h_replic_group,
115088 + param.member.member_index,
115089 + (t_FmPcdCcNextEngineParams*)&param.next_engine_params);
115090 + }
115091 + break;
115092 +
115093 +#if defined(CONFIG_COMPAT)
115094 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT:
115095 +#endif
115096 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE:
115097 + {
115098 + ioc_fm_pcd_frm_replic_member_t param;
115099 +
115100 +#if defined(CONFIG_COMPAT)
115101 + if (compat)
115102 + {
115103 + ioc_compat_fm_pcd_frm_replic_member_t compat_param;
115104 +
115105 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115106 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115107 +
115108 + compat_copy_fm_pcd_frm_replic_member(&compat_param, &param, COMPAT_US_TO_K);
115109 + }
115110 + else
115111 +#endif
115112 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115113 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115114 +
115115 + return FM_PCD_FrmReplicRemoveMember(param.h_replic_group, param.member_index);
115116 + }
115117 + break;
115118 +
115119 +#if defined(CONFIG_COMPAT)
115120 + case FM_IOC_VSP_CONFIG_COMPAT:
115121 +#endif
115122 + case FM_IOC_VSP_CONFIG:
115123 + {
115124 + ioc_fm_vsp_params_t param;
115125 +
115126 +#if defined(CONFIG_COMPAT)
115127 + if (compat)
115128 + {
115129 + ioc_compat_fm_vsp_params_t compat_param;
115130 +
115131 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115132 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115133 +
115134 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_US_TO_K);
115135 + }
115136 + else
115137 +#endif
115138 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115139 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115140 + {
115141 + uint8_t portId = param.port_params.port_id;
115142 + param.liodn_offset =
115143 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
115144 + }
115145 + param.p_fm = p_LnxWrpFmDev->h_Dev;
115146 + param.id = FM_VSP_Config((t_FmVspParams *)&param);
115147 +
115148 +#if defined(CONFIG_COMPAT)
115149 + if (compat)
115150 + {
115151 + ioc_compat_fm_vsp_params_t compat_param;
115152 +
115153 + memset(&compat_param, 0, sizeof(compat_param));
115154 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_K_TO_US);
115155 +
115156 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
115157 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115158 + }
115159 + else
115160 +#endif
115161 + if (copy_to_user((void *)arg, &param, sizeof(param)))
115162 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115163 + break;
115164 + }
115165 +
115166 +#if defined(CONFIG_COMPAT)
115167 + case FM_IOC_VSP_INIT_COMPAT:
115168 +#endif
115169 + case FM_IOC_VSP_INIT:
115170 + {
115171 + ioc_fm_obj_t id;
115172 +
115173 + memset(&id, 0, sizeof(ioc_fm_obj_t));
115174 +#if defined(CONFIG_COMPAT)
115175 + if (compat)
115176 + {
115177 + ioc_compat_fm_obj_t compat_id;
115178 +
115179 + if (copy_from_user(&compat_id,
115180 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
115181 + sizeof(ioc_compat_fm_obj_t)))
115182 + break;
115183 + id.obj = compat_pcd_id2ptr(compat_id.obj);
115184 + }
115185 + else
115186 +#endif
115187 + {
115188 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
115189 + sizeof(ioc_fm_obj_t)))
115190 + break;
115191 + }
115192 +
115193 + return FM_VSP_Init(id.obj);
115194 + }
115195 +
115196 +#if defined(CONFIG_COMPAT)
115197 + case FM_IOC_VSP_FREE_COMPAT:
115198 +#endif
115199 + case FM_IOC_VSP_FREE:
115200 + {
115201 + ioc_fm_obj_t id;
115202 +
115203 + memset(&id, 0, sizeof(ioc_fm_obj_t));
115204 +#if defined(CONFIG_COMPAT)
115205 + if (compat)
115206 + {
115207 + ioc_compat_fm_obj_t compat_id;
115208 +
115209 + if (copy_from_user(&compat_id,
115210 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
115211 + sizeof(ioc_compat_fm_obj_t)))
115212 + break;
115213 + compat_obj_delete(&compat_id, &id);
115214 + }
115215 + else
115216 +#endif
115217 + {
115218 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
115219 + sizeof(ioc_fm_obj_t)))
115220 + break;
115221 + }
115222 +
115223 + return FM_VSP_Free(id.obj);
115224 + }
115225 +
115226 +#if defined(CONFIG_COMPAT)
115227 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT:
115228 +#endif
115229 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION:
115230 + {
115231 + ioc_fm_buf_pool_depletion_params_t param;
115232 +
115233 +#if defined(CONFIG_COMPAT)
115234 + if (compat)
115235 + {
115236 + ioc_compat_fm_buf_pool_depletion_params_t compat_param;
115237 +
115238 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115239 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115240 +
115241 + compat_copy_fm_buf_pool_depletion_params(&compat_param, &param, COMPAT_US_TO_K);
115242 + }
115243 + else
115244 +#endif
115245 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115246 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115247 +
115248 + if (FM_VSP_ConfigPoolDepletion(param.p_fm_vsp,
115249 + (t_FmBufPoolDepletion *)&param.fm_buf_pool_depletion))
115250 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115251 +
115252 + break;
115253 + }
115254 +
115255 +
115256 +#if defined(CONFIG_COMPAT)
115257 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT:
115258 +#endif
115259 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT:
115260 + {
115261 + ioc_fm_buffer_prefix_content_params_t param;
115262 +
115263 +#if defined(CONFIG_COMPAT)
115264 + if (compat)
115265 + {
115266 + ioc_compat_fm_buffer_prefix_content_params_t compat_param;
115267 +
115268 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115269 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115270 +
115271 + compat_copy_fm_buffer_prefix_content_params(&compat_param, &param, COMPAT_US_TO_K);
115272 + }
115273 + else
115274 +#endif
115275 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115276 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115277 +
115278 + if (FM_VSP_ConfigBufferPrefixContent(param.p_fm_vsp,
115279 + (t_FmBufferPrefixContent *)&param.fm_buffer_prefix_content))
115280 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115281 +
115282 + break;
115283 + }
115284 +
115285 +#if defined(CONFIG_COMPAT)
115286 + case FM_IOC_VSP_CONFIG_NO_SG_COMPAT:
115287 +#endif
115288 + case FM_IOC_VSP_CONFIG_NO_SG:
115289 + {
115290 + ioc_fm_vsp_config_no_sg_params_t param;
115291 +
115292 +#if defined(CONFIG_COMPAT)
115293 + if (compat)
115294 + {
115295 + ioc_compat_fm_vsp_config_no_sg_params_t compat_param;
115296 +
115297 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115298 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115299 +
115300 + compat_copy_fm_vsp_config_no_sg_params(&compat_param, &param, COMPAT_US_TO_K);
115301 + }
115302 + else
115303 +#endif
115304 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115305 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115306 +
115307 + if (FM_VSP_ConfigNoScatherGather(param.p_fm_vsp, param.no_sg))
115308 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115309 +
115310 + break;
115311 + }
115312 +
115313 +#if defined(CONFIG_COMPAT)
115314 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT:
115315 +#endif
115316 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT:
115317 + {
115318 + ioc_fm_vsp_prs_result_params_t param;
115319 +
115320 +#if defined(CONFIG_COMPAT)
115321 + if (compat)
115322 + {
115323 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
115324 +
115325 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115326 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115327 +
115328 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_US_TO_K);
115329 + }
115330 + else
115331 +#endif
115332 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115333 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115334 +
115335 + /* this call just adds the parse results offset to p_data */
115336 + param.p_data = FM_VSP_GetBufferPrsResult(param.p_fm_vsp, param.p_data);
115337 +
115338 + if (!param.p_data)
115339 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115340 +
115341 +#if defined(CONFIG_COMPAT)
115342 + if (compat)
115343 + {
115344 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
115345 +
115346 + memset(&compat_param, 0, sizeof(compat_param));
115347 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_K_TO_US);
115348 +
115349 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
115350 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115351 + }
115352 + else
115353 +#endif
115354 + if (copy_to_user((void *)arg, &param, sizeof(param)))
115355 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115356 +
115357 + break;
115358 + }
115359 +#endif /* (DPAA_VERSION >= 11) */
115360 +
115361 +#ifdef FM_CAPWAP_SUPPORT
115362 +#warning "feature not supported!"
115363 +#if defined(CONFIG_COMPAT)
115364 + case FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT:
115365 +#endif
115366 + case FM_PCD_IOC_STATISTICS_SET_NODE:
115367 + {
115368 +/* ioc_fm_pcd_stats_params_t param;
115369 + ...
115370 + param->id = FM_PCD_StatisticsSetNode(p_LnxWrpFmDev->h_PcdDev,
115371 + (t_FmPcdStatsParams *)&param);
115372 +*/
115373 + err = E_NOT_SUPPORTED;
115374 + break;
115375 + }
115376 +#endif /* FM_CAPWAP_SUPPORT */
115377 +
115378 + default:
115379 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
115380 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr: %d.\n",
115381 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
115382 + }
115383 +
115384 + if (err)
115385 + RETURN_ERROR(MINOR, err, ("IOCTL FM PCD"));
115386 +
115387 + return E_OK;
115388 +}
115389 +
115390 +void FM_Get_Api_Version(ioc_fm_api_version_t *p_version)
115391 +{
115392 + p_version->version.major = FMD_API_VERSION_MAJOR;
115393 + p_version->version.minor = FMD_API_VERSION_MINOR;
115394 + p_version->version.respin = FMD_API_VERSION_RESPIN;
115395 + p_version->version.reserved = 0;
115396 +}
115397 +
115398 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
115399 +{
115400 + t_Error err = E_OK;
115401 +
115402 + switch (cmd)
115403 + {
115404 + case FM_IOC_SET_PORTS_BANDWIDTH:
115405 + {
115406 + ioc_fm_port_bandwidth_params *param;
115407 +
115408 + param = (ioc_fm_port_bandwidth_params*) XX_Malloc(sizeof(ioc_fm_port_bandwidth_params));
115409 + if (!param)
115410 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115411 +
115412 + memset(param, 0, sizeof(ioc_fm_port_bandwidth_params));
115413 +
115414 +#if defined(CONFIG_COMPAT)
115415 + if (compat)
115416 + {
115417 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)compat_ptr(arg), sizeof(ioc_fm_port_bandwidth_params)))
115418 + {
115419 + XX_Free(param);
115420 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115421 + }
115422 + }
115423 + else
115424 +#endif
115425 + {
115426 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)arg, sizeof(ioc_fm_port_bandwidth_params)))
115427 + {
115428 + XX_Free(param);
115429 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115430 + }
115431 + }
115432 +
115433 + err = FM_SetPortsBandwidth(p_LnxWrpFmDev->h_Dev, (t_FmPortsBandwidthParams*) param);
115434 +
115435 + XX_Free(param);
115436 + break;
115437 + }
115438 +
115439 + case FM_IOC_GET_REVISION:
115440 + {
115441 + ioc_fm_revision_info_t *param;
115442 +
115443 + param = (ioc_fm_revision_info_t *) XX_Malloc(sizeof(ioc_fm_revision_info_t));
115444 + if (!param)
115445 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115446 +
115447 + FM_GetRevision(p_LnxWrpFmDev->h_Dev, (t_FmRevisionInfo*)param);
115448 + /* This one never returns anything other than E_OK */
115449 +
115450 +#if defined(CONFIG_COMPAT)
115451 + if (compat)
115452 + {
115453 + if (copy_to_user((ioc_fm_revision_info_t *)compat_ptr(arg),
115454 + param,
115455 + sizeof(ioc_fm_revision_info_t))){
115456 + XX_Free(param);
115457 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115458 + }
115459 + }
115460 + else
115461 +#endif
115462 + {
115463 + if (copy_to_user((ioc_fm_revision_info_t *)arg,
115464 + param,
115465 + sizeof(ioc_fm_revision_info_t))){
115466 + XX_Free(param);
115467 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115468 + }
115469 + }
115470 + XX_Free(param);
115471 + break;
115472 + }
115473 +
115474 + case FM_IOC_SET_COUNTER:
115475 + {
115476 + ioc_fm_counters_params_t *param;
115477 +
115478 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
115479 + if (!param)
115480 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115481 +
115482 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
115483 +
115484 +#if defined(CONFIG_COMPAT)
115485 + if (compat)
115486 + {
115487 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
115488 + {
115489 + XX_Free(param);
115490 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115491 + }
115492 + }
115493 + else
115494 +#endif
115495 + {
115496 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
115497 + {
115498 + XX_Free(param);
115499 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115500 + }
115501 + }
115502 +
115503 + err = FM_ModifyCounter(p_LnxWrpFmDev->h_Dev, param->cnt, param->val);
115504 +
115505 + XX_Free(param);
115506 + break;
115507 + }
115508 +
115509 + case FM_IOC_GET_COUNTER:
115510 + {
115511 + ioc_fm_counters_params_t *param;
115512 +
115513 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
115514 + if (!param)
115515 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115516 +
115517 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
115518 +
115519 +#if defined(CONFIG_COMPAT)
115520 + if (compat)
115521 + {
115522 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
115523 + {
115524 + XX_Free(param);
115525 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115526 + }
115527 + }
115528 + else
115529 +#endif
115530 + {
115531 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
115532 + {
115533 + XX_Free(param);
115534 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115535 + }
115536 + }
115537 +
115538 + param->val = FM_GetCounter(p_LnxWrpFmDev->h_Dev, param->cnt);
115539 +
115540 +#if defined(CONFIG_COMPAT)
115541 + if (compat)
115542 + {
115543 + if (copy_to_user((ioc_fm_counters_params_t *)compat_ptr(arg), param, sizeof(ioc_fm_counters_params_t)))
115544 + err = E_READ_FAILED;
115545 + }
115546 + else
115547 +#endif
115548 + {
115549 + if (copy_to_user((ioc_fm_counters_params_t *)arg, param, sizeof(ioc_fm_counters_params_t)))
115550 + err = E_READ_FAILED;
115551 + }
115552 +
115553 + XX_Free(param);
115554 + break;
115555 + }
115556 +
115557 + case FM_IOC_FORCE_INTR:
115558 + {
115559 + ioc_fm_exceptions param;
115560 +
115561 +#if defined(CONFIG_COMPAT)
115562 + if (compat)
115563 + {
115564 + if (get_user(param, (ioc_fm_exceptions*) compat_ptr(arg)))
115565 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115566 + }
115567 + else
115568 +#endif
115569 + {
115570 + if (get_user(param, (ioc_fm_exceptions*)arg))
115571 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115572 + }
115573 +
115574 + err = FM_ForceIntr(p_LnxWrpFmDev->h_Dev, (e_FmExceptions)param);
115575 + break;
115576 + }
115577 +
115578 + case FM_IOC_GET_API_VERSION:
115579 + {
115580 + ioc_fm_api_version_t version;
115581 +
115582 + FM_Get_Api_Version(&version);
115583 +
115584 +#if defined(CONFIG_COMPAT)
115585 + if (compat)
115586 + {
115587 + if (copy_to_user(
115588 + (ioc_fm_api_version_t *)compat_ptr(arg),
115589 + &version, sizeof(version)))
115590 + err = E_READ_FAILED;
115591 + }
115592 + else
115593 +#endif
115594 + {
115595 + if (copy_to_user((ioc_fm_api_version_t *)arg,
115596 + &version, sizeof(version)))
115597 + err = E_READ_FAILED;
115598 + }
115599 + }
115600 + break;
115601 +
115602 + case FM_IOC_CTRL_MON_START:
115603 + {
115604 + FM_CtrlMonStart(p_LnxWrpFmDev->h_Dev);
115605 + }
115606 + break;
115607 +
115608 + case FM_IOC_CTRL_MON_STOP:
115609 + {
115610 + FM_CtrlMonStop(p_LnxWrpFmDev->h_Dev);
115611 + }
115612 + break;
115613 +
115614 +#if defined(CONFIG_COMPAT)
115615 + case FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT:
115616 +#endif
115617 + case FM_IOC_CTRL_MON_GET_COUNTERS:
115618 + {
115619 + ioc_fm_ctrl_mon_counters_params_t param;
115620 + t_FmCtrlMon mon;
115621 +
115622 +#if defined(CONFIG_COMPAT)
115623 + ioc_compat_fm_ctrl_mon_counters_params_t compat_param;
115624 +
115625 + if (compat)
115626 + {
115627 + if (copy_from_user(&compat_param, (void *)compat_ptr(arg),
115628 + sizeof(compat_param)))
115629 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115630 +
115631 + param.fm_ctrl_index = compat_param.fm_ctrl_index;
115632 + param.p_mon = (fm_ctrl_mon_t *)compat_ptr(compat_param.p_mon);
115633 + }
115634 + else
115635 +#endif
115636 + {
115637 + if (copy_from_user(&param, (void *)arg, sizeof(ioc_fm_ctrl_mon_counters_params_t)))
115638 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115639 + }
115640 +
115641 + if (FM_CtrlMonGetCounters(p_LnxWrpFmDev->h_Dev, param.fm_ctrl_index, &mon))
115642 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115643 +
115644 + if (copy_to_user(param.p_mon, &mon, sizeof(t_FmCtrlMon)))
115645 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115646 + }
115647 + break;
115648 +
115649 + default:
115650 + return LnxwrpFmPcdIOCTL(p_LnxWrpFmDev, cmd, arg, compat);
115651 + }
115652 +
115653 + if (err)
115654 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM"));
115655 +
115656 + return E_OK;
115657 +}
115658 +
115659 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat)
115660 +{
115661 + t_Error err = E_OK;
115662 +
115663 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
115664 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 70);
115665 +
115666 + switch (cmd)
115667 + {
115668 + case FM_PORT_IOC_DISABLE:
115669 + FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
115670 + /* deliberately ignoring error codes here */
115671 + return E_OK;
115672 +
115673 + case FM_PORT_IOC_ENABLE:
115674 + FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
115675 + /* deliberately ignoring error codes here */
115676 + return E_OK;
115677 +
115678 + case FM_PORT_IOC_SET_ERRORS_ROUTE:
115679 + {
115680 + ioc_fm_port_frame_err_select_t errs;
115681 +
115682 +#if defined(CONFIG_COMPAT)
115683 + if (compat)
115684 + {
115685 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)compat_ptr(arg)))
115686 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115687 + }
115688 + else
115689 +#endif
115690 + {
115691 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)arg))
115692 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115693 + }
115694 +
115695 + err = FM_PORT_SetErrorsRoute(p_LnxWrpFmPortDev->h_Dev, (fmPortFrameErrSelect_t)errs);
115696 + break;
115697 + }
115698 +
115699 + case FM_PORT_IOC_SET_RATE_LIMIT:
115700 + {
115701 + ioc_fm_port_rate_limit_t *param;
115702 +
115703 + param = (ioc_fm_port_rate_limit_t *) XX_Malloc(sizeof(ioc_fm_port_rate_limit_t));
115704 + if (!param)
115705 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115706 +
115707 + memset(param, 0, sizeof(ioc_fm_port_rate_limit_t));
115708 +
115709 +#if defined(CONFIG_COMPAT)
115710 + if (compat)
115711 + {
115712 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)compat_ptr(arg), sizeof(ioc_fm_port_rate_limit_t)))
115713 + {
115714 + XX_Free(param);
115715 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115716 + }
115717 + }
115718 + else
115719 +#endif
115720 + {
115721 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)arg, sizeof(ioc_fm_port_rate_limit_t)))
115722 + {
115723 + XX_Free(param);
115724 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115725 + }
115726 + }
115727 +
115728 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, (t_FmPortRateLimit *)param);
115729 +
115730 + XX_Free(param);
115731 + break;
115732 + }
115733 +
115734 + case FM_PORT_IOC_REMOVE_RATE_LIMIT:
115735 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
115736 + /* deliberately ignoring error codes here */
115737 + return E_OK;
115738 +
115739 + case FM_PORT_IOC_ALLOC_PCD_FQIDS:
115740 + {
115741 + ioc_fm_port_pcd_fqids_params_t *param;
115742 +
115743 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cba)
115744 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115745 +
115746 + param = (ioc_fm_port_pcd_fqids_params_t *) XX_Malloc(sizeof(ioc_fm_port_pcd_fqids_params_t));
115747 + if (!param)
115748 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115749 +
115750 + memset(param, 0, sizeof(ioc_fm_port_pcd_fqids_params_t));
115751 +
115752 +#if defined(CONFIG_COMPAT)
115753 + if (compat)
115754 + {
115755 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115756 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115757 + {
115758 + XX_Free(param);
115759 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115760 + }
115761 + }
115762 + else
115763 +#endif
115764 + {
115765 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)arg,
115766 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115767 + {
115768 + XX_Free(param);
115769 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115770 + }
115771 + }
115772 +
115773 + if (p_LnxWrpFmPortDev->pcd_owner_params.cba(p_LnxWrpFmPortDev->pcd_owner_params.dev,
115774 + param->num_fqids,
115775 + param->alignment,
115776 + &param->base_fqid))
115777 + {
115778 + XX_Free(param);
115779 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("can't allocate fqids for PCD!!!"));
115780 + }
115781 +
115782 +#if defined(CONFIG_COMPAT)
115783 + if (compat)
115784 + {
115785 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115786 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115787 + err = E_READ_FAILED;
115788 + }
115789 + else
115790 +#endif
115791 + {
115792 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)arg,
115793 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115794 + err = E_READ_FAILED;
115795 + }
115796 +
115797 + XX_Free(param);
115798 + break;
115799 + }
115800 +
115801 + case FM_PORT_IOC_FREE_PCD_FQIDS:
115802 + {
115803 + uint32_t base_fqid;
115804 +
115805 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cbf)
115806 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115807 +
115808 +#if defined(CONFIG_COMPAT)
115809 + if (compat)
115810 + {
115811 + if (get_user(base_fqid, (uint32_t*) compat_ptr(arg)))
115812 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115813 + }
115814 + else
115815 +#endif
115816 + {
115817 + if (get_user(base_fqid, (uint32_t*)arg))
115818 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115819 + }
115820 +
115821 + if (p_LnxWrpFmPortDev->pcd_owner_params.cbf(p_LnxWrpFmPortDev->pcd_owner_params.dev, base_fqid))
115822 + err = E_WRITE_FAILED;
115823 +
115824 + break;
115825 + }
115826 +
115827 +#if defined(CONFIG_COMPAT)
115828 + case FM_PORT_IOC_SET_PCD_COMPAT:
115829 +#endif
115830 + case FM_PORT_IOC_SET_PCD:
115831 + {
115832 + ioc_fm_port_pcd_params_t *port_pcd_params;
115833 + ioc_fm_port_pcd_prs_params_t *port_pcd_prs_params;
115834 + ioc_fm_port_pcd_cc_params_t *port_pcd_cc_params;
115835 + ioc_fm_port_pcd_kg_params_t *port_pcd_kg_params;
115836 + ioc_fm_port_pcd_plcr_params_t *port_pcd_plcr_params;
115837 +
115838 + port_pcd_params = (ioc_fm_port_pcd_params_t *) XX_Malloc(
115839 + sizeof(ioc_fm_port_pcd_params_t) +
115840 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115841 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115842 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115843 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115844 + if (!port_pcd_params)
115845 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115846 +
115847 + memset(port_pcd_params, 0,
115848 + sizeof(ioc_fm_port_pcd_params_t) +
115849 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115850 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115851 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115852 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115853 +
115854 + port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (port_pcd_params + 1);
115855 + port_pcd_cc_params = (ioc_fm_port_pcd_cc_params_t *) (port_pcd_prs_params + 1);
115856 + port_pcd_kg_params = (ioc_fm_port_pcd_kg_params_t *) (port_pcd_cc_params + 1);
115857 + port_pcd_plcr_params = (ioc_fm_port_pcd_plcr_params_t *) (port_pcd_kg_params + 1);
115858 +
115859 +#if defined(CONFIG_COMPAT)
115860 + if (compat)
115861 + {
115862 + ioc_compat_fm_port_pcd_params_t *compat_port_pcd_params;
115863 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
115864 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
115865 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
115866 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
115867 +
115868 + compat_port_pcd_params = (ioc_compat_fm_port_pcd_params_t *) XX_Malloc(
115869 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115870 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115871 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115872 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115873 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115874 + if (!compat_port_pcd_params)
115875 + {
115876 + XX_Free(port_pcd_params);
115877 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115878 + }
115879 +
115880 + memset(compat_port_pcd_params, 0,
115881 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115882 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115883 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115884 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115885 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115886 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_port_pcd_params + 1);
115887 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
115888 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
115889 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
115890 +
115891 + if (copy_from_user(compat_port_pcd_params,
115892 + (ioc_compat_fm_port_pcd_params_t*) compat_ptr(arg),
115893 + sizeof(ioc_compat_fm_port_pcd_params_t)))
115894 + err = E_WRITE_FAILED;
115895 +
115896 + while (!err) /* pseudo-while */
115897 + {
115898 + /* set pointers from where to copy from: */
115899 + port_pcd_params->p_prs_params = compat_ptr(compat_port_pcd_params->p_prs_params); /* same structure */
115900 + port_pcd_params->p_cc_params = compat_ptr(compat_port_pcd_params->p_cc_params);
115901 + port_pcd_params->p_kg_params = compat_ptr(compat_port_pcd_params->p_kg_params);
115902 + port_pcd_params->p_plcr_params = compat_ptr(compat_port_pcd_params->p_plcr_params);
115903 + port_pcd_params->p_ip_reassembly_manip = compat_ptr(compat_port_pcd_params->p_ip_reassembly_manip);
115904 +#if (DPAA_VERSION >= 11)
115905 + port_pcd_params->p_capwap_reassembly_manip = compat_ptr(compat_port_pcd_params->p_capwap_reassembly_manip);
115906 +#endif
115907 + /* the prs member is the same, no compat structure...memcpy only */
115908 + if (port_pcd_params->p_prs_params)
115909 + {
115910 + if (copy_from_user(same_port_pcd_prs_params,
115911 + port_pcd_params->p_prs_params,
115912 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115913 + {
115914 + err = E_WRITE_FAILED;
115915 + break; /* from pseudo-while */
115916 + }
115917 +
115918 + memcpy(port_pcd_prs_params, same_port_pcd_prs_params, sizeof(ioc_fm_port_pcd_prs_params_t));
115919 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115920 + }
115921 +
115922 + if (port_pcd_params->p_cc_params)
115923 + {
115924 + if (copy_from_user(compat_port_pcd_cc_params,
115925 + port_pcd_params->p_cc_params,
115926 + sizeof(ioc_compat_fm_port_pcd_cc_params_t)))
115927 + {
115928 + err = E_WRITE_FAILED;
115929 + break; /* from pseudo-while */
115930 + }
115931 +
115932 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115933 + }
115934 +
115935 + if (port_pcd_params->p_kg_params)
115936 + {
115937 + if (copy_from_user(compat_port_pcd_kg_params,
115938 + port_pcd_params->p_kg_params,
115939 + sizeof(ioc_compat_fm_port_pcd_kg_params_t)))
115940 + {
115941 + err = E_WRITE_FAILED;
115942 + break; /* from pseudo-while */
115943 + }
115944 +
115945 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115946 + }
115947 +
115948 + if (port_pcd_params->p_plcr_params)
115949 + {
115950 + if (copy_from_user(compat_port_pcd_plcr_params,
115951 + port_pcd_params->p_plcr_params,
115952 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t)))
115953 + {
115954 + err = E_WRITE_FAILED;
115955 + break; /* from pseudo-while */
115956 + }
115957 +
115958 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115959 + }
115960 +
115961 + break; /* pseudo-while: always run once! */
115962 + }
115963 +
115964 + if (!err)
115965 + compat_copy_fm_port_pcd(compat_port_pcd_params, port_pcd_params, COMPAT_US_TO_K);
115966 +
115967 + XX_Free(compat_port_pcd_params);
115968 + }
115969 + else
115970 +#endif
115971 + {
115972 + if (copy_from_user(port_pcd_params,
115973 + (ioc_fm_port_pcd_params_t*) arg,
115974 + sizeof(ioc_fm_port_pcd_params_t)))
115975 + err = E_WRITE_FAILED;
115976 +
115977 + while (!err) /* pseudo-while */
115978 + {
115979 + if (port_pcd_params->p_prs_params)
115980 + {
115981 + if (copy_from_user(port_pcd_prs_params,
115982 + port_pcd_params->p_prs_params,
115983 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115984 + {
115985 + err = E_WRITE_FAILED;
115986 + break; /* from pseudo-while */
115987 + }
115988 +
115989 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115990 + }
115991 +
115992 + if (port_pcd_params->p_cc_params)
115993 + {
115994 + if (copy_from_user(port_pcd_cc_params,
115995 + port_pcd_params->p_cc_params,
115996 + sizeof(ioc_fm_port_pcd_cc_params_t)))
115997 + {
115998 + err = E_WRITE_FAILED;
115999 + break; /* from pseudo-while */
116000 + }
116001 +
116002 + port_pcd_params->p_cc_params = port_pcd_cc_params;
116003 + }
116004 +
116005 + if (port_pcd_params->p_kg_params)
116006 + {
116007 + if (copy_from_user(port_pcd_kg_params,
116008 + port_pcd_params->p_kg_params,
116009 + sizeof(ioc_fm_port_pcd_kg_params_t)))
116010 + {
116011 + err = E_WRITE_FAILED;
116012 + break; /* from pseudo-while */
116013 + }
116014 +
116015 + port_pcd_params->p_kg_params = port_pcd_kg_params;
116016 + }
116017 +
116018 + if (port_pcd_params->p_plcr_params)
116019 + {
116020 + if (copy_from_user(port_pcd_plcr_params,
116021 + port_pcd_params->p_plcr_params,
116022 + sizeof(ioc_fm_port_pcd_plcr_params_t)))
116023 + {
116024 + err = E_WRITE_FAILED;
116025 + break; /* from pseudo-while */
116026 + }
116027 +
116028 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
116029 + }
116030 +
116031 + break; /* pseudo-while: always run once! */
116032 + }
116033 + }
116034 +
116035 + if (!err)
116036 + err = FM_PORT_SetPCD(p_LnxWrpFmPortDev->h_Dev, (t_FmPortPcdParams*) port_pcd_params);
116037 +
116038 + XX_Free(port_pcd_params);
116039 + break;
116040 + }
116041 +
116042 + case FM_PORT_IOC_DELETE_PCD:
116043 + err = FM_PORT_DeletePCD(p_LnxWrpFmPortDev->h_Dev);
116044 + break;
116045 +
116046 +#if defined(CONFIG_COMPAT)
116047 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT:
116048 +#endif
116049 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME:
116050 + {
116051 + ioc_fm_pcd_kg_scheme_select_t *param;
116052 +
116053 + param = (ioc_fm_pcd_kg_scheme_select_t *) XX_Malloc(
116054 + sizeof(ioc_fm_pcd_kg_scheme_select_t));
116055 + if (!param)
116056 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116057 +
116058 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_select_t));
116059 +
116060 +#if defined(CONFIG_COMPAT)
116061 + if (compat)
116062 + {
116063 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param;
116064 +
116065 + compat_param = (ioc_compat_fm_pcd_kg_scheme_select_t *) XX_Malloc(
116066 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
116067 + if (!compat_param)
116068 + {
116069 + XX_Free(param);
116070 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116071 + }
116072 +
116073 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
116074 + if (copy_from_user(compat_param,
116075 + (ioc_compat_fm_pcd_kg_scheme_select_t *) compat_ptr(arg),
116076 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)))
116077 + {
116078 + XX_Free(compat_param);
116079 + XX_Free(param);
116080 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116081 + }
116082 +
116083 + compat_copy_fm_pcd_kg_scheme_select(compat_param, param, COMPAT_US_TO_K);
116084 +
116085 + XX_Free(compat_param);
116086 + }
116087 + else
116088 +#endif
116089 + {
116090 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_select_t *)arg,
116091 + sizeof(ioc_fm_pcd_kg_scheme_select_t)))
116092 + {
116093 + XX_Free(param);
116094 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116095 + }
116096 + }
116097 +
116098 + err = FM_PORT_PcdKgModifyInitialScheme(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdKgSchemeSelect *)param);
116099 +
116100 + XX_Free(param);
116101 + break;
116102 + }
116103 +
116104 +#if defined(CONFIG_COMPAT)
116105 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT:
116106 +#endif
116107 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE:
116108 + {
116109 + ioc_fm_obj_t id;
116110 +
116111 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
116112 +
116113 +#if defined(CONFIG_COMPAT)
116114 + if (compat)
116115 + {
116116 + ioc_compat_fm_obj_t compat_id;
116117 +
116118 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
116119 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116120 +
116121 + id.obj = compat_ptr(compat_id.obj);
116122 + }
116123 + else
116124 +#endif
116125 + {
116126 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
116127 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116128 + }
116129 +
116130 + err = FM_PORT_PcdPlcrModifyInitialProfile(p_LnxWrpFmPortDev->h_Dev, id.obj);
116131 + break;
116132 + }
116133 +
116134 +#if defined(CONFIG_COMPAT)
116135 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT:
116136 +#endif
116137 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES:
116138 + {
116139 + ioc_fm_pcd_port_schemes_params_t *param;
116140 +
116141 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
116142 + sizeof(ioc_fm_pcd_port_schemes_params_t));
116143 + if (!param)
116144 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116145 +
116146 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
116147 +
116148 +#if defined(CONFIG_COMPAT)
116149 + if (compat)
116150 + {
116151 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
116152 +
116153 + if (copy_from_user(&compat_param,
116154 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
116155 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
116156 + {
116157 + XX_Free(param);
116158 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116159 + }
116160 +
116161 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
116162 + }
116163 + else
116164 +#endif
116165 + {
116166 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
116167 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
116168 + {
116169 + XX_Free(param);
116170 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116171 + }
116172 + }
116173 +
116174 + err = FM_PORT_PcdKgBindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
116175 +
116176 + XX_Free(param);
116177 + break;
116178 + }
116179 +
116180 +#if defined(CONFIG_COMPAT)
116181 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT:
116182 +#endif
116183 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES:
116184 + {
116185 + ioc_fm_pcd_port_schemes_params_t *param;
116186 +
116187 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
116188 + sizeof(ioc_fm_pcd_port_schemes_params_t));
116189 + if (!param)
116190 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116191 +
116192 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
116193 +
116194 +#if defined(CONFIG_COMPAT)
116195 + if (compat)
116196 + {
116197 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
116198 +
116199 + if (copy_from_user(&compat_param,
116200 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
116201 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
116202 + {
116203 + XX_Free(param);
116204 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116205 + }
116206 +
116207 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
116208 + }
116209 + else
116210 +#endif
116211 + {
116212 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
116213 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
116214 + {
116215 + XX_Free(param);
116216 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116217 + }
116218 + }
116219 +
116220 + err = FM_PORT_PcdKgUnbindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
116221 +
116222 + XX_Free(param);
116223 + break;
116224 + }
116225 +
116226 + case FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES:
116227 + {
116228 + uint16_t num;
116229 + if (get_user(num, (uint16_t*) arg))
116230 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116231 +
116232 + err = FM_PORT_PcdPlcrAllocProfiles(p_LnxWrpFmPortDev->h_Dev, num);
116233 + break;
116234 + }
116235 +
116236 + case FM_PORT_IOC_PCD_PLCR_FREE_PROFILES:
116237 + err = FM_PORT_PcdPlcrFreeProfiles(p_LnxWrpFmPortDev->h_Dev);
116238 + break;
116239 +
116240 + case FM_PORT_IOC_DETACH_PCD:
116241 + err = FM_PORT_DetachPCD(p_LnxWrpFmPortDev->h_Dev);
116242 + break;
116243 +
116244 + case FM_PORT_IOC_ATTACH_PCD:
116245 + err = FM_PORT_AttachPCD(p_LnxWrpFmPortDev->h_Dev);
116246 + break;
116247 +
116248 +#if defined(CONFIG_COMPAT)
116249 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT:
116250 +#endif
116251 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE:
116252 + {
116253 + ioc_fm_obj_t id;
116254 +
116255 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
116256 +
116257 +#if defined(CONFIG_COMPAT)
116258 + if (compat)
116259 + {
116260 + ioc_compat_fm_obj_t compat_id;
116261 +
116262 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
116263 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116264 +
116265 + compat_copy_fm_port_pcd_modify_tree(&compat_id, &id, COMPAT_US_TO_K);
116266 + }
116267 + else
116268 +#endif
116269 + {
116270 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
116271 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116272 + }
116273 +
116274 + err = FM_PORT_PcdCcModifyTree(p_LnxWrpFmPortDev->h_Dev, id.obj);
116275 + break;
116276 + }
116277 +
116278 + case FM_PORT_IOC_ADD_CONGESTION_GRPS:
116279 + case FM_PORT_IOC_REMOVE_CONGESTION_GRPS:
116280 + {
116281 + ioc_fm_port_congestion_groups_t *param;
116282 +
116283 + param = (ioc_fm_port_congestion_groups_t*) XX_Malloc(sizeof(ioc_fm_port_congestion_groups_t));
116284 + if (!param)
116285 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116286 +
116287 + memset(param, 0, sizeof(ioc_fm_port_congestion_groups_t));
116288 +
116289 +#if defined(CONFIG_COMPAT)
116290 + if (compat)
116291 + {
116292 + if (copy_from_user(param, (t_FmPortCongestionGrps*) compat_ptr(arg),
116293 + sizeof(t_FmPortCongestionGrps)))
116294 + {
116295 + XX_Free(param);
116296 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116297 + }
116298 + }
116299 + else
116300 +#endif /* CONFIG_COMPAT */
116301 + {
116302 + if (copy_from_user(param, (t_FmPortCongestionGrps*) arg,
116303 + sizeof(t_FmPortCongestionGrps)))
116304 + {
116305 + XX_Free(param);
116306 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116307 + }
116308 + }
116309 +
116310 + err = (cmd == FM_PORT_IOC_ADD_CONGESTION_GRPS)
116311 + ? FM_PORT_AddCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
116312 + : FM_PORT_RemoveCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
116313 + ;
116314 +
116315 + XX_Free(param);
116316 + break;
116317 + }
116318 +
116319 + case FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR:
116320 + case FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR:
116321 + {
116322 + ioc_fm_port_mac_addr_params_t *param;
116323 +
116324 + param = (ioc_fm_port_mac_addr_params_t*) XX_Malloc(
116325 + sizeof(ioc_fm_port_mac_addr_params_t));
116326 + if (!param)
116327 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116328 +
116329 + memset(param, 0, sizeof(ioc_fm_port_mac_addr_params_t));
116330 +
116331 +#if defined(CONFIG_COMPAT)
116332 + if (compat)
116333 + {
116334 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) compat_ptr(arg),
116335 + sizeof(ioc_fm_port_mac_addr_params_t)))
116336 + {
116337 + XX_Free(param);
116338 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116339 + }
116340 + }
116341 + else
116342 +#endif /* CONFIG_COMPAT */
116343 + {
116344 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) arg,
116345 + sizeof(ioc_fm_port_mac_addr_params_t)))
116346 + {
116347 + XX_Free(param);
116348 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116349 + }
116350 + }
116351 +
116352 + if (p_LnxWrpFmPortDev->pcd_owner_params.dev)
116353 + {
116354 + int id = -1;
116355 +
116356 + switch(p_LnxWrpFmPortDev->settings.param.portType)
116357 + {
116358 + case e_FM_PORT_TYPE_RX:
116359 + case e_FM_PORT_TYPE_TX:
116360 + id = p_LnxWrpFmPortDev->id;
116361 + break;
116362 + case e_FM_PORT_TYPE_RX_10G:
116363 + case e_FM_PORT_TYPE_TX_10G:
116364 + id = p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_MACS;
116365 + break;
116366 + default:
116367 + err = E_NOT_AVAILABLE;
116368 + REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!"));
116369 + }
116370 + if (id >= 0)
116371 + {
116372 + t_LnxWrpFmDev *fm = (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116373 + t_Handle mac_handle = fm->macs[id].h_Dev;
116374 +
116375 + err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR)
116376 + ? FM_MAC_AddHashMacAddr(mac_handle, (t_EnetAddr*) param)
116377 + : FM_MAC_RemoveHashMacAddr(mac_handle, (t_EnetAddr*) param);
116378 + }
116379 + }
116380 + else
116381 + {
116382 + err = E_NOT_AVAILABLE;
116383 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!?!?"));
116384 + }
116385 +
116386 + XX_Free(param);
116387 + break;
116388 + }
116389 +
116390 + case FM_PORT_IOC_SET_TX_PAUSE_FRAMES:
116391 + {
116392 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116393 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116394 + ioc_fm_port_tx_pause_frames_params_t param;
116395 + int mac_id = p_LnxWrpFmPortDev->id;
116396 +
116397 + if(&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev)
116398 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
116399 +
116400 + if (copy_from_user(&param, (ioc_fm_port_tx_pause_frames_params_t *)arg,
116401 + sizeof(ioc_fm_port_tx_pause_frames_params_t)))
116402 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116403 +
116404 + if (p_LnxWrpFmDev && p_LnxWrpFmDev->macs[mac_id].h_Dev)
116405 + {
116406 + FM_MAC_SetTxPauseFrames(p_LnxWrpFmDev->macs[mac_id].h_Dev,
116407 + param.priority,
116408 + param.pause_time,
116409 + param.thresh_time);
116410 + }
116411 + else
116412 + {
116413 + err = E_NOT_AVAILABLE;
116414 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!"));
116415 + }
116416 +
116417 + break;
116418 + }
116419 +
116420 + case FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT:
116421 + {
116422 + ioc_fm_buffer_prefix_content_t *param;
116423 +
116424 + param = (ioc_fm_buffer_prefix_content_t*) XX_Malloc(sizeof(ioc_fm_buffer_prefix_content_t));
116425 + if (!param)
116426 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116427 +
116428 + memset(param, 0, sizeof(ioc_fm_buffer_prefix_content_t));
116429 +
116430 + if (copy_from_user(param, (ioc_fm_buffer_prefix_content_t*) arg,
116431 + sizeof(ioc_fm_buffer_prefix_content_t)))
116432 + {
116433 + XX_Free(param);
116434 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116435 + }
116436 +
116437 + if (FM_PORT_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_Dev,
116438 + (t_FmBufferPrefixContent *)param))
116439 + {
116440 + XX_Free(param);
116441 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116442 + }
116443 +
116444 + XX_Free(param);
116445 + break;
116446 + }
116447 +
116448 +#if (DPAA_VERSION >= 11)
116449 +#if defined(CONFIG_COMPAT)
116450 + case FM_PORT_IOC_VSP_ALLOC_COMPAT:
116451 +#endif
116452 + case FM_PORT_IOC_VSP_ALLOC:
116453 + {
116454 + ioc_fm_port_vsp_alloc_params_t *param;
116455 + t_LnxWrpFmDev *p_LnxWrpFmDev;
116456 + t_LnxWrpFmPortDev *p_LnxWrpFmTxPortDev;
116457 +
116458 + param = (ioc_fm_port_vsp_alloc_params_t *) XX_Malloc(
116459 + sizeof(ioc_fm_port_vsp_alloc_params_t));
116460 + if (!param)
116461 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116462 +
116463 + memset(param, 0, sizeof(ioc_fm_port_vsp_alloc_params_t));
116464 +
116465 +#if defined(CONFIG_COMPAT)
116466 + if (compat)
116467 + {
116468 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param;
116469 +
116470 + compat_param = (ioc_compat_fm_port_vsp_alloc_params_t *) XX_Malloc(
116471 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
116472 + if (!compat_param)
116473 + {
116474 + XX_Free(param);
116475 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116476 + }
116477 +
116478 + memset(compat_param, 0, sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
116479 + if (copy_from_user(compat_param,
116480 + (ioc_compat_fm_port_vsp_alloc_params_t *) compat_ptr(arg),
116481 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t)))
116482 + {
116483 + XX_Free(compat_param);
116484 + XX_Free(param);
116485 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116486 + }
116487 +
116488 + compat_copy_fm_port_vsp_alloc_params(compat_param, param, COMPAT_US_TO_K);
116489 +
116490 + XX_Free(compat_param);
116491 + }
116492 + else
116493 +#endif
116494 + {
116495 + if (copy_from_user(param, (ioc_fm_port_vsp_alloc_params_t *)arg,
116496 + sizeof(ioc_fm_port_vsp_alloc_params_t)))
116497 + {
116498 + XX_Free(param);
116499 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116500 + }
116501 + }
116502 +
116503 + /* Userspace may not have the Tx port t_handle when issuing the IOCTL */
116504 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
116505 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G)
116506 + {
116507 + /* Determine the Tx port t_Handle from the Rx port id */
116508 + p_LnxWrpFmDev = p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116509 + p_LnxWrpFmTxPortDev = &p_LnxWrpFmDev->txPorts[p_LnxWrpFmPortDev->id];
116510 + param->p_fm_tx_port = p_LnxWrpFmTxPortDev->h_Dev;
116511 + }
116512 +
116513 + if (FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, (t_FmPortVSPAllocParams *)param))
116514 + {
116515 + XX_Free(param);
116516 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116517 + }
116518 +
116519 + XX_Free(param);
116520 + break;
116521 + }
116522 +#endif /* (DPAA_VERSION >= 11) */
116523 +
116524 + case FM_PORT_IOC_GET_MAC_STATISTICS:
116525 + {
116526 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116527 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116528 + ioc_fm_port_mac_statistics_t param;
116529 + int mac_id = p_LnxWrpFmPortDev->id;
116530 +
116531 + if (!p_LnxWrpFmDev)
116532 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116533 +
116534 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
116535 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
116536 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
116537 +
116538 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
116539 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116540 +
116541 + if (FM_MAC_GetStatistics(p_LnxWrpFmDev->macs[mac_id].h_Dev,
116542 + (t_FmMacStatistics *)&param))
116543 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116544 +
116545 + if (copy_to_user((ioc_fm_port_mac_statistics_t *)arg, &param,
116546 + sizeof(ioc_fm_port_mac_statistics_t)))
116547 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116548 +
116549 + break;
116550 + }
116551 +
116552 + case FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS:
116553 + {
116554 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116555 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116556 + ioc_fm_port_mac_frame_size_counters_t param;
116557 + t_FmMacFrameSizeCounters frameSizeCounters;
116558 + int mac_id = p_LnxWrpFmPortDev->id;
116559 +
116560 + if (!p_LnxWrpFmDev)
116561 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116562 +
116563 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
116564 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
116565 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
116566 +
116567 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
116568 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116569 +
116570 + if (copy_from_user(&param, (ioc_fm_port_mac_frame_size_counters_t *)arg,
116571 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
116572 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116573 +
116574 + if (FM_MAC_GetFrameSizeCounters(p_LnxWrpFmDev->macs[mac_id].h_Dev,
116575 + &frameSizeCounters, param.type))
116576 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116577 +
116578 + param.count_pkts_64 = frameSizeCounters.count_pkts_64;
116579 + param.count_pkts_65_to_127 = frameSizeCounters.count_pkts_65_to_127;
116580 + param.count_pkts_128_to_255 = frameSizeCounters.count_pkts_128_to_255;
116581 + param.count_pkts_256_to_511 = frameSizeCounters.count_pkts_256_to_511;
116582 + param.count_pkts_512_to_1023 = frameSizeCounters.count_pkts_512_to_1023;
116583 + param.count_pkts_1024_to_1518 = frameSizeCounters.count_pkts_1024_to_1518;
116584 + param.count_pkts_1519_to_1522 = frameSizeCounters.count_pkts_1519_to_1522;
116585 +
116586 + if (copy_to_user((ioc_fm_port_mac_frame_size_counters_t *)arg, &param,
116587 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
116588 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116589 +
116590 + break;
116591 + }
116592 +
116593 + case FM_PORT_IOC_GET_BMI_COUNTERS:
116594 + {
116595 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116596 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116597 + ioc_fm_port_bmi_stats_t param;
116598 +
116599 + if (!p_LnxWrpFmDev)
116600 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116601 +
116602 + if (FM_PORT_GetBmiCounters(p_LnxWrpFmPortDev->h_Dev,
116603 + (t_FmPortBmiStats *)&param))
116604 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116605 +
116606 + if (copy_to_user((ioc_fm_port_bmi_stats_t *)arg, &param,
116607 + sizeof(ioc_fm_port_bmi_stats_t)))
116608 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116609 +
116610 + break;
116611 + }
116612 +
116613 + default:
116614 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
116615 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
116616 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
116617 + }
116618 +
116619 + if (err)
116620 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM PORT"));
116621 +
116622 + return E_OK;
116623 +}
116624 +
116625 +/*****************************************************************************/
116626 +/* API routines for the FM Linux Device */
116627 +/*****************************************************************************/
116628 +
116629 +static int fm_open(struct inode *inode, struct file *file)
116630 +{
116631 + t_LnxWrpFmDev *p_LnxWrpFmDev = NULL;
116632 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
116633 + unsigned int major = imajor(inode);
116634 + unsigned int minor = iminor(inode);
116635 + struct device_node *fm_node;
116636 + static struct of_device_id fm_node_of_match[] = {
116637 + { .compatible = "fsl,fman", },
116638 + { /* end of list */ },
116639 + };
116640 +
116641 + DBG(TRACE, ("Opening minor - %d - ", minor));
116642 +
116643 + if (file->private_data != NULL)
116644 + return 0;
116645 +
116646 + /* Get all the FM nodes */
116647 + for_each_matching_node(fm_node, fm_node_of_match) {
116648 + struct platform_device *of_dev;
116649 +
116650 + of_dev = of_find_device_by_node(fm_node);
116651 + if (unlikely(of_dev == NULL)) {
116652 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
116653 + return -ENXIO;
116654 + }
116655 +
116656 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)fm_bind(&of_dev->dev);
116657 + if (p_LnxWrpFmDev->major == major)
116658 + break;
116659 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116660 + p_LnxWrpFmDev = NULL;
116661 + }
116662 +
116663 + if (!p_LnxWrpFmDev)
116664 + return -ENODEV;
116665 +
116666 + if (minor == DEV_FM_MINOR_BASE)
116667 + file->private_data = p_LnxWrpFmDev;
116668 + else if (minor == DEV_FM_PCD_MINOR_BASE)
116669 + file->private_data = p_LnxWrpFmDev;
116670 + else {
116671 + if (minor == DEV_FM_OH_PORTS_MINOR_BASE)
116672 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
116673 + else if ((minor > DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE))
116674 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->opPorts[minor-DEV_FM_OH_PORTS_MINOR_BASE-1];
116675 + else if ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE))
116676 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[minor-DEV_FM_RX_PORTS_MINOR_BASE];
116677 + else if ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))
116678 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[minor-DEV_FM_TX_PORTS_MINOR_BASE];
116679 + else
116680 + return -EINVAL;
116681 +
116682 + /* if trying to open port, check if it initialized */
116683 + if (!p_LnxWrpFmPortDev->h_Dev)
116684 + return -ENODEV;
116685 +
116686 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)fm_port_bind(p_LnxWrpFmPortDev->dev);
116687 + file->private_data = p_LnxWrpFmPortDev;
116688 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116689 + }
116690 +
116691 + if (file->private_data == NULL)
116692 + return -ENXIO;
116693 +
116694 + return 0;
116695 +}
116696 +
116697 +static int fm_close(struct inode *inode, struct file *file)
116698 +{
116699 + t_LnxWrpFmDev *p_LnxWrpFmDev;
116700 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
116701 + unsigned int minor = iminor(inode);
116702 + int err = 0;
116703 +
116704 + DBG(TRACE, ("Closing minor - %d - ", minor));
116705 +
116706 + if ((minor == DEV_FM_MINOR_BASE) ||
116707 + (minor == DEV_FM_PCD_MINOR_BASE))
116708 + {
116709 + p_LnxWrpFmDev = (t_LnxWrpFmDev*)file->private_data;
116710 + if (!p_LnxWrpFmDev)
116711 + return -ENODEV;
116712 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116713 + }
116714 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
116715 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
116716 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
116717 + {
116718 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)file->private_data;
116719 + if (!p_LnxWrpFmPortDev)
116720 + return -ENODEV;
116721 + fm_port_unbind((struct fm_port *)p_LnxWrpFmPortDev);
116722 + }
116723 +
116724 + return err;
116725 +}
116726 +
116727 +static int fm_ioctls(unsigned int minor, struct file *file, unsigned int cmd, unsigned long arg, bool compat)
116728 +{
116729 + DBG(TRACE, ("IOCTL minor - %u, cmd - 0x%08x, arg - 0x%08lx \n", minor, cmd, arg));
116730 +
116731 + if ((minor == DEV_FM_MINOR_BASE) ||
116732 + (minor == DEV_FM_PCD_MINOR_BASE))
116733 + {
116734 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_LnxWrpFmDev*)file->private_data);
116735 + if (!p_LnxWrpFmDev)
116736 + return -ENODEV;
116737 + if (LnxwrpFmIOCTL(p_LnxWrpFmDev, cmd, arg, compat))
116738 + return -EFAULT;
116739 + }
116740 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
116741 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
116742 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
116743 + {
116744 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = ((t_LnxWrpFmPortDev*)file->private_data);
116745 + if (!p_LnxWrpFmPortDev)
116746 + return -ENODEV;
116747 + if (LnxwrpFmPortIOCTL(p_LnxWrpFmPortDev, cmd, arg, compat))
116748 + return -EFAULT;
116749 + }
116750 + else
116751 + {
116752 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("minor"));
116753 + return -ENODEV;
116754 + }
116755 +
116756 + return 0;
116757 +}
116758 +
116759 +#ifdef CONFIG_COMPAT
116760 +static long fm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
116761 +{
116762 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
116763 + long res;
116764 +
116765 + fm_mutex_lock();
116766 + res = fm_ioctls(minor, file, cmd, arg, true);
116767 + fm_mutex_unlock();
116768 +
116769 + return res;
116770 +}
116771 +#endif
116772 +
116773 +static long fm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
116774 +{
116775 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
116776 + long res;
116777 +
116778 + fm_mutex_lock();
116779 + res = fm_ioctls(minor, file, cmd, arg, false);
116780 + fm_mutex_unlock();
116781 +
116782 + return res;
116783 +}
116784 +
116785 +/* Globals for FM character device */
116786 +struct file_operations fm_fops =
116787 +{
116788 + .owner = THIS_MODULE,
116789 + .unlocked_ioctl = fm_ioctl,
116790 +#ifdef CONFIG_COMPAT
116791 + .compat_ioctl = fm_compat_ioctl,
116792 +#endif
116793 + .open = fm_open,
116794 + .release = fm_close,
116795 +};
116796 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
116797 new file mode 100644
116798 index 00000000..322ae9ef
116799 --- /dev/null
116800 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
116801 @@ -0,0 +1,1297 @@
116802 +/*
116803 + * Copyright 2008-2012 Freescale Semiconductor Inc.
116804 + *
116805 + * Redistribution and use in source and binary forms, with or without
116806 + * modification, are permitted provided that the following conditions are met:
116807 + * * Redistributions of source code must retain the above copyright
116808 + * notice, this list of conditions and the following disclaimer.
116809 + * * Redistributions in binary form must reproduce the above copyright
116810 + * notice, this list of conditions and the following disclaimer in the
116811 + * documentation and/or other materials provided with the distribution.
116812 + * * Neither the name of Freescale Semiconductor nor the
116813 + * names of its contributors may be used to endorse or promote products
116814 + * derived from this software without specific prior written permission.
116815 + *
116816 + *
116817 + * ALTERNATIVELY, this software may be distributed under the terms of the
116818 + * GNU General Public License ("GPL") as published by the Free Software
116819 + * Foundation, either version 2 of that License or (at your option) any
116820 + * later version.
116821 + *
116822 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
116823 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
116824 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
116825 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
116826 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
116827 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
116828 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
116829 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
116830 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
116831 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
116832 + */
116833 +
116834 +/*
116835 + @File lnxwrp_fm_compat_ioctls.c
116836 +
116837 + @Description FM PCD compat functions
116838 +
116839 +*/
116840 +
116841 +#if !defined(CONFIG_COMPAT)
116842 +#error "missing COMPAT layer..."
116843 +#endif
116844 +
116845 +
116846 +#include <linux/kernel.h>
116847 +#include <linux/module.h>
116848 +#include <linux/fs.h>
116849 +#include <linux/cdev.h>
116850 +#include <linux/device.h>
116851 +#include <linux/irq.h>
116852 +#include <linux/interrupt.h>
116853 +#include <linux/io.h>
116854 +#include <linux/ioport.h>
116855 +#include <asm/uaccess.h>
116856 +#include <asm/errno.h>
116857 +#ifndef CONFIG_FMAN_ARM
116858 +#include <sysdev/fsl_soc.h>
116859 +#endif
116860 +
116861 +#include "part_ext.h"
116862 +#include "fm_ioctls.h"
116863 +#include "fm_pcd_ioctls.h"
116864 +#include "fm_port_ioctls.h"
116865 +#include "lnxwrp_ioctls_fm_compat.h"
116866 +
116867 +#if defined(FM_COMPAT_DBG)
116868 +static void hex_dump(void * p_addr, unsigned int size)
116869 +{
116870 + int i;
116871 +
116872 + for(i=0; i<size; i+=16)
116873 + {
116874 + printk("%p: 0x%08x 0x%08x 0x%08x 0x%08x\n", p_addr + i,
116875 + *(unsigned int *)(p_addr + i),
116876 + *(unsigned int *)(p_addr + i + 4),
116877 + *(unsigned int *)(p_addr + i + 8),
116878 + *(unsigned int *)(p_addr + i +12)
116879 + );
116880 + }
116881 +}
116882 +#endif
116883 +
116884 +/* maping kernel pointers w/ UserSpace id's { */
116885 +struct map_node {
116886 + void *ptr;
116887 + u8 node_type;
116888 +};
116889 +
116890 +static struct map_node compat_ptr2id_array[COMPAT_PTR2ID_ARRAY_MAX] = {{NULL},{FM_MAP_TYPE_UNSPEC}};
116891 +
116892 +void compat_del_ptr2id(void *p, enum fm_map_node_type node_type)
116893 +{
116894 + compat_uptr_t k;
116895 +
116896 + _fm_cpt_dbg(COMPAT_GENERIC, "delete (%p)\n", p);
116897 +
116898 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116899 + if(compat_ptr2id_array[k].ptr == p){
116900 + compat_ptr2id_array[k].ptr = NULL;
116901 + compat_ptr2id_array[k].node_type = FM_MAP_TYPE_UNSPEC;
116902 + }
116903 +}
116904 +EXPORT_SYMBOL(compat_del_ptr2id);
116905 +
116906 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type node_type)
116907 +{
116908 + compat_uptr_t k;
116909 +
116910 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) do ->\n", p);
116911 +
116912 + if(!p)
116913 + return 0;
116914 +
116915 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116916 + if(compat_ptr2id_array[k].ptr == NULL)
116917 + {
116918 + compat_ptr2id_array[k].ptr = p;
116919 + compat_ptr2id_array[k].node_type = node_type;
116920 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x \n", k | COMPAT_PTR2ID_WATERMARK);
116921 + return k | COMPAT_PTR2ID_WATERMARK;
116922 + }
116923 +
116924 + printk(KERN_WARNING "FMan map list full! No more PCD space on kernel!\n");
116925 + return 0;
116926 +}
116927 +EXPORT_SYMBOL(compat_add_ptr2id);
116928 +
116929 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type node_type)
116930 +{
116931 + compat_uptr_t k;
116932 +
116933 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) get -> \n", p);
116934 +
116935 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116936 + if(compat_ptr2id_array[k].ptr == p &&
116937 + compat_ptr2id_array[k].node_type == node_type) {
116938 +
116939 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x\n", k | COMPAT_PTR2ID_WATERMARK);
116940 + return k | COMPAT_PTR2ID_WATERMARK;
116941 + }
116942 +
116943 + return 0;
116944 +}
116945 +EXPORT_SYMBOL(compat_get_ptr2id);
116946 +
116947 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type node_type)
116948 +{
116949 +
116950 + _fm_cpt_dbg(COMPAT_GENERIC, " (0x%08x) get -> \n", comp);
116951 +
116952 + if((COMPAT_PTR2ID_WM_MASK & comp) != COMPAT_PTR2ID_WATERMARK) {
116953 + _fm_cpt_dbg(COMPAT_GENERIC, "Error, invalid watermark (0x%08x)!\n\n", comp);
116954 + dump_stack();
116955 + return compat_ptr(comp);
116956 + }
116957 +
116958 + comp &= ~COMPAT_PTR2ID_WM_MASK;
116959 +
116960 + if(((0 < comp) && (comp < COMPAT_PTR2ID_ARRAY_MAX) && (compat_ptr2id_array[comp].ptr != NULL)
116961 + && compat_ptr2id_array[comp].node_type == node_type)) {
116962 + _fm_cpt_dbg(COMPAT_GENERIC, "%p\n", compat_ptr2id_array[comp].ptr);
116963 + return compat_ptr2id_array[comp].ptr;
116964 + }
116965 + return NULL;
116966 +}
116967 +EXPORT_SYMBOL(compat_get_id2ptr);
116968 +/* } maping kernel pointers w/ UserSpace id's */
116969 +
116970 +void compat_obj_delete(
116971 + ioc_compat_fm_obj_t *compat_id,
116972 + ioc_fm_obj_t *id)
116973 +{
116974 + id->obj = compat_pcd_id2ptr(compat_id->obj);
116975 + compat_del_ptr2id(id->obj, FM_MAP_TYPE_PCD_NODE);
116976 +}
116977 +
116978 +static inline void compat_copy_fm_pcd_plcr_next_engine(
116979 + ioc_compat_fm_pcd_plcr_next_engine_params_u *compat_param,
116980 + ioc_fm_pcd_plcr_next_engine_params_u *param,
116981 + ioc_fm_pcd_engine next_engine,
116982 + uint8_t compat)
116983 +{
116984 + _fm_cpt_dbg (compat, " {->...\n");
116985 +
116986 + switch (next_engine)
116987 + {
116988 + case e_IOC_FM_PCD_PLCR:
116989 + if (compat == COMPAT_US_TO_K)
116990 + param->p_profile = compat_pcd_id2ptr(compat_param->p_profile);
116991 + else
116992 + compat_param->p_profile = compat_pcd_ptr2id(param->p_profile);
116993 + break;
116994 + case e_IOC_FM_PCD_KG:
116995 + if (compat == COMPAT_US_TO_K)
116996 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116997 + else
116998 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116999 + break;
117000 + default:
117001 + if (compat == COMPAT_US_TO_K)
117002 + param->action = compat_param->action;
117003 + else
117004 + compat_param->action = param->action;
117005 + break;
117006 + }
117007 +
117008 + _fm_cpt_dbg (compat, " ...->}\n");
117009 +}
117010 +
117011 +void compat_copy_fm_pcd_plcr_profile(
117012 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
117013 + ioc_fm_pcd_plcr_profile_params_t *param,
117014 + uint8_t compat)
117015 +{
117016 + _fm_cpt_dbg (compat, " {->...\n");
117017 +
117018 + if (compat == COMPAT_US_TO_K)
117019 + {
117020 + param->modify = compat_param->modify;
117021 +
117022 + /* profile_select */
117023 + if (!compat_param->modify)
117024 + {
117025 + param->profile_select.new_params.profile_type =
117026 + compat_param->profile_select.new_params.profile_type;
117027 + param->profile_select.new_params.p_fm_port =
117028 + compat_ptr(compat_param->profile_select.new_params.p_fm_port);
117029 + param->profile_select.new_params.relative_profile_id =
117030 + compat_param->profile_select.new_params.relative_profile_id;
117031 + }
117032 + else
117033 + param->profile_select.p_profile =
117034 + compat_pcd_id2ptr(compat_param->profile_select.p_profile);
117035 +
117036 + param->alg_selection = compat_param->alg_selection;
117037 + param->color_mode = compat_param->color_mode;
117038 +
117039 + /* both parameters in the union has the same size, so memcpy works */
117040 + memcpy(&param->color, &compat_param->color, sizeof(param->color));
117041 +
117042 + memcpy(&param->non_passthrough_alg_param,
117043 + &compat_param->non_passthrough_alg_param,
117044 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
117045 +
117046 + param->next_engine_on_green = compat_param->next_engine_on_green;
117047 + param->next_engine_on_yellow = compat_param->next_engine_on_yellow;
117048 + param->next_engine_on_red = compat_param->next_engine_on_red;
117049 +
117050 + param->trap_profile_on_flow_A = compat_param->trap_profile_on_flow_A;
117051 + param->trap_profile_on_flow_B = compat_param->trap_profile_on_flow_B;
117052 + param->trap_profile_on_flow_C = compat_param->trap_profile_on_flow_C;
117053 + }
117054 + else
117055 + {
117056 + compat_param->modify = param->modify;
117057 +
117058 + /* profile_select */
117059 + if (!param->modify)
117060 + {
117061 + compat_param->profile_select.new_params.profile_type =
117062 + param->profile_select.new_params.profile_type;
117063 + compat_param->profile_select.new_params.p_fm_port =
117064 + ptr_to_compat(param->profile_select.new_params.p_fm_port);
117065 + compat_param->profile_select.new_params.relative_profile_id =
117066 + param->profile_select.new_params.relative_profile_id;
117067 + }
117068 + else
117069 + compat_param->profile_select.p_profile =
117070 + compat_pcd_ptr2id(param->profile_select.p_profile);
117071 +
117072 + compat_param->alg_selection = param->alg_selection;
117073 + compat_param->color_mode = param->color_mode;
117074 +
117075 + /* both parameters in the union has the same size, so memcpy works */
117076 + memcpy(&compat_param->color, &param->color, sizeof(compat_param->color));
117077 +
117078 + memcpy(&compat_param->non_passthrough_alg_param,
117079 + &param->non_passthrough_alg_param,
117080 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
117081 +
117082 + compat_param->next_engine_on_green = param->next_engine_on_green;
117083 + compat_param->next_engine_on_yellow = param->next_engine_on_yellow;
117084 + compat_param->next_engine_on_red = param->next_engine_on_red;
117085 +
117086 + compat_param->trap_profile_on_flow_A = param->trap_profile_on_flow_A;
117087 + compat_param->trap_profile_on_flow_B = param->trap_profile_on_flow_B;
117088 + compat_param->trap_profile_on_flow_C = param->trap_profile_on_flow_C;
117089 +
117090 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117091 + }
117092 +
117093 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_green,
117094 + &param->params_on_green, param->next_engine_on_green, compat);
117095 +
117096 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_yellow,
117097 + &param->params_on_yellow, param->next_engine_on_yellow, compat);
117098 +
117099 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_red,
117100 + &param->params_on_red, param->next_engine_on_red, compat);
117101 +
117102 + _fm_cpt_dbg (compat, " ...->}\n");
117103 +}
117104 +
117105 +static inline void compat_copy_fm_pcd_cc_next_kg(
117106 + ioc_compat_fm_pcd_cc_next_kg_params_t *compat_param,
117107 + ioc_fm_pcd_cc_next_kg_params_t *param,
117108 + uint8_t compat)
117109 +{
117110 + _fm_cpt_dbg (compat, " {->...\n");
117111 +
117112 + if (compat == COMPAT_US_TO_K)
117113 + {
117114 + param->new_fqid = compat_param->new_fqid;
117115 + param->override_fqid = compat_param->override_fqid;
117116 +#if DPAA_VERSION >= 11
117117 + param->new_relative_storage_profile_id = compat_param->new_relative_storage_profile_id;
117118 +#endif
117119 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
117120 + }
117121 + else
117122 + {
117123 + compat_param->new_fqid = param->new_fqid;
117124 + compat_param->override_fqid = param->override_fqid;
117125 +#if DPAA_VERSION >= 11
117126 + compat_param->new_relative_storage_profile_id = param->new_relative_storage_profile_id;
117127 +#endif
117128 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
117129 + }
117130 +
117131 + _fm_cpt_dbg (compat, " ...->}\n");
117132 +}
117133 +
117134 +static inline void compat_copy_fm_pcd_cc_next_cc(
117135 + ioc_compat_fm_pcd_cc_next_cc_params_t *compat_param,
117136 + ioc_fm_pcd_cc_next_cc_params_t *param,
117137 + uint8_t compat)
117138 +{
117139 + _fm_cpt_dbg (compat, " {->...\n");
117140 +
117141 + if (compat == COMPAT_US_TO_K)
117142 + param->cc_node_id = compat_pcd_id2ptr(compat_param->cc_node_id);
117143 + else
117144 + compat_param->cc_node_id = compat_pcd_ptr2id(param->cc_node_id);
117145 +
117146 + _fm_cpt_dbg (compat, " ...->}\n");
117147 +}
117148 +
117149 +static inline void compat_copy_fm_pcd_cc_next_engine(
117150 + ioc_compat_fm_pcd_cc_next_engine_params_t *compat_param,
117151 + ioc_fm_pcd_cc_next_engine_params_t *param,
117152 + uint8_t compat)
117153 +{
117154 + _fm_cpt_dbg (compat, " {->...\n");
117155 +
117156 + if (compat == COMPAT_US_TO_K)
117157 + {
117158 + param->next_engine = compat_param->next_engine;
117159 + if (param->next_engine != e_IOC_FM_PCD_INVALID )
117160 + _fm_cpt_dbg(compat, " param->next_engine = %i \n", param->next_engine);
117161 +
117162 + switch (param->next_engine)
117163 + {
117164 +#if DPAA_VERSION >= 11
117165 + case e_IOC_FM_PCD_FR:
117166 + param->params.fr_params.frm_replic_id = compat_pcd_id2ptr(compat_param->params.fr_params.frm_replic_id);
117167 + break;
117168 +#endif /* DPAA_VERSION >= 11 */
117169 + case e_IOC_FM_PCD_CC:
117170 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
117171 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
117172 + break;
117173 + case e_IOC_FM_PCD_KG:
117174 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
117175 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
117176 + break;
117177 + case e_IOC_FM_PCD_DONE:
117178 + case e_IOC_FM_PCD_PLCR:
117179 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
117180 + default:
117181 + memcpy(&param->params, &compat_param->params, sizeof(param->params));
117182 + }
117183 + param->statistics_en = compat_param->statistics_en;
117184 + }
117185 + else
117186 + {
117187 + compat_param->next_engine = param->next_engine;
117188 +
117189 + switch (compat_param->next_engine)
117190 + {
117191 +#if DPAA_VERSION >= 11
117192 + case e_IOC_FM_PCD_FR:
117193 + compat_param->params.fr_params.frm_replic_id = compat_pcd_ptr2id(param->params.fr_params.frm_replic_id);
117194 + break;
117195 +#endif /* DPAA_VERSION >= 11 */
117196 + case e_IOC_FM_PCD_CC:
117197 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
117198 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
117199 + break;
117200 + case e_IOC_FM_PCD_KG:
117201 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
117202 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
117203 + break;
117204 + case e_IOC_FM_PCD_DONE:
117205 + case e_IOC_FM_PCD_PLCR:
117206 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
117207 + default:
117208 + memcpy(&compat_param->params, &param->params, sizeof(compat_param->params));
117209 + }
117210 + compat_param->statistics_en = param->statistics_en;
117211 + }
117212 +
117213 + _fm_cpt_dbg (compat, " ...->}\n");
117214 +}
117215 +
117216 +void compat_copy_fm_pcd_cc_key(
117217 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
117218 + ioc_fm_pcd_cc_key_params_t *param,
117219 + uint8_t compat)
117220 +{
117221 + if (compat == COMPAT_US_TO_K)
117222 + {
117223 + param->p_key = compat_ptr(compat_param->p_key);
117224 + param->p_mask = compat_ptr(compat_param->p_mask);
117225 + }
117226 + else
117227 + {
117228 + compat_param->p_key = ptr_to_compat(param->p_key);
117229 + compat_param->p_mask = ptr_to_compat(param->p_mask);
117230 + }
117231 +
117232 + compat_copy_fm_pcd_cc_next_engine(
117233 + &compat_param->cc_next_engine_params,
117234 + &param->cc_next_engine_params,
117235 + compat);
117236 +}
117237 +
117238 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
117239 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
117240 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
117241 + uint8_t compat)
117242 +{
117243 + if (compat == COMPAT_US_TO_K)
117244 + {
117245 + param->id = compat_pcd_id2ptr(compat_param->id);
117246 + param->key_indx = compat_param->key_indx;
117247 + param->key_size = compat_param->key_size;
117248 + compat_copy_fm_pcd_cc_key(
117249 + &compat_param->key_params,
117250 + &param->key_params,
117251 + compat);
117252 + }
117253 + else
117254 + {
117255 + compat_param->id = compat_pcd_ptr2id(param->id);
117256 + compat_param->key_indx = param->key_indx;
117257 + compat_param->key_size = param->key_size;
117258 + compat_copy_fm_pcd_cc_key(
117259 + &compat_param->key_params,
117260 + &param->key_params,
117261 + compat);
117262 + }
117263 +}
117264 +
117265 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
117266 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
117267 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
117268 + uint8_t compat)
117269 +{
117270 + if (compat == COMPAT_US_TO_K)
117271 + {
117272 + param->id = compat_pcd_id2ptr(compat_param->id);
117273 + param->key_indx = compat_param->key_indx;
117274 + param->key_size = compat_param->key_size;
117275 + }
117276 + else
117277 + {
117278 + compat_param->id = compat_pcd_ptr2id(param->id);
117279 + compat_param->key_indx = param->key_indx;
117280 + compat_param->key_size = param->key_size;
117281 + }
117282 +
117283 + compat_copy_fm_pcd_cc_next_engine(
117284 + &compat_param->cc_next_engine_params,
117285 + &param->cc_next_engine_params,
117286 + compat);
117287 +}
117288 +
117289 +void compat_fm_pcd_cc_tree_modify_next_engine(
117290 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
117291 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
117292 + uint8_t compat)
117293 +{
117294 + if (compat == COMPAT_US_TO_K)
117295 + {
117296 + param->id = compat_pcd_id2ptr(compat_param->id);
117297 + param->grp_indx = compat_param->grp_indx;
117298 + param->indx = compat_param->indx;
117299 + }
117300 + else
117301 + {
117302 + compat_param->id = compat_pcd_ptr2id(param->id);
117303 + compat_param->grp_indx = param->grp_indx;
117304 + compat_param->indx = param->indx;
117305 + }
117306 +
117307 + compat_copy_fm_pcd_cc_next_engine(
117308 + &compat_param->cc_next_engine_params,
117309 + &param->cc_next_engine_params,
117310 + compat);
117311 +}
117312 +
117313 +void compat_copy_fm_pcd_hash_table(
117314 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
117315 + ioc_fm_pcd_hash_table_params_t *param,
117316 + uint8_t compat)
117317 +{
117318 + if (compat == COMPAT_US_TO_K)
117319 + {
117320 + param->max_num_of_keys = compat_param->max_num_of_keys;
117321 + param->statistics_mode = compat_param->statistics_mode;
117322 + param->kg_hash_shift = compat_param->kg_hash_shift;
117323 + param->hash_res_mask = compat_param->hash_res_mask;
117324 + param->hash_shift = compat_param->hash_shift;
117325 + param->match_key_size = compat_param->match_key_size;
117326 + param->id = compat_pcd_id2ptr(compat_param->id);
117327 + }
117328 + else
117329 + {
117330 + compat_param->max_num_of_keys = param->max_num_of_keys;
117331 + compat_param->statistics_mode = param->statistics_mode;
117332 + compat_param->kg_hash_shift = param->kg_hash_shift;
117333 + compat_param->hash_res_mask = param->hash_res_mask;
117334 + compat_param->hash_shift = param->hash_shift;
117335 + compat_param->match_key_size = param->match_key_size;
117336 +
117337 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117338 + }
117339 +
117340 + compat_copy_fm_pcd_cc_next_engine(
117341 + &compat_param->cc_next_engine_params_for_miss,
117342 + &param->cc_next_engine_params_for_miss,
117343 + compat);
117344 +}
117345 +
117346 +void compat_copy_fm_pcd_cc_grp(
117347 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
117348 + ioc_fm_pcd_cc_grp_params_t *param,
117349 + uint8_t compat)
117350 +{
117351 + int k;
117352 +
117353 + _fm_cpt_dbg (compat, " {->...\n");
117354 +
117355 + if (compat == COMPAT_US_TO_K)
117356 + {
117357 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
117358 + memcpy(param->unit_ids, compat_param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
117359 + }
117360 + else
117361 + {
117362 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
117363 + memcpy(compat_param->unit_ids, param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
117364 + }
117365 +
117366 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP; k++)
117367 + compat_copy_fm_pcd_cc_next_engine(
117368 + &compat_param->next_engine_per_entries_in_grp[k],
117369 + &param->next_engine_per_entries_in_grp[k],
117370 + compat);
117371 +
117372 + _fm_cpt_dbg (compat, " ...->}\n");
117373 +}
117374 +
117375 +void compat_copy_fm_pcd_cc_tree(
117376 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
117377 + ioc_fm_pcd_cc_tree_params_t *param,
117378 + uint8_t compat)
117379 +{
117380 + int k;
117381 + _fm_cpt_dbg (compat, " {->...\n");
117382 +
117383 + if (compat == COMPAT_US_TO_K)
117384 + {
117385 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
117386 + param->num_of_groups = compat_param->num_of_groups;
117387 + }
117388 + else
117389 + {
117390 + compat_param->net_env_id = compat_pcd_ptr2id(param->net_env_id);
117391 + compat_param->num_of_groups = param->num_of_groups;
117392 +
117393 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117394 + }
117395 +
117396 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS; k++)
117397 + compat_copy_fm_pcd_cc_grp(
117398 + &compat_param->fm_pcd_cc_group_params[k],
117399 + &param->fm_pcd_cc_group_params[k],
117400 + compat);
117401 +
117402 + _fm_cpt_dbg (compat, " ...->}\n");
117403 +}
117404 +
117405 +void compat_fm_pcd_prs_sw(
117406 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
117407 + ioc_fm_pcd_prs_sw_params_t *param,
117408 + uint8_t compat)
117409 +{
117410 + if (compat == COMPAT_US_TO_K)
117411 + {
117412 + param->override = compat_param->override;
117413 + param->size = compat_param->size;
117414 + param->base = compat_param->base;
117415 + param->p_code = compat_ptr(compat_param->p_code);
117416 + memcpy(param->sw_prs_data_params,compat_param->sw_prs_data_params,IOC_FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t));
117417 + param->num_of_labels = compat_param->num_of_labels;
117418 + memcpy(param->labels_table,compat_param->labels_table,IOC_FM_PCD_PRS_NUM_OF_LABELS*sizeof(ioc_fm_pcd_prs_label_params_t));
117419 + }
117420 +}
117421 +
117422 +void compat_copy_fm_pcd_kg_scheme(
117423 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
117424 + ioc_fm_pcd_kg_scheme_params_t *param,
117425 + uint8_t compat)
117426 +{
117427 + _fm_cpt_dbg(compat," {->...\n");
117428 +
117429 + if (compat == COMPAT_US_TO_K)
117430 + {
117431 + param->modify = compat_param->modify;
117432 +
117433 + /* scm_id */
117434 + if (compat_param->modify)
117435 + {
117436 + param->scm_id.scheme_id = compat_pcd_id2ptr(compat_param->scm_id.scheme_id);
117437 + _fm_cpt_dbg(compat," param->scm_id.scheme_id = %p \n", param->scm_id.scheme_id);
117438 + }
117439 + else
117440 + param->scm_id.relative_scheme_id = compat_param->scm_id.relative_scheme_id;
117441 +
117442 + param->always_direct = compat_param->always_direct;
117443 + /* net_env_params */
117444 + param->net_env_params.net_env_id = compat_pcd_id2ptr(compat_param->net_env_params.net_env_id);
117445 + param->net_env_params.num_of_distinction_units = compat_param->net_env_params.num_of_distinction_units;
117446 + memcpy(param->net_env_params.unit_ids,
117447 + compat_param->net_env_params.unit_ids,
117448 + IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117449 +
117450 + param->use_hash = compat_param->use_hash;
117451 + memcpy(&param->key_extract_and_hash_params,
117452 + &compat_param->key_extract_and_hash_params,
117453 + sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
117454 + param->bypass_fqid_generation = compat_param->bypass_fqid_generation;
117455 + param->base_fqid = compat_param->base_fqid;
117456 +#if DPAA_VERSION >= 11
117457 + param->override_storage_profile =
117458 + compat_param->override_storage_profile;
117459 + param->storage_profile = compat_param->storage_profile;
117460 +#endif
117461 + param->num_of_used_extracted_ors = compat_param->num_of_used_extracted_ors;
117462 + memcpy(param->extracted_ors,
117463 + compat_param->extracted_ors,
117464 + IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
117465 + param->next_engine = compat_param->next_engine;
117466 +
117467 + /* kg_next_engine_params */
117468 + if (param->next_engine == e_IOC_FM_PCD_CC)
117469 + {
117470 + param->kg_next_engine_params.cc.tree_id = compat_pcd_id2ptr(compat_param->kg_next_engine_params.cc.tree_id);
117471 + param->kg_next_engine_params.cc.grp_id = compat_param->kg_next_engine_params.cc.grp_id;
117472 + param->kg_next_engine_params.cc.plcr_next = compat_param->kg_next_engine_params.cc.plcr_next;
117473 + param->kg_next_engine_params.cc.bypass_plcr_profile_generation
117474 + = compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
117475 + memcpy(&param->kg_next_engine_params.cc.plcr_profile,
117476 + &compat_param->kg_next_engine_params.cc.plcr_profile,
117477 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
117478 + }
117479 + else
117480 + memcpy(&param->kg_next_engine_params,
117481 + &compat_param->kg_next_engine_params,
117482 + sizeof(param->kg_next_engine_params));
117483 +
117484 + memcpy(&param->scheme_counter,
117485 + &compat_param->scheme_counter,
117486 + sizeof(ioc_fm_pcd_kg_scheme_counter_t));
117487 + }
117488 + else
117489 + {
117490 + compat_param->modify = param->modify;
117491 +
117492 + /* scm_id */
117493 + if (param->modify)
117494 + compat_param->scm_id.scheme_id = compat_pcd_ptr2id(param->scm_id.scheme_id);
117495 + else
117496 + compat_param->scm_id.relative_scheme_id = param->scm_id.relative_scheme_id;
117497 +
117498 + compat_param->always_direct = param->always_direct;
117499 +
117500 + /* net_env_params */
117501 + compat_param->net_env_params.net_env_id = compat_pcd_ptr2id(param->net_env_params.net_env_id);
117502 + compat_param->net_env_params.num_of_distinction_units = param->net_env_params.num_of_distinction_units;
117503 + memcpy(compat_param->net_env_params.unit_ids, param->net_env_params.unit_ids, IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117504 +
117505 + compat_param->use_hash = param->use_hash;
117506 + 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));
117507 + compat_param->bypass_fqid_generation = param->bypass_fqid_generation;
117508 + compat_param->base_fqid = param->base_fqid;
117509 +#if DPAA_VERSION >= 11
117510 + compat_param->override_storage_profile =
117511 + param->override_storage_profile;
117512 + compat_param->storage_profile = param->storage_profile;
117513 +#endif
117514 + compat_param->num_of_used_extracted_ors = param->num_of_used_extracted_ors;
117515 + 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));
117516 + compat_param->next_engine = param->next_engine;
117517 +
117518 + /* kg_next_engine_params */
117519 + if (compat_param->next_engine == e_IOC_FM_PCD_CC)
117520 + {
117521 + compat_param->kg_next_engine_params.cc.tree_id = compat_pcd_ptr2id(param->kg_next_engine_params.cc.tree_id);
117522 + compat_param->kg_next_engine_params.cc.grp_id = param->kg_next_engine_params.cc.grp_id;
117523 + compat_param->kg_next_engine_params.cc.plcr_next = param->kg_next_engine_params.cc.plcr_next;
117524 + compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation
117525 + = param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
117526 + memcpy(&compat_param->kg_next_engine_params.cc.plcr_profile,
117527 + &param->kg_next_engine_params.cc.plcr_profile,
117528 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
117529 + }
117530 + else
117531 + memcpy(&param->kg_next_engine_params, &compat_param->kg_next_engine_params, sizeof(compat_param->kg_next_engine_params));
117532 +
117533 + memcpy(&compat_param->scheme_counter, &param->scheme_counter, sizeof(ioc_fm_pcd_kg_scheme_counter_t));
117534 +
117535 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117536 + }
117537 +
117538 + _fm_cpt_dbg(compat," ...->}\n");
117539 +}
117540 +
117541 +void compat_copy_fm_pcd_kg_scheme_spc(
117542 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
117543 + ioc_fm_pcd_kg_scheme_spc_t *param,
117544 + uint8_t compat)
117545 +{
117546 + if (compat == COMPAT_US_TO_K)
117547 + {
117548 + param->id = compat_pcd_id2ptr(compat_param->id);
117549 + param->val = compat_param->val;
117550 + } else {
117551 + compat_param->id = compat_pcd_ptr2id(param->id);
117552 + compat_param->val = param->val;
117553 + }
117554 +}
117555 +
117556 +
117557 +void compat_copy_fm_pcd_kg_scheme_select(
117558 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
117559 + ioc_fm_pcd_kg_scheme_select_t *param,
117560 + uint8_t compat)
117561 +{
117562 + if (compat == COMPAT_US_TO_K)
117563 + {
117564 + param->direct = compat_param->direct;
117565 + if (param->direct)
117566 + param->scheme_id = compat_pcd_id2ptr(compat_param->scheme_id);
117567 + }
117568 +}
117569 +
117570 +void compat_copy_fm_pcd_kg_schemes_params(
117571 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
117572 + ioc_fm_pcd_port_schemes_params_t *param,
117573 + uint8_t compat)
117574 +{
117575 + int k;
117576 +
117577 + if (compat == COMPAT_US_TO_K) {
117578 + param->num_of_schemes = compat_param->num_of_schemes;
117579 + for(k=0; k < compat_param->num_of_schemes; k++)
117580 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
117581 + }
117582 +}
117583 +
117584 +void compat_copy_fm_port_pcd_cc(
117585 + ioc_compat_fm_port_pcd_cc_params_t *compat_cc_params ,
117586 + ioc_fm_port_pcd_cc_params_t *p_cc_params,
117587 + uint8_t compat)
117588 +{
117589 + if (compat == COMPAT_US_TO_K){
117590 + p_cc_params->cc_tree_id = compat_pcd_id2ptr(compat_cc_params->cc_tree_id);
117591 + }
117592 +}
117593 +
117594 +void compat_copy_fm_port_pcd_kg(
117595 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
117596 + ioc_fm_port_pcd_kg_params_t *param,
117597 + uint8_t compat)
117598 +{
117599 + if (compat == COMPAT_US_TO_K){
117600 + uint8_t k;
117601 +
117602 + param->num_of_schemes = compat_param->num_of_schemes;
117603 + for(k=0; k<compat_param->num_of_schemes; k++)
117604 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
117605 +
117606 + param->direct_scheme = compat_param->direct_scheme;
117607 + if (param->direct_scheme)
117608 + param->direct_scheme_id = compat_pcd_id2ptr(compat_param->direct_scheme_id);
117609 + }
117610 +}
117611 +
117612 +void compat_copy_fm_port_pcd(
117613 + ioc_compat_fm_port_pcd_params_t *compat_param,
117614 + ioc_fm_port_pcd_params_t *param,
117615 + uint8_t compat)
117616 +{
117617 + if (compat == COMPAT_US_TO_K)
117618 + {
117619 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
117620 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
117621 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
117622 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
117623 +
117624 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_param + 1);
117625 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
117626 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
117627 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
117628 +
117629 + _fm_cpt_dbg(compat,"\n param->p_prs_params=%p \n", param->p_prs_params);
117630 + _fm_cpt_dbg(compat," param->p_cc_params=%p \n", param->p_cc_params);
117631 + _fm_cpt_dbg(compat," param->p_kg_params=%p \n", param->p_kg_params);
117632 + _fm_cpt_dbg(compat," param->p_plcr_params=%p \n", param->p_plcr_params);
117633 + _fm_cpt_dbg(compat," param->p_ip_reassembly_manip=%p \n", param->p_ip_reassembly_manip);
117634 +#if (DPAA_VERSION >= 11)
117635 + _fm_cpt_dbg(compat," param->p_capwap_reassembly_manip=%p \n", param->p_capwap_reassembly_manip);
117636 +#endif
117637 + param->pcd_support = compat_param->pcd_support;
117638 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
117639 +
117640 + if (param->p_cc_params)
117641 + compat_copy_fm_port_pcd_cc(compat_port_pcd_cc_params, param->p_cc_params, COMPAT_US_TO_K);
117642 + if (param->p_kg_params)
117643 + compat_copy_fm_port_pcd_kg(compat_port_pcd_kg_params, param->p_kg_params, COMPAT_US_TO_K);
117644 + if (param->p_plcr_params)
117645 + param->p_plcr_params->plcr_profile_id = compat_pcd_id2ptr(compat_port_pcd_plcr_params->plcr_profile_id);
117646 + param->p_ip_reassembly_manip = compat_pcd_id2ptr(compat_param->p_ip_reassembly_manip);
117647 +#if (DPAA_VERSION >= 11)
117648 + param->p_capwap_reassembly_manip = compat_pcd_id2ptr(compat_param->p_capwap_reassembly_manip);
117649 +#endif
117650 + }
117651 +}
117652 +
117653 +void compat_copy_fm_port_pcd_modify_tree(
117654 + ioc_compat_fm_obj_t *compat_id,
117655 + ioc_fm_obj_t *id,
117656 + uint8_t compat)
117657 +{
117658 + if (compat == COMPAT_US_TO_K)
117659 + id->obj = compat_pcd_id2ptr(compat_id->obj);
117660 +}
117661 +
117662 +#if (DPAA_VERSION >= 11)
117663 +void compat_copy_fm_port_vsp_alloc_params(
117664 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
117665 + ioc_fm_port_vsp_alloc_params_t *param,
117666 + uint8_t compat)
117667 +{
117668 + if (compat == COMPAT_US_TO_K)
117669 + {
117670 + _fm_cpt_dbg(compat," param->p_fm_tx_port=%p \n", param->p_fm_tx_port);
117671 +
117672 + param->dflt_relative_id = compat_param->dflt_relative_id;
117673 + param->num_of_profiles = compat_param->num_of_profiles;
117674 + param->p_fm_tx_port = compat_pcd_id2ptr(compat_param->p_fm_tx_port);
117675 + }
117676 +}
117677 +#endif /* (DPAA_VERSION >= 11) */
117678 +
117679 +void compat_copy_fm_pcd_cc_tbl_get_stats(
117680 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
117681 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
117682 + uint8_t compat)
117683 +{
117684 + if (compat == COMPAT_US_TO_K)
117685 + {
117686 + param->id = compat_pcd_id2ptr(compat_param->id);
117687 + param->key_index = compat_param->key_index;
117688 + memcpy(&param->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
117689 + } else {
117690 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117691 + compat_param->key_index = param->key_index;
117692 + memcpy(&compat_param->statistics, &param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
117693 + }
117694 +}
117695 +
117696 +
117697 +void compat_copy_fm_pcd_net_env(
117698 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
117699 + ioc_fm_pcd_net_env_params_t *param,
117700 + uint8_t compat)
117701 +{
117702 + if (compat == COMPAT_US_TO_K)
117703 + {
117704 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
117705 + memcpy(param->units, compat_param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117706 + param->id = NULL; /* to avoid passing garbage to the kernel */
117707 + }
117708 + else
117709 + {
117710 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
117711 + memcpy(compat_param->units, param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117712 +
117713 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117714 + }
117715 +}
117716 +
117717 +void compat_copy_fm_pcd_cc_node_modify_key(
117718 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
117719 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
117720 + uint8_t compat)
117721 +{
117722 + if (compat == COMPAT_US_TO_K)
117723 + {
117724 + param->key_indx = compat_param->key_indx;
117725 + param->key_size = compat_param->key_size;
117726 + param->p_key = (uint8_t *)compat_ptr(compat_param->p_key);
117727 + _fm_cpt_dbg(compat," param->p_key = %p \n", param->p_key);
117728 + param->p_mask = (uint8_t *)compat_ptr(compat_param->p_mask);
117729 + _fm_cpt_dbg(compat," param->p_mask = %p\n", param->p_mask);
117730 + param->id = compat_pcd_id2ptr(compat_param->id);
117731 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117732 + }
117733 + else
117734 + {
117735 + compat_param->key_indx = param->key_indx;
117736 + compat_param->key_size = param->key_size;
117737 + compat_param->p_key = ptr_to_compat((void *)param->p_key);
117738 + compat_param->p_mask = ptr_to_compat((void *)param->p_mask);
117739 +
117740 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117741 + }
117742 +}
117743 +
117744 +void compat_copy_keys(
117745 + ioc_compat_keys_params_t *compat_param,
117746 + ioc_keys_params_t *param,
117747 + uint8_t compat)
117748 +{
117749 + int k = 0;
117750 +
117751 + _fm_cpt_dbg(compat," {->...\n");
117752 +
117753 + if (compat == COMPAT_US_TO_K) {
117754 + param->max_num_of_keys = compat_param->max_num_of_keys;
117755 + param->mask_support = compat_param->mask_support;
117756 + param->statistics_mode = compat_param->statistics_mode;
117757 + param->num_of_keys = compat_param->num_of_keys;
117758 + param->key_size = compat_param->key_size;
117759 +#if (DPAA_VERSION >= 11)
117760 + memcpy(&param->frame_length_ranges,
117761 + &compat_param->frame_length_ranges,
117762 + sizeof(param->frame_length_ranges[0]) *
117763 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
117764 +#endif /* (DPAA_VERSION >= 11) */
117765 + }
117766 + else {
117767 + compat_param->max_num_of_keys = param->max_num_of_keys;
117768 + compat_param->mask_support = param->mask_support;
117769 + compat_param->statistics_mode = param->statistics_mode;
117770 + compat_param->num_of_keys = param->num_of_keys;
117771 + compat_param->key_size = param->key_size;
117772 +#if (DPAA_VERSION >= 11)
117773 + memcpy(&compat_param->frame_length_ranges,
117774 + &param->frame_length_ranges,
117775 + sizeof(compat_param->frame_length_ranges[0]) *
117776 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
117777 +#endif /* (DPAA_VERSION >= 11) */
117778 + }
117779 +
117780 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_KEYS; k++)
117781 + compat_copy_fm_pcd_cc_key(
117782 + &compat_param->key_params[k],
117783 + &param->key_params[k],
117784 + compat);
117785 +
117786 + compat_copy_fm_pcd_cc_next_engine(
117787 + &compat_param->cc_next_engine_params_for_miss,
117788 + &param->cc_next_engine_params_for_miss,
117789 + compat);
117790 +
117791 + _fm_cpt_dbg(compat," ...->}\n");
117792 +}
117793 +
117794 +void compat_copy_fm_pcd_cc_node(
117795 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
117796 + ioc_fm_pcd_cc_node_params_t *param,
117797 + uint8_t compat)
117798 +{
117799 + _fm_cpt_dbg(compat," {->...\n");
117800 +
117801 + if (compat == COMPAT_US_TO_K)
117802 + memcpy(&param->extract_cc_params, &compat_param->extract_cc_params, sizeof(ioc_fm_pcd_extract_entry_t));
117803 +
117804 + else
117805 + {
117806 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117807 +
117808 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117809 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117810 + }
117811 +
117812 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117813 +
117814 + _fm_cpt_dbg(compat," ...->}\n");
117815 +}
117816 +
117817 +void compat_fm_pcd_manip_set_node(
117818 + ioc_compat_fm_pcd_manip_params_t *compat_param,
117819 + ioc_fm_pcd_manip_params_t *param,
117820 + uint8_t compat)
117821 +{
117822 + if (compat == COMPAT_US_TO_K) {
117823 + param->type = compat_param->type;
117824 + switch (param->type) {
117825 + case e_IOC_FM_PCD_MANIP_HDR:
117826 + param->u.hdr.rmv = compat_param->u.hdr.rmv;
117827 + memcpy(&param->u.hdr.rmv_params,
117828 + &compat_param->u.hdr.rmv_params,
117829 + sizeof(param->u.hdr.rmv_params));
117830 +
117831 + param->u.hdr.insrt = compat_param->u.hdr.insrt;
117832 + param->u.hdr.insrt_params.type =
117833 + compat_param->u.hdr.insrt_params.type;
117834 + switch (compat_param->u.hdr.insrt_params.type)
117835 + {
117836 + case e_IOC_FM_PCD_MANIP_INSRT_GENERIC:
117837 + param->u.hdr.insrt_params.u.generic.offset =
117838 + compat_param->u.hdr.insrt_params.u.generic.offset;
117839 + param->u.hdr.insrt_params.u.generic.size =
117840 + compat_param->u.hdr.insrt_params.u.generic.size;
117841 + param->u.hdr.insrt_params.u.generic.replace =
117842 + compat_param->u.hdr.insrt_params.u.generic.replace;
117843 + param->u.hdr.insrt_params.u.generic.p_data =
117844 + compat_ptr(compat_param->u.hdr.insrt_params.u.generic.p_data);
117845 + break;
117846 + case e_IOC_FM_PCD_MANIP_INSRT_BY_HDR:
117847 + param->u.hdr.insrt_params.u.by_hdr.type =
117848 + compat_param->u.hdr.insrt_params.u.by_hdr.type;
117849 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2 =
117850 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2;
117851 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update =
117852 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update;
117853 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size =
117854 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size;
117855 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data =
117856 + compat_ptr(compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data);
117857 + break;
117858 + default:
117859 + _fm_cpt_err("Unsupported type: %d", compat_param->u.hdr.insrt_params.type);
117860 + }
117861 +
117862 + param->u.hdr.field_update = compat_param->u.hdr.field_update;
117863 + memcpy(&param->u.hdr.field_update_params,
117864 + &compat_param->u.hdr.field_update_params,
117865 + sizeof(param->u.hdr.field_update_params));
117866 +
117867 + param->u.hdr.custom = compat_param->u.hdr.custom;
117868 + memcpy(&param->u.hdr.custom_params,
117869 + &compat_param->u.hdr.custom_params,
117870 + sizeof(param->u.hdr.custom_params));
117871 +
117872 + param->u.hdr.dont_parse_after_manip =
117873 + compat_param->u.hdr.dont_parse_after_manip;
117874 + break;
117875 + case e_IOC_FM_PCD_MANIP_REASSEM:
117876 + memcpy(&param->u.reassem, &compat_param->u.reassem, sizeof(param->u.reassem));
117877 + break;
117878 + case e_IOC_FM_PCD_MANIP_FRAG:
117879 + memcpy(&param->u.frag, &compat_param->u.frag, sizeof(param->u.frag));
117880 + break;
117881 + case e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD:
117882 + memcpy(&param->u.special_offload,
117883 + &compat_param->u.special_offload,
117884 + sizeof(param->u.special_offload));
117885 + break;
117886 + }
117887 +
117888 + param->p_next_manip = compat_pcd_id2ptr(compat_param->p_next_manip);
117889 + param->id = compat_pcd_id2ptr(compat_param->id);
117890 + }
117891 + else {
117892 + compat_param->type = param->type;
117893 + memcpy(&compat_param->u, &param->u, sizeof(compat_param->u));
117894 +
117895 + if (param->type == e_IOC_FM_PCD_MANIP_HDR &&
117896 + param->u.hdr.insrt_params.type == e_IOC_FM_PCD_MANIP_INSRT_GENERIC)
117897 + compat_param->u.hdr.insrt_params.u.generic.p_data =
117898 + ptr_to_compat(param->u.hdr.insrt_params.u.generic.p_data);
117899 +
117900 + compat_param->p_next_manip = compat_pcd_ptr2id(param->id);
117901 + /* ... should be one that was added previously by the very call to
117902 + compat_add_ptr2id() below: */
117903 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117904 + }
117905 +}
117906 +
117907 +void compat_copy_fm_pcd_manip_get_stats(
117908 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
117909 + ioc_fm_pcd_manip_get_stats_t *param,
117910 + uint8_t compat)
117911 +{
117912 + _fm_cpt_dbg (compat, " {->...\n");
117913 +
117914 + if (compat == COMPAT_US_TO_K)
117915 + {
117916 + param->id = compat_pcd_id2ptr(compat_param->id);
117917 + memcpy(&param->stats, &compat_param->stats,
117918 + sizeof(ioc_fm_pcd_manip_stats_t));
117919 + }
117920 + else
117921 + {
117922 + compat_param->id = compat_add_ptr2id(param->id,
117923 + FM_MAP_TYPE_PCD_NODE);
117924 + memcpy(&compat_param->stats, &param->stats,
117925 + sizeof(ioc_fm_pcd_manip_stats_t));
117926 + }
117927 +
117928 + _fm_cpt_dbg (compat, " ...->}\n");
117929 +}
117930 +
117931 +#if (DPAA_VERSION >= 11)
117932 +void compat_copy_fm_pcd_frm_replic_group_params(
117933 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
117934 + ioc_fm_pcd_frm_replic_group_params_t *param,
117935 + uint8_t compat)
117936 +{
117937 + int k;
117938 +
117939 + _fm_cpt_dbg (compat, " {->...\n");
117940 +
117941 + if (compat == COMPAT_US_TO_K)
117942 + {
117943 + param->max_num_of_entries = compat_param->max_num_of_entries;
117944 + param->num_of_entries = compat_param->num_of_entries;
117945 + param->id = compat_pcd_id2ptr(compat_param->id);
117946 + }
117947 + else
117948 + {
117949 + compat_param->max_num_of_entries = param->max_num_of_entries;
117950 + compat_param->num_of_entries = param->num_of_entries;
117951 + compat_param->id = compat_add_ptr2id(param->id,
117952 + FM_MAP_TYPE_PCD_NODE);
117953 + }
117954 +
117955 + for (k=0; k < IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES; k++)
117956 + compat_copy_fm_pcd_cc_next_engine(
117957 + &compat_param->next_engine_params[k],
117958 + &param->next_engine_params[k],
117959 + compat);
117960 +
117961 + _fm_cpt_dbg (compat, " ...->}\n");
117962 +}
117963 +
117964 +void compat_copy_fm_pcd_frm_replic_member(
117965 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
117966 + ioc_fm_pcd_frm_replic_member_t *param,
117967 + uint8_t compat)
117968 +{
117969 + _fm_cpt_dbg (compat, " {->...\n");
117970 +
117971 + if (compat == COMPAT_US_TO_K)
117972 + {
117973 + param->h_replic_group = compat_pcd_id2ptr(compat_param->h_replic_group);
117974 + param->member_index = compat_param->member_index;
117975 + }
117976 +
117977 + _fm_cpt_dbg (compat, " ...->}\n");
117978 +}
117979 +
117980 +void compat_copy_fm_pcd_frm_replic_member_params(
117981 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
117982 + ioc_fm_pcd_frm_replic_member_params_t *param,
117983 + uint8_t compat)
117984 +{
117985 + _fm_cpt_dbg (compat, " {->...\n");
117986 +
117987 + compat_copy_fm_pcd_frm_replic_member(&compat_param->member,
117988 + &param->member, compat);
117989 +
117990 + compat_copy_fm_pcd_cc_next_engine(&compat_param->next_engine_params,
117991 + &param->next_engine_params, compat);
117992 +
117993 + _fm_cpt_dbg (compat, " ...->}\n");
117994 +}
117995 +
117996 +void compat_copy_fm_vsp_params(
117997 + ioc_compat_fm_vsp_params_t *compat_param,
117998 + ioc_fm_vsp_params_t *param,
117999 + uint8_t compat)
118000 +{
118001 + _fm_cpt_dbg (compat, " {->...\n");
118002 +
118003 + if (compat == COMPAT_US_TO_K)
118004 + {
118005 + memcpy(&param->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
118006 + param->liodn_offset = compat_param->liodn_offset;
118007 + param->port_params.port_id = compat_param->port_params.port_id;
118008 + param->port_params.port_type = compat_param->port_params.port_type;
118009 + param->relative_profile_id = compat_param->relative_profile_id;
118010 + }
118011 + else
118012 + {
118013 + memcpy(&compat_param->ext_buf_pools, &param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
118014 + compat_param->liodn_offset = param->liodn_offset;
118015 + compat_param->port_params.port_id = param->port_params.port_id;
118016 + compat_param->port_params.port_type = param->port_params.port_type;
118017 + compat_param->relative_profile_id = param->relative_profile_id;
118018 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118019 + }
118020 +
118021 + _fm_cpt_dbg (compat, " ...->}\n");
118022 +}
118023 +
118024 +void compat_copy_fm_buf_pool_depletion_params(
118025 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
118026 + ioc_fm_buf_pool_depletion_params_t *param,
118027 + uint8_t compat)
118028 +{
118029 + _fm_cpt_dbg (compat, " {->...\n");
118030 +
118031 + if (compat == COMPAT_US_TO_K)
118032 + {
118033 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
118034 + memcpy(&param->fm_buf_pool_depletion,
118035 + &compat_param->fm_buf_pool_depletion,
118036 + sizeof(ioc_fm_buf_pool_depletion_t));
118037 + }
118038 +
118039 + _fm_cpt_dbg (compat, " ...->}\n");
118040 +}
118041 +
118042 +void compat_copy_fm_buffer_prefix_content_params(
118043 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
118044 + ioc_fm_buffer_prefix_content_params_t *param,
118045 + uint8_t compat)
118046 +{
118047 + _fm_cpt_dbg (compat, " {->...\n");
118048 +
118049 + if (compat == COMPAT_US_TO_K)
118050 + {
118051 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
118052 + memcpy(&param->fm_buffer_prefix_content,
118053 + &compat_param->fm_buffer_prefix_content,
118054 + sizeof(ioc_fm_buffer_prefix_content_t));
118055 + }
118056 +
118057 + _fm_cpt_dbg (compat, " ...->}\n");
118058 +}
118059 +
118060 +void compat_copy_fm_vsp_config_no_sg_params(
118061 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
118062 + ioc_fm_vsp_config_no_sg_params_t *param,
118063 + uint8_t compat)
118064 +{
118065 + _fm_cpt_dbg (compat, " {->...\n");
118066 +
118067 + if (compat == COMPAT_US_TO_K)
118068 + {
118069 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
118070 + param->no_sg = compat_param->no_sg;
118071 + }
118072 +
118073 + _fm_cpt_dbg (compat, " ...->}\n");
118074 +}
118075 +
118076 +void compat_copy_fm_vsp_prs_result_params(
118077 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
118078 + ioc_fm_vsp_prs_result_params_t *param,
118079 + uint8_t compat)
118080 +{
118081 + _fm_cpt_dbg (compat, " {->...\n");
118082 +
118083 + if (compat == COMPAT_US_TO_K)
118084 + {
118085 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
118086 + /* p_data is an user-space pointer that needs to remain unmodified */
118087 + param->p_data = (void *)(unsigned long long)compat_param->p_data;
118088 + }
118089 + else
118090 + {
118091 + compat_param->p_fm_vsp = compat_pcd_ptr2id(param->p_fm_vsp);
118092 + /* p_data is an user-space pointer that needs to remain unmodified */
118093 + compat_param->p_data = (compat_uptr_t)((unsigned long long)param->p_data & 0xFFFFFFFF);
118094 + }
118095 +
118096 + _fm_cpt_dbg (compat, " ...->}\n");
118097 +}
118098 +#endif /* (DPAA_VERSION >= 11) */
118099 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
118100 new file mode 100644
118101 index 00000000..187011f7
118102 --- /dev/null
118103 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
118104 @@ -0,0 +1,755 @@
118105 +/*
118106 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118107 + *
118108 + * Redistribution and use in source and binary forms, with or without
118109 + * modification, are permitted provided that the following conditions are met:
118110 + * * Redistributions of source code must retain the above copyright
118111 + * notice, this list of conditions and the following disclaimer.
118112 + * * Redistributions in binary form must reproduce the above copyright
118113 + * notice, this list of conditions and the following disclaimer in the
118114 + * documentation and/or other materials provided with the distribution.
118115 + * * Neither the name of Freescale Semiconductor nor the
118116 + * names of its contributors may be used to endorse or promote products
118117 + * derived from this software without specific prior written permission.
118118 + *
118119 + *
118120 + * ALTERNATIVELY, this software may be distributed under the terms of the
118121 + * GNU General Public License ("GPL") as published by the Free Software
118122 + * Foundation, either version 2 of that License or (at your option) any
118123 + * later version.
118124 + *
118125 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118126 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118127 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118128 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118129 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118130 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118131 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118132 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118133 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118134 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118135 + */
118136 +
118137 +/*
118138 + @File lnxwrp_ioctls_fm_compat.h
118139 +
118140 + @Description FM PCD compat structures definition.
118141 +
118142 +*/
118143 +
118144 +#ifndef __FM_COMPAT_IOCTLS_H
118145 +#define __FM_COMPAT_IOCTLS_H
118146 +
118147 +#include <linux/compat.h>
118148 +
118149 +#define COMPAT_K_TO_US 0 /* copy from Kernel to User */
118150 +#define COMPAT_US_TO_K 1 /* copy from User to Kernel */
118151 +#define COMPAT_GENERIC 2
118152 +
118153 +#define COMPAT_COPY_K2US(dest, src, type) compat_copy_##type(src, dest, 0)
118154 +#define COMPAT_COPY_US2K(dest, src, type) compat_copy_##type(dest, src, 1)
118155 +
118156 +/* mapping kernel pointers w/ UserSpace id's { */
118157 +/* Because compat_ptr(ptr_to_compat(X)) != X, this way we cannot exchange pointers
118158 + back and forth (US - KS). compat_ptr is a cast and pointers are broken. */
118159 +#define COMPAT_PTR2ID_ARRAY_MAX (512+1) /* first location is not used */
118160 +#define COMPAT_PTR2ID_WATERMARK 0xface0000
118161 +#define COMPAT_PTR2ID_WM_MASK 0xffff0000
118162 +
118163 +/* define it for debug trace */
118164 +/*#define FM_COMPAT_DBG*/
118165 +
118166 +#define _fm_cpt_prk(stage, format, arg...) \
118167 + printk(stage "fm_cpt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
118168 +
118169 +#define _fm_cpt_inf(format, arg...) _fm_cpt_prk(KERN_INFO, format, ##arg)
118170 +#define _fm_cpt_wrn(format, arg...) _fm_cpt_prk(KERN_WARNING, format, ##arg)
118171 +#define _fm_cpt_err(format, arg...) _fm_cpt_prk(KERN_ERR, format, ##arg)
118172 +
118173 +/* used for compat IOCTL debugging */
118174 +#if defined(FM_COMPAT_DBG)
118175 + #define _fm_cpt_dbg(from, format, arg...) \
118176 + do{ \
118177 + if (from == COMPAT_US_TO_K) \
118178 + printk("fm_cpt to KS [%s:%u](cpu:%u) - " format, \
118179 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
118180 + else if (from == COMPAT_K_TO_US) \
118181 + printk("fm_cpt to US [%s:%u](cpu:%u) - " format, \
118182 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
118183 + else \
118184 + printk("fm_cpt [%s:%u](cpu:%u) - " format, \
118185 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
118186 + }while(0)
118187 +#else
118188 +# define _fm_cpt_dbg(arg...)
118189 +#endif
118190 +
118191 +/*TODO: per FMan module:
118192 + *
118193 + * Parser: FM_MAP_TYPE_PARSER_NODE,
118194 + * Kg: FM_MAP_TYPE_KG_NODE,
118195 + * Policer: FM_MAP_TYPE_POLICER_NODE
118196 + * Manip: FM_MAP_TYPE_MANIP_NODE
118197 + **/
118198 +enum fm_map_node_type {
118199 + FM_MAP_TYPE_UNSPEC = 0,
118200 + FM_MAP_TYPE_PCD_NODE,
118201 +
118202 + /* add types here, update the policy */
118203 +
118204 + __FM_MAP_TYPE_AFTER_LAST,
118205 + FM_MAP_TYPE_MAX = __FM_MAP_TYPE_AFTER_LAST - 1
118206 +};
118207 +
118208 +void compat_del_ptr2id(void *p, enum fm_map_node_type);
118209 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type);
118210 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type);
118211 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type);
118212 +
118213 +static inline compat_uptr_t compat_pcd_ptr2id(void *ptr) {
118214 + return (ptr)? compat_get_ptr2id(ptr, FM_MAP_TYPE_PCD_NODE)
118215 + : (compat_uptr_t) 0;
118216 +}
118217 +
118218 +static inline void *compat_pcd_id2ptr(compat_uptr_t id) {
118219 + return (id) ? compat_get_id2ptr(id, FM_MAP_TYPE_PCD_NODE)
118220 + : NULL;
118221 +}
118222 +
118223 +/* other similar inlines may be added as new nodes are added
118224 + to enum fm_map_node_type above... */
118225 +/* } mapping kernel pointers w/ UserSpace id's */
118226 +
118227 +/* pcd compat structures { */
118228 +typedef struct ioc_compat_fm_pcd_cc_node_remove_key_params_t {
118229 + compat_uptr_t id;
118230 + uint16_t key_indx;
118231 +} ioc_compat_fm_pcd_cc_node_remove_key_params_t;
118232 +
118233 +typedef union ioc_compat_fm_pcd_plcr_next_engine_params_u {
118234 + ioc_fm_pcd_done_action action;
118235 + compat_uptr_t p_profile;
118236 + compat_uptr_t p_direct_scheme;
118237 +} ioc_compat_fm_pcd_plcr_next_engine_params_u;
118238 +
118239 +typedef struct ioc_compat_fm_pcd_plcr_profile_params_t {
118240 + bool modify;
118241 + union {
118242 + struct {
118243 + ioc_fm_pcd_profile_type_selection profile_type;
118244 + compat_uptr_t p_fm_port;
118245 + uint16_t relative_profile_id;
118246 + } new_params;
118247 + compat_uptr_t p_profile;
118248 + } profile_select;
118249 + ioc_fm_pcd_plcr_algorithm_selection alg_selection;
118250 + ioc_fm_pcd_plcr_color_mode color_mode;
118251 +
118252 + union {
118253 + ioc_fm_pcd_plcr_color dflt_color;
118254 + ioc_fm_pcd_plcr_color override;
118255 + } color;
118256 +
118257 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param;
118258 +
118259 + ioc_fm_pcd_engine next_engine_on_green;
118260 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_green;
118261 +
118262 + ioc_fm_pcd_engine next_engine_on_yellow;
118263 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_yellow;
118264 +
118265 + ioc_fm_pcd_engine next_engine_on_red;
118266 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_red;
118267 +
118268 + bool trap_profile_on_flow_A;
118269 + bool trap_profile_on_flow_B;
118270 + bool trap_profile_on_flow_C;
118271 + compat_uptr_t id;
118272 +} ioc_compat_fm_pcd_plcr_profile_params_t;
118273 +
118274 +typedef struct ioc_compat_fm_obj_t {
118275 + compat_uptr_t obj;
118276 +} ioc_compat_fm_obj_t;
118277 +
118278 +typedef struct ioc_compat_fm_pcd_kg_scheme_select_t {
118279 + bool direct;
118280 + compat_uptr_t scheme_id;
118281 +} ioc_compat_fm_pcd_kg_scheme_select_t;
118282 +
118283 +typedef struct ioc_compat_fm_pcd_port_schemes_params_t {
118284 + uint8_t num_of_schemes;
118285 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
118286 +} ioc_compat_fm_pcd_port_schemes_params_t;
118287 +
118288 +#if (DPAA_VERSION >= 11)
118289 +typedef struct ioc_compat_fm_port_vsp_alloc_params_t {
118290 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
118291 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
118292 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
118293 + if relevant function called for Rx port */
118294 + compat_uptr_t p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
118295 +}ioc_compat_fm_port_vsp_alloc_params_t;
118296 +#endif /* (DPAA_VERSION >= 11) */
118297 +
118298 +typedef struct ioc_compat_fm_pcd_net_env_params_t {
118299 + uint8_t num_of_distinction_units;
118300 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* same structure*/
118301 + compat_uptr_t id;
118302 +} ioc_compat_fm_pcd_net_env_params_t;
118303 +
118304 +typedef struct ioc_compat_fm_pcd_prs_sw_params_t {
118305 + bool override;
118306 + uint32_t size;
118307 + uint16_t base;
118308 + compat_uptr_t p_code;
118309 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
118310 + uint8_t num_of_labels;
118311 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
118312 +} ioc_compat_fm_pcd_prs_sw_params_t;
118313 +
118314 +typedef struct ioc_compat_fm_pcd_cc_next_kg_params_t {
118315 + bool override_fqid;
118316 + uint32_t new_fqid;
118317 +#if DPAA_VERSION >= 11
118318 + uint8_t new_relative_storage_profile_id;
118319 +#endif
118320 + compat_uptr_t p_direct_scheme;
118321 +} ioc_compat_fm_pcd_cc_next_kg_params_t;
118322 +
118323 +typedef struct ioc_compat_fm_pcd_cc_next_cc_params_t {
118324 + compat_uptr_t cc_node_id;
118325 +} ioc_compat_fm_pcd_cc_next_cc_params_t;
118326 +
118327 +#if DPAA_VERSION >= 11
118328 +typedef struct ioc_compat_fm_pcd_cc_next_fr_params_t {
118329 + compat_uptr_t frm_replic_id;
118330 +} ioc_compat_fm_pcd_cc_next_fr_params_t;
118331 +#endif /* DPAA_VERSION >= 11 */
118332 +
118333 +typedef struct ioc_compat_fm_pcd_cc_next_engine_params_t {
118334 + ioc_fm_pcd_engine next_engine;
118335 + union {
118336 + ioc_compat_fm_pcd_cc_next_cc_params_t cc_params; /**< compat structure*/
118337 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< same structure*/
118338 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< same structure*/
118339 + ioc_compat_fm_pcd_cc_next_kg_params_t kg_params; /**< compat structure*/
118340 +#if DPAA_VERSION >= 11
118341 + ioc_compat_fm_pcd_cc_next_fr_params_t fr_params; /**< compat structure*/
118342 +#endif /* DPAA_VERSION >= 11 */
118343 + } params;
118344 + compat_uptr_t manip_id;
118345 + bool statistics_en;
118346 +} ioc_compat_fm_pcd_cc_next_engine_params_t;
118347 +
118348 +typedef struct ioc_compat_fm_pcd_cc_grp_params_t {
118349 + uint8_t num_of_distinction_units;
118350 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
118351 + 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];
118352 +} ioc_compat_fm_pcd_cc_grp_params_t;
118353 +
118354 +typedef struct ioc_compat_fm_pcd_cc_tree_params_t {
118355 + compat_uptr_t net_env_id;
118356 + uint8_t num_of_groups;
118357 + ioc_compat_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
118358 + compat_uptr_t id;
118359 +} ioc_compat_fm_pcd_cc_tree_params_t;
118360 +
118361 +typedef struct ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t {
118362 + compat_uptr_t id;
118363 + uint8_t grp_indx;
118364 + uint8_t indx;
118365 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
118366 +} ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t;
118367 +
118368 +typedef struct ioc_compat_fm_pcd_cc_key_params_t {
118369 + compat_uptr_t p_key;
118370 + compat_uptr_t p_mask;
118371 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; /**< compat structure*/
118372 +} ioc_compat_fm_pcd_cc_key_params_t;
118373 +
118374 +typedef struct ioc_compat_keys_params_t {
118375 + uint16_t max_num_of_keys;
118376 + bool mask_support;
118377 + ioc_fm_pcd_cc_stats_mode statistics_mode;
118378 +#if (DPAA_VERSION >= 11)
118379 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
118380 +#endif /* (DPAA_VERSION >= 11) */
118381 + uint16_t num_of_keys;
118382 + uint8_t key_size;
118383 + ioc_compat_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; /**< compat structure*/
118384 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; /**< compat structure*/
118385 +} ioc_compat_keys_params_t;
118386 +
118387 +typedef struct ioc_compat_fm_pcd_cc_node_params_t {
118388 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< same structure*/
118389 + ioc_compat_keys_params_t keys_params; /**< compat structure*/
118390 + compat_uptr_t id;
118391 +} ioc_compat_fm_pcd_cc_node_params_t;
118392 +
118393 +/**************************************************************************//**
118394 + @Description Parameters for defining a hash table
118395 +*//***************************************************************************/
118396 +typedef struct ioc_compat_fm_pcd_hash_table_params_t {
118397 + uint16_t max_num_of_keys;
118398 + ioc_fm_pcd_cc_stats_mode statistics_mode;
118399 + uint8_t kg_hash_shift;
118400 + uint16_t hash_res_mask;
118401 + uint8_t hash_shift;
118402 + uint8_t match_key_size;
118403 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
118404 + compat_uptr_t id;
118405 +} ioc_compat_fm_pcd_hash_table_params_t;
118406 +
118407 +typedef struct ioc_compat_fm_pcd_hash_table_add_key_params_t {
118408 + compat_uptr_t p_hash_tbl;
118409 + uint8_t key_size;
118410 + ioc_compat_fm_pcd_cc_key_params_t key_params;
118411 +} ioc_compat_fm_pcd_hash_table_add_key_params_t;
118412 +
118413 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_params_t {
118414 + compat_uptr_t id;
118415 + uint16_t key_indx;
118416 + uint8_t key_size;
118417 + compat_uptr_t p_key;
118418 + compat_uptr_t p_mask;
118419 +} ioc_compat_fm_pcd_cc_node_modify_key_params_t;
118420 +
118421 +typedef struct ioc_compat_fm_pcd_hash_table_remove_key_params_t {
118422 + compat_uptr_t p_hash_tbl;
118423 + uint8_t key_size;
118424 + compat_uptr_t p_key;
118425 +} ioc_compat_fm_pcd_hash_table_remove_key_params_t;
118426 +
118427 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
118428 + compat_uptr_t id;
118429 + uint16_t key_indx;
118430 + uint8_t key_size;
118431 + ioc_compat_fm_pcd_cc_key_params_t key_params;
118432 +} ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
118433 +
118434 +typedef struct ioc_compat_fm_port_pcd_plcr_params_t {
118435 + compat_uptr_t plcr_profile_id;
118436 +} ioc_compat_fm_port_pcd_plcr_params_t;
118437 +
118438 +typedef struct ioc_compat_fm_port_pcd_cc_params_t {
118439 + compat_uptr_t cc_tree_id;
118440 +} ioc_compat_fm_port_pcd_cc_params_t;
118441 +
118442 +typedef struct ioc_compat_fm_port_pcd_kg_params_t {
118443 + uint8_t num_of_schemes;
118444 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
118445 + bool direct_scheme;
118446 + compat_uptr_t direct_scheme_id;
118447 +} ioc_compat_fm_port_pcd_kg_params_t;
118448 +
118449 +typedef struct ioc_compat_fm_port_pcd_params_t {
118450 + ioc_fm_port_pcd_support pcd_support;
118451 + compat_uptr_t net_env_id;
118452 + compat_uptr_t p_prs_params;
118453 + compat_uptr_t p_cc_params;
118454 + compat_uptr_t p_kg_params;
118455 + compat_uptr_t p_plcr_params;
118456 + compat_uptr_t p_ip_reassembly_manip;
118457 +#if DPAA_VERSION >= 11
118458 + compat_uptr_t p_capwap_reassembly_manip;
118459 +#endif
118460 +} ioc_compat_fm_port_pcd_params_t;
118461 +
118462 +typedef struct ioc_compat_fm_pcd_kg_cc_t {
118463 + compat_uptr_t tree_id;
118464 + uint8_t grp_id;
118465 + bool plcr_next;
118466 + bool bypass_plcr_profile_generation;
118467 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
118468 +} ioc_compat_fm_pcd_kg_cc_t;
118469 +
118470 +typedef struct ioc_compat_fm_pcd_kg_scheme_params_t {
118471 + bool modify;
118472 + union {
118473 + uint8_t relative_scheme_id;
118474 + compat_uptr_t scheme_id;
118475 + } scm_id;
118476 + bool always_direct;
118477 + struct {
118478 + compat_uptr_t net_env_id;
118479 + uint8_t num_of_distinction_units;
118480 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
118481 + } net_env_params;
118482 + bool use_hash;
118483 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
118484 + bool bypass_fqid_generation;
118485 + uint32_t base_fqid;
118486 + uint8_t num_of_used_extracted_ors;
118487 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
118488 +#if DPAA_VERSION >= 11
118489 + bool override_storage_profile;
118490 + ioc_fm_pcd_kg_storage_profile_t storage_profile;
118491 +#endif /* DPAA_VERSION >= 11 */
118492 + ioc_fm_pcd_engine next_engine;
118493 + union{
118494 + ioc_fm_pcd_done_action done_action;
118495 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
118496 + ioc_compat_fm_pcd_kg_cc_t cc;
118497 + } kg_next_engine_params;
118498 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter;
118499 + compat_uptr_t id;
118500 +} ioc_compat_fm_pcd_kg_scheme_params_t;
118501 +
118502 +typedef struct ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t {
118503 + compat_uptr_t id;
118504 + uint16_t key_indx;
118505 + uint8_t key_size;
118506 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
118507 +} ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t;
118508 +
118509 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t {
118510 + uint8_t offset;
118511 + uint8_t size;
118512 + bool replace;
118513 + compat_uptr_t p_data;
118514 +} ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t;
118515 +
118516 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
118517 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2;
118518 + bool update;
118519 + uint8_t size;
118520 + compat_uptr_t p_data;
118521 +} ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
118522 +
118523 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_t {
118524 + uint8_t size; /**< size of inserted section */
118525 + compat_uptr_t p_data; /**< data to be inserted */
118526 +} ioc_compat_fm_pcd_manip_hdr_insrt_t;
118527 +
118528 +#if (DPAA_VERSION >= 11)
118529 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t {
118530 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
118531 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
118532 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
118533 + the inserted header */
118534 + uint16_t id; /**< 16 bit New IP ID */
118535 + bool dont_frag_overwrite;
118536 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
118537 + * This byte is configured to be overwritten when RPD is set. */
118538 + uint8_t last_dst_offset;
118539 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
118540 + * in order to calculate UDP checksum pseudo header;
118541 + * Otherwise set it to '0'. */
118542 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
118543 +} ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t;
118544 +#endif /* (DPAA_VERSION >= 11) */
118545 +
118546 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
118547 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type;
118548 + union {
118549 + ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
118550 +#if (DPAA_VERSION >= 11)
118551 + ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t ip_params;
118552 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt;
118553 +#endif /* (DPAA_VERSION >= 11) */
118554 + } u;
118555 +} ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
118556 +
118557 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_params_t {
118558 + ioc_fm_pcd_manip_hdr_insrt_type type;
118559 + union {
118560 + ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr;
118561 + ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t generic;
118562 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
118563 +#error "FM_CAPWAP_SUPPORT feature not supported!"
118564 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
118565 +#endif /* FM_CAPWAP_SUPPORT */
118566 + } u;
118567 +} ioc_compat_fm_pcd_manip_hdr_insrt_params_t;
118568 +
118569 +typedef struct ioc_compat_fm_pcd_manip_hdr_params_t {
118570 + bool rmv;
118571 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params;
118572 + bool insrt;
118573 + ioc_compat_fm_pcd_manip_hdr_insrt_params_t insrt_params;
118574 + bool field_update;
118575 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params;
118576 + bool custom;
118577 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params;
118578 + bool dont_parse_after_manip;
118579 +} ioc_compat_fm_pcd_manip_hdr_params_t;
118580 +
118581 +typedef struct ioc_compat_fm_pcd_manip_special_offload_params_t {
118582 + bool decryption;
118583 + bool ecn_copy;
118584 + bool dscp_copy;
118585 + bool variable_ip_hdr_len;
118586 + bool variable_ip_version;
118587 + uint8_t outer_ip_hdr_len;
118588 + uint16_t arw_size;
118589 + compat_uptr_t arw_addr;
118590 +} ioc_compat_fm_pcd_manip_special_offload_params_t;
118591 +
118592 +typedef struct ioc_compat_fm_pcd_manip_params_t {
118593 + ioc_fm_pcd_manip_type type;
118594 + union {
118595 + ioc_compat_fm_pcd_manip_hdr_params_t hdr;
118596 + ioc_fm_pcd_manip_reassem_params_t reassem;
118597 + ioc_fm_pcd_manip_frag_params_t frag;
118598 + ioc_compat_fm_pcd_manip_special_offload_params_t special_offload;
118599 + } u;
118600 + compat_uptr_t p_next_manip;
118601 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
118602 +#error "FM_CAPWAP_SUPPORT feature not supported!"
118603 + bool frag_or_reasm;
118604 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;
118605 +#endif /* FM_CAPWAP_SUPPORT */
118606 + compat_uptr_t id;
118607 +} ioc_compat_fm_pcd_manip_params_t;
118608 +
118609 +typedef struct ioc_compat_fm_pcd_manip_get_stats_t {
118610 + compat_uptr_t id;
118611 + ioc_fm_pcd_manip_stats_t stats;
118612 +} ioc_compat_fm_pcd_manip_get_stats_t;
118613 +
118614 +#if (DPAA_VERSION >= 11)
118615 +typedef struct ioc_compat_fm_pcd_frm_replic_group_params_t {
118616 + uint8_t max_num_of_entries;
118617 + uint8_t num_of_entries;
118618 + ioc_compat_fm_pcd_cc_next_engine_params_t
118619 + next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
118620 + compat_uptr_t id;
118621 +} ioc_compat_fm_pcd_frm_replic_group_params_t;
118622 +
118623 +typedef struct ioc_compat_fm_pcd_frm_replic_member_t {
118624 + compat_uptr_t h_replic_group;
118625 + uint16_t member_index;
118626 +} ioc_compat_fm_pcd_frm_replic_member_t;
118627 +
118628 +typedef struct ioc_compat_fm_pcd_frm_replic_member_params_t {
118629 + ioc_compat_fm_pcd_frm_replic_member_t member;
118630 + ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_params;
118631 +} ioc_compat_fm_pcd_frm_replic_member_params_t;
118632 +
118633 +typedef struct ioc_compat_fm_vsp_params_t {
118634 + compat_uptr_t p_fm; /**< A handle to the FM object this VSP related to */
118635 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
118636 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
118637 + parameter associated with Rx / OP port */
118638 + uint16_t liodn_offset; /**< VSP's LIODN offset */
118639 + struct {
118640 + ioc_fm_port_type port_type; /**< Port type */
118641 + uint8_t port_id; /**< Port Id - relative to type */
118642 + } port_params;
118643 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
118644 + defined in relevant FM object */
118645 + compat_uptr_t id; /**< return value */
118646 +} ioc_compat_fm_vsp_params_t;
118647 +
118648 +typedef struct ioc_compat_fm_buf_pool_depletion_params_t {
118649 + compat_uptr_t p_fm_vsp;
118650 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
118651 +} ioc_compat_fm_buf_pool_depletion_params_t;
118652 +
118653 +typedef struct ioc_compat_fm_buffer_prefix_content_params_t {
118654 + compat_uptr_t p_fm_vsp;
118655 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
118656 +} ioc_compat_fm_buffer_prefix_content_params_t;
118657 +
118658 +typedef struct ioc_compat_fm_vsp_config_no_sg_params_t {
118659 + compat_uptr_t p_fm_vsp;
118660 + bool no_sg;
118661 +} ioc_compat_fm_vsp_config_no_sg_params_t;
118662 +
118663 +typedef struct ioc_compat_fm_vsp_prs_result_params_t {
118664 + compat_uptr_t p_fm_vsp;
118665 + compat_uptr_t p_data;
118666 +} ioc_compat_fm_vsp_prs_result_params_t;
118667 +
118668 +#endif /* (DPAA_VERSION >= 11) */
118669 +typedef struct ioc_compat_fm_pcd_kg_scheme_spc_t {
118670 + uint32_t val;
118671 + compat_uptr_t id;
118672 +} ioc_compat_fm_pcd_kg_scheme_spc_t;
118673 +
118674 +typedef struct ioc_compat_fm_ctrl_mon_counters_params_t {
118675 + uint8_t fm_ctrl_index;
118676 + compat_uptr_t p_mon;
118677 +} ioc_compat_fm_ctrl_mon_counters_params_t;
118678 +
118679 +typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t {
118680 + compat_uptr_t id;
118681 + uint16_t key_index;
118682 + ioc_fm_pcd_cc_key_statistics_t statistics;
118683 +} ioc_compat_fm_pcd_cc_tbl_get_stats_t;
118684 +
118685 +
118686 +/* } pcd compat structures */
118687 +
118688 +void compat_obj_delete(
118689 + ioc_compat_fm_obj_t *compat_id,
118690 + ioc_fm_obj_t *id);
118691 +
118692 +/* pcd compat functions { */
118693 +void compat_copy_fm_pcd_plcr_profile(
118694 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
118695 + ioc_fm_pcd_plcr_profile_params_t *param,
118696 + uint8_t compat);
118697 +
118698 +void compat_copy_fm_pcd_cc_key(
118699 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
118700 + ioc_fm_pcd_cc_key_params_t *param,
118701 + uint8_t compat);
118702 +
118703 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
118704 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
118705 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
118706 + uint8_t compat);
118707 +
118708 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
118709 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
118710 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
118711 + uint8_t compat);
118712 +
118713 +void compat_fm_pcd_cc_tree_modify_next_engine(
118714 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
118715 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
118716 + uint8_t compat);
118717 +
118718 +void compat_copy_fm_pcd_hash_table(
118719 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
118720 + ioc_fm_pcd_hash_table_params_t *param,
118721 + uint8_t compat);
118722 +
118723 +void compat_copy_fm_pcd_cc_grp(
118724 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
118725 + ioc_fm_pcd_cc_grp_params_t *param,
118726 + uint8_t compat);
118727 +
118728 +void compat_copy_fm_pcd_cc_tree(
118729 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
118730 + ioc_fm_pcd_cc_tree_params_t *param,
118731 + uint8_t compat);
118732 +
118733 +void compat_copy_fm_pcd_cc_tbl_get_stats(
118734 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
118735 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
118736 + uint8_t compat);
118737 +
118738 +void compat_fm_pcd_prs_sw(
118739 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
118740 + ioc_fm_pcd_prs_sw_params_t *param,
118741 + uint8_t compat);
118742 +
118743 +void compat_copy_fm_pcd_kg_scheme(
118744 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
118745 + ioc_fm_pcd_kg_scheme_params_t *param,
118746 + uint8_t compat);
118747 +
118748 +void compat_copy_fm_pcd_kg_scheme_select(
118749 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
118750 + ioc_fm_pcd_kg_scheme_select_t *param,
118751 + uint8_t compat);
118752 +
118753 +void compat_copy_fm_pcd_kg_schemes_params(
118754 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
118755 + ioc_fm_pcd_port_schemes_params_t *param,
118756 + uint8_t compat);
118757 +
118758 +void compat_copy_fm_port_pcd_kg(
118759 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
118760 + ioc_fm_port_pcd_kg_params_t *param,
118761 + uint8_t compat);
118762 +
118763 +void compat_copy_fm_port_pcd(
118764 + ioc_compat_fm_port_pcd_params_t *compat_param,
118765 + ioc_fm_port_pcd_params_t *param,
118766 + uint8_t compat);
118767 +
118768 +#if (DPAA_VERSION >= 11)
118769 +void compat_copy_fm_port_vsp_alloc_params(
118770 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
118771 + ioc_fm_port_vsp_alloc_params_t *param,
118772 + uint8_t compat);
118773 +#endif /* (DPAA_VERSION >= 11) */
118774 +
118775 +void compat_copy_fm_pcd_net_env(
118776 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
118777 + ioc_fm_pcd_net_env_params_t *param,
118778 + uint8_t compat);
118779 +
118780 +void compat_copy_fm_pcd_cc_node_modify_key(
118781 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
118782 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
118783 + uint8_t compat);
118784 +
118785 +void compat_copy_keys(
118786 + ioc_compat_keys_params_t *compat_param,
118787 + ioc_keys_params_t *param,
118788 + uint8_t compat);
118789 +
118790 +void compat_copy_fm_pcd_cc_node(
118791 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
118792 + ioc_fm_pcd_cc_node_params_t *param,
118793 + uint8_t compat);
118794 +
118795 +void compat_fm_pcd_manip_set_node(
118796 + ioc_compat_fm_pcd_manip_params_t *compat_param,
118797 + ioc_fm_pcd_manip_params_t *param,
118798 + uint8_t compat);
118799 +
118800 +void compat_copy_fm_pcd_manip_get_stats(
118801 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
118802 + ioc_fm_pcd_manip_get_stats_t *param,
118803 + uint8_t compat);
118804 +
118805 +void compat_copy_fm_port_pcd_modify_tree(
118806 + ioc_compat_fm_obj_t *compat_id,
118807 + ioc_fm_obj_t *id,
118808 + uint8_t compat);
118809 +
118810 +#if (DPAA_VERSION >= 11)
118811 +void compat_copy_fm_pcd_frm_replic_group_params(
118812 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
118813 + ioc_fm_pcd_frm_replic_group_params_t *param,
118814 + uint8_t compat);
118815 +
118816 +void compat_copy_fm_pcd_frm_replic_member(
118817 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
118818 + ioc_fm_pcd_frm_replic_member_t *param,
118819 + uint8_t compat);
118820 +
118821 +void compat_copy_fm_pcd_frm_replic_member_params(
118822 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
118823 + ioc_fm_pcd_frm_replic_member_params_t *param,
118824 + uint8_t compat);
118825 +
118826 +void compat_copy_fm_vsp_params(
118827 + ioc_compat_fm_vsp_params_t *compat_param,
118828 + ioc_fm_vsp_params_t *param,
118829 + uint8_t compat);
118830 +
118831 +void compat_copy_fm_buf_pool_depletion_params(
118832 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
118833 + ioc_fm_buf_pool_depletion_params_t *param,
118834 + uint8_t compat);
118835 +
118836 +void compat_copy_fm_buffer_prefix_content_params(
118837 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
118838 + ioc_fm_buffer_prefix_content_params_t *param,
118839 + uint8_t compat);
118840 +
118841 +void compat_copy_fm_vsp_config_no_sg_params(
118842 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
118843 + ioc_fm_vsp_config_no_sg_params_t *param,
118844 + uint8_t compat);
118845 +
118846 +void compat_copy_fm_vsp_prs_result_params(
118847 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
118848 + ioc_fm_vsp_prs_result_params_t *param,
118849 + uint8_t compat);
118850 +
118851 +#endif /* (DPAA_VERSION >= 11) */
118852 +
118853 +void compat_copy_fm_pcd_kg_scheme_spc(
118854 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
118855 + ioc_fm_pcd_kg_scheme_spc_t *param,
118856 + uint8_t compat);
118857 +
118858 +/* } pcd compat functions */
118859 +#endif
118860 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
118861 new file mode 100644
118862 index 00000000..1b72e1d5
118863 --- /dev/null
118864 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
118865 @@ -0,0 +1,121 @@
118866 +/*
118867 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118868 + *
118869 + * Redistribution and use in source and binary forms, with or without
118870 + * modification, are permitted provided that the following conditions are met:
118871 + * * Redistributions of source code must retain the above copyright
118872 + * notice, this list of conditions and the following disclaimer.
118873 + * * Redistributions in binary form must reproduce the above copyright
118874 + * notice, this list of conditions and the following disclaimer in the
118875 + * documentation and/or other materials provided with the distribution.
118876 + * * Neither the name of Freescale Semiconductor nor the
118877 + * names of its contributors may be used to endorse or promote products
118878 + * derived from this software without specific prior written permission.
118879 + *
118880 + *
118881 + * ALTERNATIVELY, this software may be distributed under the terms of the
118882 + * GNU General Public License ("GPL") as published by the Free Software
118883 + * Foundation, either version 2 of that License or (at your option) any
118884 + * later version.
118885 + *
118886 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118887 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118888 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118889 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118890 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118891 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118892 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118893 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118894 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118895 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118896 + */
118897 +
118898 +/*
118899 + @File lnxwrp_resources.h
118900 +
118901 + @Description FMD wrapper resource allocation functions.
118902 +
118903 +*/
118904 +
118905 +#ifndef LNXWRP_RESOURCES_H_
118906 +#define LNXWRP_RESOURCES_H_
118907 +
118908 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118909 +#include "lnxwrp_fm.h"
118910 +#else
118911 +#include "lnxwrp_resources_ut.h"
118912 +#endif
118913 +
118914 +#define ROUND(X) ((2*(X)+1)/2)
118915 +#define CEIL(X) ((X)+1)
118916 +/* #define ROUND_DIV(X, Y) (((X)+(Y)/2)/(Y)) */
118917 +#define ROUND_DIV(X, Y) ((2*(X)+(Y))/(2*(Y)))
118918 +#define CEIL_DIV(X, Y) (((X)+(Y)-1)/(Y))
118919 +
118920 +/* used for resource calculus */
118921 +#define DPDE_1G 2 /* DQDP 1g - from LLD:
118922 + DEFAULT_PORT_txFifoDeqPipelineDepth_1G */
118923 +#define DPDE_10G 8 /* DQDP 10g - from LLD:
118924 + DEFAULT_PORT_txFifoDeqPipelineDepth_10G */
118925 +
118926 +int fm_set_active_fman_ports(struct platform_device *of_dev,
118927 + t_LnxWrpFmDev *p_LnxWrpFmDev);
118928 +
118929 +/* Calculate the fifosize based on MURAM allocation, number of ports, dpde
118930 + * value and s/g software support (! Kernel does not suport s/g).
118931 + *
118932 + * Algorithm summary:
118933 + * - Calculate the the minimum fifosize required for every type of port
118934 + * (TX,RX for 1G, 2.5G and 10G).
118935 + * - Set TX the minimum fifosize required.
118936 + * - Distribute the remaining buffers (after all TX were set) to RX ports
118937 + * based on:
118938 + * 1G RX = Remaining_buffers * 1/(1+2.5+10)
118939 + * 2.5G RX = Remaining_buffers * 2.5/(1+2.5+10)
118940 + * 10G RX = Remaining_buffers * 10/(1+2.5+10)
118941 + * - if the RX is smaller than the minimum required, then set the minimum
118942 + * required
118943 + * - In the end distribuite the leftovers if there are any (due to
118944 + * unprecise calculus) or if over allocation cat some buffers from all RX
118945 + * ports w/o pass over minimum required treshold, but if there must be
118946 + * pass the treshold in order to cat the over allocation ,then this
118947 + * configuration can not be set - KERN_ALERT.
118948 +*/
118949 +int fm_precalculate_fifosizes(t_LnxWrpFmDev *p_LnxWrpFmDev,
118950 + int muram_fifo_size);
118951 +
118952 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118953 +int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118954 +#endif
118955 +
118956 +/* Compute FMan open DMA based on total number of open DMAs and
118957 + * number of available fman ports.
118958 + *
118959 + * By default 10g ports are set to input parameters. The other ports
118960 + * tries to keep the proportion rx=2tx open dmas or tresholds.
118961 + *
118962 + * If leftovers, then those will be set as shared.
118963 + *
118964 + * If after computing overflow appears, then it decrements open dma
118965 + * for all ports w/o cross the tresholds. If the tresholds are meet
118966 + * and is still overflow, then it returns error.
118967 +*/
118968 +int fm_precalculate_open_dma(t_LnxWrpFmDev *p_LnxWrpFmDev,
118969 + int max_fm_open_dma,
118970 + int default_tx_10g_dmas,
118971 + int default_rx_10g_dmas,
118972 + int min_tx_10g_treshold, int min_rx_10g_treshold);
118973 +
118974 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118975 +int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118976 +#endif
118977 +
118978 +/* Compute FMan tnums based on available tnums and number of ports.
118979 + * Set defaults (minim tresholds) and then distribute leftovers.*/
118980 +int fm_precalculate_tnums(t_LnxWrpFmDev *p_LnxWrpFmDev, int max_fm_tnums);
118981 +
118982 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118983 +int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118984 +#endif
118985 +
118986 +#endif /* LNXWRP_RESOURCES_H_ */
118987 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
118988 new file mode 100644
118989 index 00000000..6c06a5a6
118990 --- /dev/null
118991 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
118992 @@ -0,0 +1,191 @@
118993 +/* Copyright (c) 2012 Freescale Semiconductor, Inc.
118994 + * All rights reserved.
118995 + *
118996 + * Redistribution and use in source and binary forms, with or without
118997 + * modification, are permitted provided that the following conditions are met:
118998 + * * Redistributions of source code must retain the above copyright
118999 + * notice, this list of conditions and the following disclaimer.
119000 + * * Redistributions in binary form must reproduce the above copyright
119001 + * notice, this list of conditions and the following disclaimer in the
119002 + * documentation and/or other materials provided with the distribution.
119003 + * * Neither the name of Freescale Semiconductor nor the
119004 + * names of its contributors may be used to endorse or promote products
119005 + * derived from this software without specific prior written permission.
119006 + *
119007 + *
119008 + * ALTERNATIVELY, this software may be distributed under the terms of the
119009 + * GNU General Public License ("GPL") as published by the Free Software
119010 + * Foundation, either version 2 of that License or (at your option) any
119011 + * later version.
119012 + *
119013 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119014 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119015 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119016 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119017 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119018 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119019 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119020 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119021 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119022 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119023 + */
119024 +
119025 +#include "lnxwrp_resources.h"
119026 +#include "lnxwrp_resources_ut.h"
119027 +
119028 +#define KILOBYTE 0x400 /* 1024 */
119029 +
119030 +typedef enum e_board_type {
119031 + e_p3041,
119032 + e_p4080,
119033 + e_p5020,
119034 + e_p1023
119035 +} e_board_type;
119036 +
119037 +uint8_t board_type;
119038 +uint32_t muram_size = 0;
119039 +uint32_t dmas_num = 0;
119040 +uint32_t task_num = 0;
119041 +uint32_t frame_size = 0;
119042 +uint32_t oh_num = 0;
119043 +uint32_t num_ports_1g = 0;
119044 +uint32_t num_ports_10g = 0;
119045 +uint32_t num_ports_2g5 = 0;
119046 +uint32_t fsl_fman_phy_maxfrm = 0;
119047 +uint32_t dpa_rx_extra_headroom = 0;
119048 +
119049 +void show_help(void){
119050 + printf(" help: \n");
119051 + printf(" -b <board_type> -f <max_fram_size(mtu)> -o <num_oh_ports> -g1"
119052 + " <num_1g_ports> -g10 <num_10g_ports> -g25 <num_2g5_ports>\n");
119053 + printf(" Maxim num of DMAS availbale: P3/P4/P5:32 , P1023:16 \n");
119054 + printf(" Maxim num of TNUMs availbale: P3/P4/P5:128, P1023:32 \n");
119055 + printf(" Muram size: P3/P4/P5:160K, P1023:64K \n");
119056 + printf(" Number of ports:\n");
119057 + printf(" P3/P5: 5p 1g, 1p 10g, 7p oh \n");
119058 + printf(" P4 : 4p 1g, 1p 10g, 7p oh \n");
119059 + printf(" P1 : 2p 1g, 0p 10g, 4p oh \n");
119060 + printf(" MTU: Default:1522, Jumbo:9600 \n");
119061 +}
119062 +
119063 +int fm_set_param(t_LnxWrpFmDev *p_LnxWrpFmDev) {
119064 + struct fm_active_ports *fm_active_ports_info = NULL;
119065 + fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info;
119066 +
119067 + switch(board_type){
119068 + case e_p3041:
119069 + case e_p5020:
119070 + muram_size = 160*KILOBYTE;
119071 + dmas_num = 32;
119072 + task_num = 128;
119073 + if ((num_ports_1g+num_ports_2g5) > 5 || num_ports_10g > 1 || oh_num > 7)
119074 + goto err_fm_set_param;
119075 + break;
119076 + case e_p4080:
119077 + muram_size = 160*KILOBYTE;
119078 + dmas_num = 32;
119079 + task_num = 128;
119080 + if ((num_ports_1g+num_ports_2g5) > 4 || num_ports_10g > 1 || oh_num > 7)
119081 + goto err_fm_set_param;
119082 + break;
119083 + case e_p1023:
119084 + muram_size = 64*KILOBYTE;
119085 + dmas_num = 16;
119086 + task_num = 128;
119087 + if ((num_ports_1g+num_ports_2g5) > 2 || oh_num > 4)
119088 + goto err_fm_set_param;
119089 + break;
119090 + default:
119091 + goto err_fm_set_param;
119092 + break;
119093 + }
119094 +
119095 + p_LnxWrpFmDev->id = 0;
119096 + fsl_fman_phy_maxfrm = frame_size;
119097 + dpa_rx_extra_headroom = 0; /* ATTENTION: can be != 0 */
119098 + fm_active_ports_info->num_oh_ports = oh_num;
119099 + fm_active_ports_info->num_tx_ports = num_ports_1g;
119100 + fm_active_ports_info->num_rx_ports = num_ports_1g;
119101 + fm_active_ports_info->num_tx25_ports = num_ports_2g5;
119102 + fm_active_ports_info->num_rx25_ports = num_ports_2g5;
119103 + fm_active_ports_info->num_tx10_ports = num_ports_10g;
119104 + fm_active_ports_info->num_rx10_ports = num_ports_10g;
119105 +
119106 + return 0;
119107 +
119108 +err_fm_set_param:
119109 + printf(" ERR: To many ports!!! \n");
119110 + return -1;
119111 +}
119112 +
119113 +int main (int argc, char *argv[]){
119114 + t_LnxWrpFmDev LnxWrpFmDev;
119115 + t_LnxWrpFmDev *p_LnxWrpFmDev = &LnxWrpFmDev;
119116 + int tokens_cnt = 1;
119117 +
119118 + char *token = NULL;
119119 +
119120 + while(tokens_cnt < argc)
119121 + {
119122 + token = argv[tokens_cnt++];
119123 + if (strcmp(token, "-b") == 0){
119124 + if(strcmp(argv[tokens_cnt],"p3") == 0)
119125 + board_type = e_p3041;
119126 + else if(strcmp(argv[tokens_cnt],"p4") == 0)
119127 + board_type = e_p4080;
119128 + else if(strcmp(argv[tokens_cnt],"p5") == 0)
119129 + board_type = e_p5020;
119130 + else if(strcmp(argv[tokens_cnt],"p1") == 0)
119131 + board_type = e_p1023;
119132 + else
119133 + show_help();
119134 + tokens_cnt++;
119135 + }
119136 + else if(strcmp(token, "-d") == 0){
119137 + dmas_num = atoi(argv[tokens_cnt++]);
119138 + }
119139 + else if(strcmp(token, "-t") == 0)
119140 + task_num = atoi(argv[tokens_cnt++]);
119141 + else if(strcmp(token, "-f") == 0)
119142 + frame_size = atoi(argv[tokens_cnt++]);
119143 + else if(strcmp(token, "-o") == 0)
119144 + oh_num = atoi(argv[tokens_cnt++]);
119145 + else if(strcmp(token, "-g1") == 0)
119146 + num_ports_1g = atoi(argv[tokens_cnt++]);
119147 + else if(strcmp(token, "-g10") == 0)
119148 + num_ports_10g = atoi(argv[tokens_cnt++]);
119149 + else if(strcmp(token, "-g25") == 0)
119150 + num_ports_2g5 = atoi(argv[tokens_cnt++]);
119151 + else {
119152 + show_help();
119153 + return -1;
119154 + }
119155 + }
119156 +
119157 + if(fm_set_param(p_LnxWrpFmDev) < 0){
119158 + show_help();
119159 + return -1;
119160 + }
119161 +
119162 + if(fm_precalculate_fifosizes(
119163 + p_LnxWrpFmDev,
119164 + 128*KILOBYTE)
119165 + != 0)
119166 + return -1;
119167 + if(fm_precalculate_open_dma(
119168 + p_LnxWrpFmDev,
119169 + dmas_num, /* max open dmas:dpaa_integration_ext.h */
119170 + FM_DEFAULT_TX10G_OPENDMA, /* default TX 10g open dmas */
119171 + FM_DEFAULT_RX10G_OPENDMA, /* default RX 10g open dmas */
119172 + FM_10G_OPENDMA_MIN_TRESHOLD,/* TX 10g minimum treshold */
119173 + FM_10G_OPENDMA_MIN_TRESHOLD)/* RX 10g minimum treshold */
119174 + != 0)
119175 + return -1;
119176 + if(fm_precalculate_tnums(
119177 + p_LnxWrpFmDev,
119178 + task_num) /* max TNUMS: dpa integration file. */
119179 + != 0)
119180 + return -1;
119181 +
119182 + return 0;
119183 +}
119184 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
119185 new file mode 100644
119186 index 00000000..063946eb
119187 --- /dev/null
119188 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
119189 @@ -0,0 +1,144 @@
119190 +/* Copyright (c) 2012 Freescale Semiconductor, Inc
119191 + * All rights reserved.
119192 + *
119193 + * Redistribution and use in source and binary forms, with or without
119194 + * modification, are permitted provided that the following conditions are met:
119195 + * * Redistributions of source code must retain the above copyright
119196 + * notice, this list of conditions and the following disclaimer.
119197 + * * Redistributions in binary form must reproduce the above copyright
119198 + * notice, this list of conditions and the following disclaimer in the
119199 + * documentation and/or other materials provided with the distribution.
119200 + * * Neither the name of Freescale Semiconductor nor the
119201 + * names of its contributors may be used to endorse or promote products
119202 + * derived from this software without specific prior written permission.
119203 + *
119204 + *
119205 + * ALTERNATIVELY, this software may be distributed under the terms of the
119206 + * GNU General Public License ("GPL") as published by the Free Software
119207 + * Foundation, either version 2 of that License or (at your option) any
119208 + * later version.
119209 + *
119210 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119211 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119212 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119213 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119214 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119215 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119216 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119217 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119218 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119219 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119220 + */
119221 +
119222 +#ifndef FM_RESS_TEST_H_
119223 +#define FM_RESS_TEST_H_
119224 +
119225 +#include <stdint.h>
119226 +#include <stdbool.h>
119227 +#include <stdio.h>
119228 +#include <assert.h>
119229 +#include <string.h>
119230 +#include <stdlib.h>
119231 +
119232 +#define _Packed
119233 +#define _PackedType __attribute__ ((packed))
119234 +#define MAX(x, y) (((x) > (y)) ? (x) : (y))
119235 +#define MIN(x, y) (((x) < (y)) ? (x) : (y))
119236 +#define KERN_ALERT ""
119237 +#define KERN_INFO ""
119238 +#define ASSERT_COND assert
119239 +#define printk printf
119240 +#define NET_IP_ALIGN 0
119241 +#define FM_FIFO_ALLOCATION_OLD_ALG
119242 +
119243 +#if defined(CONFIG_FMAN_DISABLE_OH_AND_DISTRIBUTE_RESOURCES)
119244 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
119245 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
119246 +#else
119247 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
119248 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
119249 +#endif
119250 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
119251 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
119252 +
119253 +/* information about all active ports for an FMan.
119254 + * !Some ports may be disabled by u-boot, thus will not be available */
119255 +struct fm_active_ports {
119256 + uint32_t num_oh_ports;
119257 + uint32_t num_tx_ports;
119258 + uint32_t num_rx_ports;
119259 + uint32_t num_tx25_ports;
119260 + uint32_t num_rx25_ports;
119261 + uint32_t num_tx10_ports;
119262 + uint32_t num_rx10_ports;
119263 +};
119264 +
119265 +/* FMan resources precalculated at fm probe based
119266 + * on available FMan port. */
119267 +struct fm_resource_settings {
119268 + /* buffers - fifo sizes */
119269 + uint32_t tx1g_num_buffers;
119270 + uint32_t rx1g_num_buffers;
119271 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
119272 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
119273 + uint32_t tx10g_num_buffers;
119274 + uint32_t rx10g_num_buffers;
119275 + uint32_t oh_num_buffers;
119276 + uint32_t shared_ext_buffers;
119277 +
119278 +
119279 + /* open DMAs */
119280 + uint32_t tx_1g_dmas;
119281 + uint32_t rx_1g_dmas;
119282 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
119283 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
119284 + uint32_t tx_10g_dmas;
119285 + uint32_t rx_10g_dmas;
119286 + uint32_t oh_dmas;
119287 + uint32_t shared_ext_open_dma;
119288 +
119289 + /* Tnums */
119290 + uint32_t tx_1g_tnums;
119291 + uint32_t rx_1g_tnums;
119292 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
119293 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
119294 + uint32_t tx_10g_tnums;
119295 + uint32_t rx_10g_tnums;
119296 + uint32_t oh_tnums;
119297 + uint32_t shared_ext_tnums;
119298 +};
119299 +
119300 +typedef struct {
119301 + uint8_t id;
119302 + struct fm_active_ports fm_active_ports_info;
119303 + struct fm_resource_settings fm_resource_settings_info;
119304 +} t_LnxWrpFmDev;
119305 +
119306 +typedef struct {
119307 + uint8_t id;
119308 +} t_LnxWrpFmPortDev;
119309 +
119310 +typedef _Packed struct t_FmPrsResult {
119311 + volatile uint8_t lpid; /**< Logical port id */
119312 + volatile uint8_t shimr; /**< Shim header result */
119313 + volatile uint16_t l2r; /**< Layer 2 result */
119314 + volatile uint16_t l3r; /**< Layer 3 result */
119315 + volatile uint8_t l4r; /**< Layer 4 result */
119316 + volatile uint8_t cplan; /**< Classification plan id */
119317 + volatile uint16_t nxthdr; /**< Next Header */
119318 + volatile uint16_t cksum; /**< Checksum */
119319 + volatile uint32_t lcv; /**< LCV */
119320 + volatile uint8_t shim_off[3]; /**< Shim offset */
119321 + volatile uint8_t eth_off; /**< ETH offset */
119322 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
119323 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
119324 + volatile uint8_t etype_off; /**< ETYPE offset */
119325 + volatile uint8_t pppoe_off; /**< PPP offset */
119326 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
119327 + volatile uint8_t ip_off[2]; /**< IP offset */
119328 + volatile uint8_t gre_off; /**< GRE offset */
119329 + volatile uint8_t l4_off; /**< Layer 4 offset */
119330 + volatile uint8_t nxthdr_off; /**< Parser end point */
119331 +} _PackedType t_FmPrsResult;
119332 +
119333 +#endif
119334 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
119335 new file mode 100644
119336 index 00000000..58009cd8
119337 --- /dev/null
119338 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
119339 @@ -0,0 +1,28 @@
119340 +CC=gcc
119341 +
119342 +LNXWRP_RESS_UT=lnxwrp_resources_ut
119343 +OBJ=lnxwrp_resources
119344 +
119345 +INC_PATH=
119346 +LIB_PATH=
119347 +
119348 +INC=$(addprefix -I,$(INC_PATH))
119349 +LIB=$(addprefix -L,$(LIB_PATH))
119350 +
119351 +CFLAGS= -gdwarf-2 -g -O0 -Wall
119352 +XFLAGS= -DFMAN_RESOURCES_UNIT_TEST
119353 +
119354 +all: $(LNXWRP_RESS_UT)
119355 +
119356 +$(LNXWRP_RESS_UT):$(addsuffix .o,$(OBJ)) $(LNXWRP_RESS_UT).o
119357 + $(CC) -o $(LNXWRP_RESS_UT) $(LNXWRP_RESS_UT).o $(addsuffix .o,$(OBJ))
119358 +
119359 +%.o: %.c
119360 + @(echo " (CC) $@")
119361 + @($(CC) $(INC) $(CFLAGS) $(XFLAGS) -o $(@) -c $<)
119362 +
119363 +.PHONY: clean
119364 +
119365 +clean:
119366 + rm -f *.o
119367 + rm -f $(LNXWRP_RESS_UT)
119368 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
119369 new file mode 100644
119370 index 00000000..813771bf
119371 --- /dev/null
119372 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
119373 @@ -0,0 +1,60 @@
119374 +/*
119375 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119376 + *
119377 + * Redistribution and use in source and binary forms, with or without
119378 + * modification, are permitted provided that the following conditions are met:
119379 + * * Redistributions of source code must retain the above copyright
119380 + * notice, this list of conditions and the following disclaimer.
119381 + * * Redistributions in binary form must reproduce the above copyright
119382 + * notice, this list of conditions and the following disclaimer in the
119383 + * documentation and/or other materials provided with the distribution.
119384 + * * Neither the name of Freescale Semiconductor nor the
119385 + * names of its contributors may be used to endorse or promote products
119386 + * derived from this software without specific prior written permission.
119387 + *
119388 + *
119389 + * ALTERNATIVELY, this software may be distributed under the terms of the
119390 + * GNU General Public License ("GPL") as published by the Free Software
119391 + * Foundation, either version 2 of that License or (at your option) any
119392 + * later version.
119393 + *
119394 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119395 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119396 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119397 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119398 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119399 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119400 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119401 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119402 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119403 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119404 + */
119405 +
119406 +/*
119407 + @File lnxwrp_sysfs.c
119408 +
119409 + @Description FM wrapper sysfs related functions.
119410 +
119411 +*/
119412 +
119413 +#include <linux/types.h>
119414 +#include "lnxwrp_sysfs.h"
119415 +
119416 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
119417 + const struct sysfs_stats_t *sysfs_stats,
119418 + uint8_t *offset)
119419 +{
119420 + int i = 0;
119421 +
119422 + while (sysfs_stats[i].stat_name != NULL) {
119423 + if (strcmp(sysfs_stats[i].stat_name, attr_name) == 0) {
119424 + if (offset != NULL)
119425 + *offset = i;
119426 + return sysfs_stats[i].stat_counter;
119427 + }
119428 +
119429 + i++;
119430 + }
119431 + WARN(1, "FMD: Should never get here!");
119432 + return 0;
119433 +}
119434 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
119435 new file mode 100644
119436 index 00000000..2098b244
119437 --- /dev/null
119438 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
119439 @@ -0,0 +1,60 @@
119440 +/*
119441 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119442 + *
119443 + * Redistribution and use in source and binary forms, with or without
119444 + * modification, are permitted provided that the following conditions are met:
119445 + * * Redistributions of source code must retain the above copyright
119446 + * notice, this list of conditions and the following disclaimer.
119447 + * * Redistributions in binary form must reproduce the above copyright
119448 + * notice, this list of conditions and the following disclaimer in the
119449 + * documentation and/or other materials provided with the distribution.
119450 + * * Neither the name of Freescale Semiconductor nor the
119451 + * names of its contributors may be used to endorse or promote products
119452 + * derived from this software without specific prior written permission.
119453 + *
119454 + *
119455 + * ALTERNATIVELY, this software may be distributed under the terms of the
119456 + * GNU General Public License ("GPL") as published by the Free Software
119457 + * Foundation, either version 2 of that License or (at your option) any
119458 + * later version.
119459 + *
119460 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119461 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119462 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119463 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119464 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119465 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119466 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119467 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119468 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119469 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119470 + */
119471 +
119472 +#ifndef LNXWRP_SYSFS_H_
119473 +#define LNXWRP_SYSFS_H_
119474 +
119475 +/* Linux Headers ------------------- */
119476 +#include <linux/version.h>
119477 +
119478 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
119479 +#define MODVERSIONS
119480 +#endif
119481 +#ifdef MODVERSIONS
119482 +#include <config/modversions.h>
119483 +#endif /* MODVERSIONS */
119484 +
119485 +#include <linux/kernel.h>
119486 +#include <linux/module.h>
119487 +#include <linux/device.h>
119488 +#include <linux/sysfs.h>
119489 +
119490 +struct sysfs_stats_t {
119491 + const char *stat_name;
119492 + uint8_t stat_counter;
119493 +};
119494 +
119495 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
119496 + const struct sysfs_stats_t *sysfs_stats,
119497 + uint8_t *offset);
119498 +
119499 +#endif /* LNXWRP_SYSFS_H_ */
119500 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
119501 new file mode 100644
119502 index 00000000..1badbf98
119503 --- /dev/null
119504 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
119505 @@ -0,0 +1,1855 @@
119506 +/*
119507 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119508 + *
119509 + * Redistribution and use in source and binary forms, with or without
119510 + * modification, are permitted provided that the following conditions are met:
119511 + * * Redistributions of source code must retain the above copyright
119512 + * notice, this list of conditions and the following disclaimer.
119513 + * * Redistributions in binary form must reproduce the above copyright
119514 + * notice, this list of conditions and the following disclaimer in the
119515 + * documentation and/or other materials provided with the distribution.
119516 + * * Neither the name of Freescale Semiconductor nor the
119517 + * names of its contributors may be used to endorse or promote products
119518 + * derived from this software without specific prior written permission.
119519 + *
119520 + *
119521 + * ALTERNATIVELY, this software may be distributed under the terms of the
119522 + * GNU General Public License ("GPL") as published by the Free Software
119523 + * Foundation, either version 2 of that License or (at your option) any
119524 + * later version.
119525 + *
119526 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119527 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119528 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119529 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119530 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119531 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119532 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119533 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119534 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119535 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119536 + */
119537 +
119538 +#include "lnxwrp_sysfs.h"
119539 +#include "lnxwrp_sysfs_fm.h"
119540 +#include "lnxwrp_fm.h"
119541 +
119542 +#include "../../sdk_fman/Peripherals/FM/inc/fm_common.h"
119543 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h"
119544 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_kg.h"
119545 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h"
119546 +
119547 +#if defined(__ERR_MODULE__)
119548 +#undef __ERR_MODULE__
119549 +#endif
119550 +
119551 +#include "../../sdk_fman/Peripherals/FM/fm.h"
119552 +#include <linux/delay.h>
119553 +
119554 +
119555 +static int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val);
119556 +
119557 +enum fm_dma_match_stats {
119558 + FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
119559 + FM_DMA_COUNTERS_BUS_ERROR,
119560 + FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
119561 + FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
119562 + FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR
119563 +};
119564 +
119565 +static const struct sysfs_stats_t fm_sysfs_stats[] = {
119566 + /* FM statistics */
119567 + {
119568 + .stat_name = "enq_total_frame",
119569 + .stat_counter = e_FM_COUNTERS_ENQ_TOTAL_FRAME,
119570 + },
119571 + {
119572 + .stat_name = "deq_total_frame",
119573 + .stat_counter = e_FM_COUNTERS_DEQ_TOTAL_FRAME,
119574 + },
119575 + {
119576 + .stat_name = "deq_0",
119577 + .stat_counter = e_FM_COUNTERS_DEQ_0,
119578 + },
119579 + {
119580 + .stat_name = "deq_1",
119581 + .stat_counter = e_FM_COUNTERS_DEQ_1,
119582 + },
119583 + {
119584 + .stat_name = "deq_2",
119585 + .stat_counter = e_FM_COUNTERS_DEQ_2,
119586 + },
119587 + {
119588 + .stat_name = "deq_3",
119589 + .stat_counter = e_FM_COUNTERS_DEQ_3,
119590 + },
119591 + {
119592 + .stat_name = "deq_from_default",
119593 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_DEFAULT,
119594 + },
119595 + {
119596 + .stat_name = "deq_from_context",
119597 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_CONTEXT,
119598 + },
119599 + {
119600 + .stat_name = "deq_from_fd",
119601 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_FD,
119602 + },
119603 + {
119604 + .stat_name = "deq_confirm",
119605 + .stat_counter = e_FM_COUNTERS_DEQ_CONFIRM,
119606 + },
119607 + /* FM:DMA statistics */
119608 + {
119609 + .stat_name = "cmq_not_empty",
119610 + .stat_counter = FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
119611 + },
119612 + {
119613 + .stat_name = "bus_error",
119614 + .stat_counter = FM_DMA_COUNTERS_BUS_ERROR,
119615 + },
119616 + {
119617 + .stat_name = "read_buf_ecc_error",
119618 + .stat_counter = FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
119619 + },
119620 + {
119621 + .stat_name = "write_buf_ecc_sys_error",
119622 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
119623 + },
119624 + {
119625 + .stat_name = "write_buf_ecc_fm_error",
119626 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR,
119627 + },
119628 + /* FM:PCD statistics */
119629 + {
119630 + .stat_name = "pcd_kg_total",
119631 + .stat_counter = e_FM_PCD_KG_COUNTERS_TOTAL,
119632 + },
119633 + {
119634 + .stat_name = "pcd_plcr_yellow",
119635 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_YELLOW,
119636 + },
119637 + {
119638 + .stat_name = "pcd_plcr_red",
119639 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RED,
119640 + },
119641 + {
119642 + .stat_name = "pcd_plcr_recolored_to_red",
119643 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED,
119644 + },
119645 + {
119646 + .stat_name = "pcd_plcr_recolored_to_yellow",
119647 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW,
119648 + },
119649 + {
119650 + .stat_name = "pcd_plcr_total",
119651 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_TOTAL,
119652 + },
119653 + {
119654 + .stat_name = "pcd_plcr_length_mismatch",
119655 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH,
119656 + },
119657 + {
119658 + .stat_name = "pcd_prs_parse_dispatch",
119659 + .stat_counter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH,
119660 + },
119661 + {
119662 + .stat_name = "pcd_prs_l2_parse_result_returned",
119663 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED,
119664 + },
119665 + {
119666 + .stat_name = "pcd_prs_l3_parse_result_returned",
119667 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED,
119668 + },
119669 + {
119670 + .stat_name = "pcd_prs_l4_parse_result_returned",
119671 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED,
119672 + },
119673 + {
119674 + .stat_name = "pcd_prs_shim_parse_result_returned",
119675 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED,
119676 + },
119677 + {
119678 + .stat_name = "pcd_prs_l2_parse_result_returned_with_err",
119679 + .stat_counter =
119680 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR,
119681 + },
119682 + {
119683 + .stat_name = "pcd_prs_l3_parse_result_returned_with_err",
119684 + .stat_counter =
119685 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR,
119686 + },
119687 + {
119688 + .stat_name = "pcd_prs_l4_parse_result_returned_with_err",
119689 + .stat_counter =
119690 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR,
119691 + },
119692 + {
119693 + .stat_name = "pcd_prs_shim_parse_result_returned_with_err",
119694 + .stat_counter =
119695 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR,
119696 + },
119697 + {
119698 + .stat_name = "pcd_prs_soft_prs_cycles",
119699 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES,
119700 + },
119701 + {
119702 + .stat_name = "pcd_prs_soft_prs_stall_cycles",
119703 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES,
119704 + },
119705 + {
119706 + .stat_name = "pcd_prs_hard_prs_cycle_incl_stall_cycles",
119707 + .stat_counter =
119708 + e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES,
119709 + },
119710 + {
119711 + .stat_name = "pcd_prs_muram_read_cycles",
119712 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES,
119713 + },
119714 + {
119715 + .stat_name = "pcd_prs_muram_read_stall_cycles",
119716 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES,
119717 + },
119718 + {
119719 + .stat_name = "pcd_prs_muram_write_cycles",
119720 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES,
119721 + },
119722 + {
119723 + .stat_name = "pcd_prs_muram_write_stall_cycles",
119724 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES,
119725 + },
119726 + {
119727 + .stat_name = "pcd_prs_fpm_command_stall_cycles",
119728 + .stat_counter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES,
119729 + },
119730 + {}
119731 +};
119732 +
119733 +
119734 +static ssize_t show_fm_risc_load(struct device *dev,
119735 + struct device_attribute *attr, char *buf)
119736 +{
119737 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119738 + unsigned long flags;
119739 + int m =0;
119740 + int err =0;
119741 + unsigned n = 0;
119742 + t_FmCtrlMon util;
119743 + uint8_t i =0 ;
119744 +
119745 + if (attr == NULL || buf == NULL || dev == NULL)
119746 + return -EINVAL;
119747 +
119748 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119749 + if (WARN_ON(p_wrp_fm_dev == NULL))
119750 + return -EINVAL;
119751 +
119752 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119753 + return -EIO;
119754 +
119755 + local_irq_save(flags);
119756 +
119757 + /* Calculate risc load */
119758 + FM_CtrlMonStart(p_wrp_fm_dev->h_Dev);
119759 + msleep(1000);
119760 + FM_CtrlMonStop(p_wrp_fm_dev->h_Dev);
119761 +
119762 + for (i = 0; i < FM_NUM_OF_CTRL; i++) {
119763 + err |= FM_CtrlMonGetCounters(p_wrp_fm_dev->h_Dev, i, &util);
119764 + m = snprintf(&buf[n],PAGE_SIZE,"\tRisc%u: util-%u%%, efficiency-%u%%\n",
119765 + i, util.percentCnt[0], util.percentCnt[1]);
119766 + n=m+n;
119767 + }
119768 +
119769 + local_irq_restore(flags);
119770 +
119771 + return n;
119772 +}
119773 +
119774 +/* Fm stats and regs dumps via sysfs */
119775 +static ssize_t show_fm_dma_stats(struct device *dev,
119776 + struct device_attribute *attr, char *buf)
119777 +{
119778 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119779 + t_FmDmaStatus dma_status;
119780 + unsigned long flags = 0;
119781 + unsigned n = 0;
119782 + uint8_t counter_value = 0, counter = 0;
119783 +
119784 + if (attr == NULL || buf == NULL || dev == NULL)
119785 + return -EINVAL;
119786 +
119787 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119788 + if (WARN_ON(p_wrp_fm_dev == NULL))
119789 + return -EINVAL;
119790 +
119791 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119792 + return -EIO;
119793 +
119794 + counter = fm_find_statistic_counter_by_name(
119795 + attr->attr.name,
119796 + fm_sysfs_stats, NULL);
119797 +
119798 + local_irq_save(flags);
119799 +
119800 + memset(&dma_status, 0, sizeof(dma_status));
119801 + FM_GetDmaStatus(p_wrp_fm_dev->h_Dev, &dma_status);
119802 +
119803 + switch (counter) {
119804 + case FM_DMA_COUNTERS_CMQ_NOT_EMPTY:
119805 + counter_value = dma_status.cmqNotEmpty;
119806 + break;
119807 + case FM_DMA_COUNTERS_BUS_ERROR:
119808 + counter_value = dma_status.busError;
119809 + break;
119810 + case FM_DMA_COUNTERS_READ_BUF_ECC_ERROR:
119811 + counter_value = dma_status.readBufEccError;
119812 + break;
119813 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR:
119814 + counter_value = dma_status.writeBufEccSysError;
119815 + break;
119816 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR:
119817 + counter_value = dma_status.writeBufEccFmError;
119818 + break;
119819 + default:
119820 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
119821 + __func__);
119822 + break;
119823 + };
119824 +
119825 + n = snprintf(buf, PAGE_SIZE, "\tFM %u counter: %c\n",
119826 + p_wrp_fm_dev->id, counter_value ? 'T' : 'F');
119827 +
119828 + local_irq_restore(flags);
119829 +
119830 + return n;
119831 +}
119832 +
119833 +static ssize_t show_fm_stats(struct device *dev,
119834 + struct device_attribute *attr, char *buf)
119835 +{
119836 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119837 + unsigned long flags = 0;
119838 + unsigned n = 0, cnt_e = 0;
119839 + uint32_t cnt_val;
119840 + int err;
119841 +
119842 + if (attr == NULL || buf == NULL || dev == NULL)
119843 + return -EINVAL;
119844 +
119845 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119846 + if (WARN_ON(p_wrp_fm_dev == NULL))
119847 + return -EINVAL;
119848 +
119849 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119850 + return -EIO;
119851 +
119852 + cnt_e = fm_find_statistic_counter_by_name(
119853 + attr->attr.name,
119854 + fm_sysfs_stats, NULL);
119855 +
119856 + err = fm_get_counter(p_wrp_fm_dev->h_Dev,
119857 + (e_FmCounters) cnt_e, &cnt_val);
119858 +
119859 + if (err)
119860 + return err;
119861 +
119862 + local_irq_save(flags);
119863 +
119864 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119865 + p_wrp_fm_dev->id, cnt_val);
119866 +
119867 + local_irq_restore(flags);
119868 +
119869 + return n;
119870 +}
119871 +
119872 +static ssize_t show_fm_muram_free_sz(struct device *dev,
119873 + struct device_attribute *attr, char *buf)
119874 +{
119875 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119876 + unsigned long flags = 0;
119877 + unsigned n = 0;
119878 + uint64_t muram_free_size = 0;
119879 +
119880 + if (attr == NULL || buf == NULL || dev == NULL)
119881 + return -EINVAL;
119882 +
119883 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119884 + if (WARN_ON(p_wrp_fm_dev == NULL))
119885 + return -EINVAL;
119886 +
119887 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119888 + return -EIO;
119889 +
119890 + muram_free_size = FM_MURAM_GetFreeMemSize(p_wrp_fm_dev->h_MuramDev);
119891 +
119892 + local_irq_save(flags);
119893 +
119894 + n = snprintf(buf, PAGE_SIZE, "\tFM %d muram_free_size: %lld\n",
119895 + p_wrp_fm_dev->id, muram_free_size);
119896 +
119897 + local_irq_restore(flags);
119898 +
119899 + return n;
119900 +}
119901 +
119902 +static ssize_t show_fm_ctrl_code_ver(struct device *dev,
119903 + struct device_attribute *attr, char *buf)
119904 +{
119905 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119906 + unsigned long flags = 0;
119907 + unsigned n = 0;
119908 + t_FmCtrlCodeRevisionInfo rv_info;
119909 +
119910 + if (attr == NULL || buf == NULL || dev == NULL)
119911 + return -EINVAL;
119912 +
119913 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119914 + if (WARN_ON(p_wrp_fm_dev == NULL))
119915 + return -EINVAL;
119916 +
119917 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119918 + return -EIO;
119919 +
119920 + FM_GetFmanCtrlCodeRevision((t_Fm *)p_wrp_fm_dev->h_Dev, &rv_info);
119921 +
119922 + local_irq_save(flags);
119923 +
119924 + FM_DMP_LN(buf, n, "- FM %d ctrl code pkg info:\n", p_wrp_fm_dev->id);
119925 + FM_DMP_LN(buf, n, "Package rev: %d\n", rv_info.packageRev);
119926 + FM_DMP_LN(buf, n, "major rev: %d\n", rv_info.majorRev);
119927 + FM_DMP_LN(buf, n, "minor rev: %d\n", rv_info.minorRev);
119928 +
119929 + local_irq_restore(flags);
119930 +
119931 + return n;
119932 +}
119933 +
119934 +static ssize_t show_fm_pcd_stats(struct device *dev,
119935 + struct device_attribute *attr, char *buf)
119936 +{
119937 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119938 + unsigned long flags = 0;
119939 + unsigned n = 0, counter = 0;
119940 +
119941 + if (attr == NULL || buf == NULL || dev == NULL)
119942 + return -EINVAL;
119943 +
119944 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119945 + if (WARN_ON(p_wrp_fm_dev == NULL))
119946 + return -EINVAL;
119947 +
119948 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev ||
119949 + !p_wrp_fm_dev->h_PcdDev)
119950 + return -EIO;
119951 +
119952 + counter = fm_find_statistic_counter_by_name(
119953 + attr->attr.name,
119954 + fm_sysfs_stats, NULL);
119955 +
119956 + local_irq_save(flags);
119957 +
119958 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119959 + p_wrp_fm_dev->id,
119960 + FM_PCD_GetCounter(p_wrp_fm_dev->h_PcdDev,
119961 + (e_FmPcdCounters) counter));
119962 +
119963 + local_irq_restore(flags);
119964 +
119965 + return n;
119966 +}
119967 +
119968 +static ssize_t show_fm_tnum_dbg(struct device *dev,
119969 + struct device_attribute *attr,
119970 + char *buf)
119971 +{
119972 + unsigned long flags;
119973 + unsigned n = 0;
119974 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119975 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119976 +#endif
119977 +
119978 + if (attr == NULL || buf == NULL || dev == NULL)
119979 + return -EINVAL;
119980 +
119981 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119982 +
119983 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119984 + if (WARN_ON(p_wrp_fm_dev == NULL))
119985 + return -EINVAL;
119986 +
119987 + local_irq_save(flags);
119988 +
119989 + if (!p_wrp_fm_dev->active)
119990 + return -EIO;
119991 + else {
119992 + int tn_s;
119993 +
119994 + if (!sscanf(attr->attr.name, "tnum_dbg_%d", &tn_s))
119995 + return -EINVAL;
119996 +
119997 + n = fm_dump_tnum_dbg(p_wrp_fm_dev->h_Dev,
119998 + tn_s, tn_s + 15, buf, n);
119999 + }
120000 + local_irq_restore(flags);
120001 +#else
120002 +
120003 + local_irq_save(flags);
120004 + n = snprintf(buf, PAGE_SIZE,
120005 + "Debug level is too low to dump registers!!!\n");
120006 + local_irq_restore(flags);
120007 +#endif /* (defined(DEBUG_ERRORS) && ... */
120008 +
120009 + return n;
120010 +}
120011 +
120012 +static ssize_t show_fm_cls_plan(struct device *dev,
120013 + struct device_attribute *attr,
120014 + char *buf)
120015 +{
120016 + unsigned long flags;
120017 + unsigned n = 0;
120018 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120019 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120020 +#endif
120021 +
120022 + if (attr == NULL || buf == NULL || dev == NULL)
120023 + return -EINVAL;
120024 +
120025 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120026 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120027 + if (WARN_ON(p_wrp_fm_dev == NULL))
120028 + return -EINVAL;
120029 +
120030 + local_irq_save(flags);
120031 +
120032 + n = snprintf(buf, PAGE_SIZE, "\n FM-KG classification plan dump.\n");
120033 +
120034 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120035 + return -EIO;
120036 + else {
120037 + int cpn;
120038 +
120039 + if (!sscanf(attr->attr.name, "cls_plan_%d", &cpn))
120040 + return -EINVAL;
120041 +
120042 + n = fm_dump_cls_plan(p_wrp_fm_dev->h_PcdDev, cpn, buf, n);
120043 + }
120044 + local_irq_restore(flags);
120045 +#else
120046 + local_irq_save(flags);
120047 + n = snprintf(buf, PAGE_SIZE,
120048 + "Debug level is too low to dump registers!!!\n");
120049 + local_irq_restore(flags);
120050 +#endif /* (defined(DEBUG_ERRORS) && ... */
120051 +
120052 + return n;
120053 +}
120054 +
120055 +static ssize_t show_fm_profiles(struct device *dev,
120056 + struct device_attribute *attr,
120057 + char *buf)
120058 +{
120059 + unsigned long flags;
120060 + unsigned n = 0;
120061 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120062 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120063 +#endif
120064 +
120065 + if (attr == NULL || buf == NULL || dev == NULL)
120066 + return -EINVAL;
120067 +
120068 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120069 +
120070 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120071 + if (WARN_ON(p_wrp_fm_dev == NULL))
120072 + return -EINVAL;
120073 +
120074 + local_irq_save(flags);
120075 +
120076 + n = snprintf(buf, PAGE_SIZE, "FM policer profile dump.\n");
120077 +
120078 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120079 + return -EIO;
120080 + else {
120081 + int pn;
120082 +
120083 + if (!sscanf(attr->attr.name, "profile_%d", &pn))
120084 + return -EINVAL;
120085 +
120086 + n = fm_profile_dump_regs(p_wrp_fm_dev->h_PcdDev, pn, buf, n);
120087 + }
120088 + local_irq_restore(flags);
120089 +#else
120090 + local_irq_save(flags);
120091 + n = snprintf(buf, PAGE_SIZE,
120092 + "Debug level is too low to dump registers!!!\n");
120093 + local_irq_restore(flags);
120094 +#endif /* (defined(DEBUG_ERRORS) && ... */
120095 +
120096 + return n;
120097 +}
120098 +
120099 +static ssize_t show_fm_schemes(struct device *dev,
120100 + struct device_attribute *attr,
120101 + char *buf)
120102 +{
120103 + unsigned long flags;
120104 + unsigned n = 0;
120105 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120106 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120107 +#endif
120108 +
120109 + if (attr == NULL || buf == NULL || dev == NULL)
120110 + return -EINVAL;
120111 +
120112 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120113 +
120114 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120115 + if (WARN_ON(p_wrp_fm_dev == NULL))
120116 + return -EINVAL;
120117 +
120118 + local_irq_save(flags);
120119 +
120120 + n = snprintf(buf, PAGE_SIZE, "FM-KG driver schemes dump.\n");
120121 +
120122 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120123 + return -EIO;
120124 + else {
120125 + int sn;
120126 +
120127 + if (!sscanf(attr->attr.name, "scheme_%d", &sn))
120128 + return -EINVAL;
120129 +
120130 + n = fm_dump_scheme(p_wrp_fm_dev->h_PcdDev, sn, buf, n);
120131 + }
120132 + local_irq_restore(flags);
120133 +#else
120134 +
120135 + local_irq_save(flags);
120136 + n = snprintf(buf, PAGE_SIZE,
120137 + "Debug level is too low to dump registers!!!\n");
120138 + local_irq_restore(flags);
120139 +#endif /* (defined(DEBUG_ERRORS) && ... */
120140 +
120141 + return n;
120142 +}
120143 +
120144 +/* FM */
120145 +static DEVICE_ATTR(enq_total_frame, S_IRUGO, show_fm_stats, NULL);
120146 +static DEVICE_ATTR(deq_total_frame, S_IRUGO, show_fm_stats, NULL);
120147 +static DEVICE_ATTR(fm_risc_load_val, S_IRUGO, show_fm_risc_load, NULL);
120148 +static DEVICE_ATTR(deq_0, S_IRUGO, show_fm_stats, NULL);
120149 +static DEVICE_ATTR(deq_1, S_IRUGO, show_fm_stats, NULL);
120150 +static DEVICE_ATTR(deq_2, S_IRUGO, show_fm_stats, NULL);
120151 +static DEVICE_ATTR(deq_3, S_IRUGO, show_fm_stats, NULL);
120152 +static DEVICE_ATTR(deq_from_default, S_IRUGO, show_fm_stats, NULL);
120153 +static DEVICE_ATTR(deq_from_context, S_IRUGO, show_fm_stats, NULL);
120154 +static DEVICE_ATTR(deq_from_fd, S_IRUGO, show_fm_stats, NULL);
120155 +static DEVICE_ATTR(deq_confirm, S_IRUGO, show_fm_stats, NULL);
120156 +/* FM:DMA */
120157 +static DEVICE_ATTR(cmq_not_empty, S_IRUGO, show_fm_dma_stats, NULL);
120158 +static DEVICE_ATTR(bus_error, S_IRUGO, show_fm_dma_stats, NULL);
120159 +static DEVICE_ATTR(read_buf_ecc_error, S_IRUGO, show_fm_dma_stats, NULL);
120160 +static DEVICE_ATTR(write_buf_ecc_sys_error, S_IRUGO, show_fm_dma_stats, NULL);
120161 +static DEVICE_ATTR(write_buf_ecc_fm_error, S_IRUGO, show_fm_dma_stats, NULL);
120162 +/* FM:PCD */
120163 +static DEVICE_ATTR(pcd_kg_total, S_IRUGO, show_fm_pcd_stats, NULL);
120164 +static DEVICE_ATTR(pcd_plcr_yellow, S_IRUGO, show_fm_pcd_stats, NULL);
120165 +static DEVICE_ATTR(pcd_plcr_red, S_IRUGO, show_fm_pcd_stats, NULL);
120166 +static DEVICE_ATTR(pcd_plcr_recolored_to_red, S_IRUGO, show_fm_pcd_stats,
120167 + NULL);
120168 +static DEVICE_ATTR(pcd_plcr_recolored_to_yellow, S_IRUGO, show_fm_pcd_stats,
120169 + NULL);
120170 +static DEVICE_ATTR(pcd_plcr_total, S_IRUGO, show_fm_pcd_stats, NULL);
120171 +static DEVICE_ATTR(pcd_plcr_length_mismatch, S_IRUGO, show_fm_pcd_stats,
120172 + NULL);
120173 +static DEVICE_ATTR(pcd_prs_parse_dispatch, S_IRUGO, show_fm_pcd_stats, NULL);
120174 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned, S_IRUGO,
120175 + show_fm_pcd_stats, NULL);
120176 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned, S_IRUGO,
120177 + show_fm_pcd_stats, NULL);
120178 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned, S_IRUGO,
120179 + show_fm_pcd_stats, NULL);
120180 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned, S_IRUGO,
120181 + show_fm_pcd_stats, NULL);
120182 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned_with_err, S_IRUGO,
120183 + show_fm_pcd_stats, NULL);
120184 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned_with_err, S_IRUGO,
120185 + show_fm_pcd_stats, NULL);
120186 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned_with_err, S_IRUGO,
120187 + show_fm_pcd_stats, NULL);
120188 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned_with_err, S_IRUGO,
120189 + show_fm_pcd_stats, NULL);
120190 +static DEVICE_ATTR(pcd_prs_soft_prs_cycles, S_IRUGO, show_fm_pcd_stats, NULL);
120191 +static DEVICE_ATTR(pcd_prs_soft_prs_stall_cycles, S_IRUGO, show_fm_pcd_stats,
120192 + NULL);
120193 +static DEVICE_ATTR(pcd_prs_hard_prs_cycle_incl_stall_cycles, S_IRUGO,
120194 + show_fm_pcd_stats, NULL);
120195 +static DEVICE_ATTR(pcd_prs_muram_read_cycles, S_IRUGO, show_fm_pcd_stats,
120196 + NULL);
120197 +static DEVICE_ATTR(pcd_prs_muram_read_stall_cycles, S_IRUGO,
120198 + show_fm_pcd_stats, NULL);
120199 +static DEVICE_ATTR(pcd_prs_muram_write_cycles, S_IRUGO, show_fm_pcd_stats,
120200 + NULL);
120201 +static DEVICE_ATTR(pcd_prs_muram_write_stall_cycles, S_IRUGO,
120202 + show_fm_pcd_stats, NULL);
120203 +static DEVICE_ATTR(pcd_prs_fpm_command_stall_cycles, S_IRUGO,
120204 + show_fm_pcd_stats, NULL);
120205 +
120206 +static DEVICE_ATTR(tnum_dbg_0, S_IRUGO, show_fm_tnum_dbg, NULL);
120207 +static DEVICE_ATTR(tnum_dbg_16, S_IRUGO, show_fm_tnum_dbg, NULL);
120208 +static DEVICE_ATTR(tnum_dbg_32, S_IRUGO, show_fm_tnum_dbg, NULL);
120209 +static DEVICE_ATTR(tnum_dbg_48, S_IRUGO, show_fm_tnum_dbg, NULL);
120210 +static DEVICE_ATTR(tnum_dbg_64, S_IRUGO, show_fm_tnum_dbg, NULL);
120211 +static DEVICE_ATTR(tnum_dbg_80, S_IRUGO, show_fm_tnum_dbg, NULL);
120212 +static DEVICE_ATTR(tnum_dbg_96, S_IRUGO, show_fm_tnum_dbg, NULL);
120213 +static DEVICE_ATTR(tnum_dbg_112, S_IRUGO, show_fm_tnum_dbg, NULL);
120214 +
120215 +static DEVICE_ATTR(cls_plan_0, S_IRUGO, show_fm_cls_plan, NULL);
120216 +static DEVICE_ATTR(cls_plan_1, S_IRUGO, show_fm_cls_plan, NULL);
120217 +static DEVICE_ATTR(cls_plan_2, S_IRUGO, show_fm_cls_plan, NULL);
120218 +static DEVICE_ATTR(cls_plan_3, S_IRUGO, show_fm_cls_plan, NULL);
120219 +static DEVICE_ATTR(cls_plan_4, S_IRUGO, show_fm_cls_plan, NULL);
120220 +static DEVICE_ATTR(cls_plan_5, S_IRUGO, show_fm_cls_plan, NULL);
120221 +static DEVICE_ATTR(cls_plan_6, S_IRUGO, show_fm_cls_plan, NULL);
120222 +static DEVICE_ATTR(cls_plan_7, S_IRUGO, show_fm_cls_plan, NULL);
120223 +static DEVICE_ATTR(cls_plan_8, S_IRUGO, show_fm_cls_plan, NULL);
120224 +static DEVICE_ATTR(cls_plan_9, S_IRUGO, show_fm_cls_plan, NULL);
120225 +static DEVICE_ATTR(cls_plan_10, S_IRUGO, show_fm_cls_plan, NULL);
120226 +static DEVICE_ATTR(cls_plan_11, S_IRUGO, show_fm_cls_plan, NULL);
120227 +static DEVICE_ATTR(cls_plan_12, S_IRUGO, show_fm_cls_plan, NULL);
120228 +static DEVICE_ATTR(cls_plan_13, S_IRUGO, show_fm_cls_plan, NULL);
120229 +static DEVICE_ATTR(cls_plan_14, S_IRUGO, show_fm_cls_plan, NULL);
120230 +static DEVICE_ATTR(cls_plan_15, S_IRUGO, show_fm_cls_plan, NULL);
120231 +static DEVICE_ATTR(cls_plan_16, S_IRUGO, show_fm_cls_plan, NULL);
120232 +static DEVICE_ATTR(cls_plan_17, S_IRUGO, show_fm_cls_plan, NULL);
120233 +static DEVICE_ATTR(cls_plan_18, S_IRUGO, show_fm_cls_plan, NULL);
120234 +static DEVICE_ATTR(cls_plan_19, S_IRUGO, show_fm_cls_plan, NULL);
120235 +static DEVICE_ATTR(cls_plan_20, S_IRUGO, show_fm_cls_plan, NULL);
120236 +static DEVICE_ATTR(cls_plan_21, S_IRUGO, show_fm_cls_plan, NULL);
120237 +static DEVICE_ATTR(cls_plan_22, S_IRUGO, show_fm_cls_plan, NULL);
120238 +static DEVICE_ATTR(cls_plan_23, S_IRUGO, show_fm_cls_plan, NULL);
120239 +static DEVICE_ATTR(cls_plan_24, S_IRUGO, show_fm_cls_plan, NULL);
120240 +static DEVICE_ATTR(cls_plan_25, S_IRUGO, show_fm_cls_plan, NULL);
120241 +static DEVICE_ATTR(cls_plan_26, S_IRUGO, show_fm_cls_plan, NULL);
120242 +static DEVICE_ATTR(cls_plan_27, S_IRUGO, show_fm_cls_plan, NULL);
120243 +static DEVICE_ATTR(cls_plan_28, S_IRUGO, show_fm_cls_plan, NULL);
120244 +static DEVICE_ATTR(cls_plan_29, S_IRUGO, show_fm_cls_plan, NULL);
120245 +static DEVICE_ATTR(cls_plan_30, S_IRUGO, show_fm_cls_plan, NULL);
120246 +static DEVICE_ATTR(cls_plan_31, S_IRUGO, show_fm_cls_plan, NULL);
120247 +
120248 +static DEVICE_ATTR(profile_0, S_IRUGO, show_fm_profiles, NULL);
120249 +static DEVICE_ATTR(profile_1, S_IRUGO, show_fm_profiles, NULL);
120250 +static DEVICE_ATTR(profile_2, S_IRUGO, show_fm_profiles, NULL);
120251 +static DEVICE_ATTR(profile_3, S_IRUGO, show_fm_profiles, NULL);
120252 +static DEVICE_ATTR(profile_4, S_IRUGO, show_fm_profiles, NULL);
120253 +static DEVICE_ATTR(profile_5, S_IRUGO, show_fm_profiles, NULL);
120254 +static DEVICE_ATTR(profile_6, S_IRUGO, show_fm_profiles, NULL);
120255 +static DEVICE_ATTR(profile_7, S_IRUGO, show_fm_profiles, NULL);
120256 +static DEVICE_ATTR(profile_8, S_IRUGO, show_fm_profiles, NULL);
120257 +static DEVICE_ATTR(profile_9, S_IRUGO, show_fm_profiles, NULL);
120258 +static DEVICE_ATTR(profile_10, S_IRUGO, show_fm_profiles, NULL);
120259 +static DEVICE_ATTR(profile_11, S_IRUGO, show_fm_profiles, NULL);
120260 +static DEVICE_ATTR(profile_12, S_IRUGO, show_fm_profiles, NULL);
120261 +static DEVICE_ATTR(profile_13, S_IRUGO, show_fm_profiles, NULL);
120262 +static DEVICE_ATTR(profile_14, S_IRUGO, show_fm_profiles, NULL);
120263 +static DEVICE_ATTR(profile_15, S_IRUGO, show_fm_profiles, NULL);
120264 +static DEVICE_ATTR(profile_16, S_IRUGO, show_fm_profiles, NULL);
120265 +static DEVICE_ATTR(profile_17, S_IRUGO, show_fm_profiles, NULL);
120266 +static DEVICE_ATTR(profile_18, S_IRUGO, show_fm_profiles, NULL);
120267 +static DEVICE_ATTR(profile_19, S_IRUGO, show_fm_profiles, NULL);
120268 +static DEVICE_ATTR(profile_20, S_IRUGO, show_fm_profiles, NULL);
120269 +static DEVICE_ATTR(profile_21, S_IRUGO, show_fm_profiles, NULL);
120270 +static DEVICE_ATTR(profile_22, S_IRUGO, show_fm_profiles, NULL);
120271 +static DEVICE_ATTR(profile_23, S_IRUGO, show_fm_profiles, NULL);
120272 +static DEVICE_ATTR(profile_24, S_IRUGO, show_fm_profiles, NULL);
120273 +static DEVICE_ATTR(profile_25, S_IRUGO, show_fm_profiles, NULL);
120274 +static DEVICE_ATTR(profile_26, S_IRUGO, show_fm_profiles, NULL);
120275 +static DEVICE_ATTR(profile_27, S_IRUGO, show_fm_profiles, NULL);
120276 +static DEVICE_ATTR(profile_28, S_IRUGO, show_fm_profiles, NULL);
120277 +static DEVICE_ATTR(profile_29, S_IRUGO, show_fm_profiles, NULL);
120278 +static DEVICE_ATTR(profile_30, S_IRUGO, show_fm_profiles, NULL);
120279 +static DEVICE_ATTR(profile_31, S_IRUGO, show_fm_profiles, NULL);
120280 +
120281 +static DEVICE_ATTR(scheme_0, S_IRUGO, show_fm_schemes, NULL);
120282 +static DEVICE_ATTR(scheme_1, S_IRUGO, show_fm_schemes, NULL);
120283 +static DEVICE_ATTR(scheme_2, S_IRUGO, show_fm_schemes, NULL);
120284 +static DEVICE_ATTR(scheme_3, S_IRUGO, show_fm_schemes, NULL);
120285 +static DEVICE_ATTR(scheme_4, S_IRUGO, show_fm_schemes, NULL);
120286 +static DEVICE_ATTR(scheme_5, S_IRUGO, show_fm_schemes, NULL);
120287 +static DEVICE_ATTR(scheme_6, S_IRUGO, show_fm_schemes, NULL);
120288 +static DEVICE_ATTR(scheme_7, S_IRUGO, show_fm_schemes, NULL);
120289 +static DEVICE_ATTR(scheme_8, S_IRUGO, show_fm_schemes, NULL);
120290 +static DEVICE_ATTR(scheme_9, S_IRUGO, show_fm_schemes, NULL);
120291 +static DEVICE_ATTR(scheme_10, S_IRUGO, show_fm_schemes, NULL);
120292 +static DEVICE_ATTR(scheme_11, S_IRUGO, show_fm_schemes, NULL);
120293 +static DEVICE_ATTR(scheme_12, S_IRUGO, show_fm_schemes, NULL);
120294 +static DEVICE_ATTR(scheme_13, S_IRUGO, show_fm_schemes, NULL);
120295 +static DEVICE_ATTR(scheme_14, S_IRUGO, show_fm_schemes, NULL);
120296 +static DEVICE_ATTR(scheme_15, S_IRUGO, show_fm_schemes, NULL);
120297 +static DEVICE_ATTR(scheme_16, S_IRUGO, show_fm_schemes, NULL);
120298 +static DEVICE_ATTR(scheme_17, S_IRUGO, show_fm_schemes, NULL);
120299 +static DEVICE_ATTR(scheme_18, S_IRUGO, show_fm_schemes, NULL);
120300 +static DEVICE_ATTR(scheme_19, S_IRUGO, show_fm_schemes, NULL);
120301 +static DEVICE_ATTR(scheme_20, S_IRUGO, show_fm_schemes, NULL);
120302 +static DEVICE_ATTR(scheme_21, S_IRUGO, show_fm_schemes, NULL);
120303 +static DEVICE_ATTR(scheme_22, S_IRUGO, show_fm_schemes, NULL);
120304 +static DEVICE_ATTR(scheme_23, S_IRUGO, show_fm_schemes, NULL);
120305 +static DEVICE_ATTR(scheme_24, S_IRUGO, show_fm_schemes, NULL);
120306 +static DEVICE_ATTR(scheme_25, S_IRUGO, show_fm_schemes, NULL);
120307 +static DEVICE_ATTR(scheme_26, S_IRUGO, show_fm_schemes, NULL);
120308 +static DEVICE_ATTR(scheme_27, S_IRUGO, show_fm_schemes, NULL);
120309 +static DEVICE_ATTR(scheme_28, S_IRUGO, show_fm_schemes, NULL);
120310 +static DEVICE_ATTR(scheme_29, S_IRUGO, show_fm_schemes, NULL);
120311 +static DEVICE_ATTR(scheme_30, S_IRUGO, show_fm_schemes, NULL);
120312 +static DEVICE_ATTR(scheme_31, S_IRUGO, show_fm_schemes, NULL);
120313 +
120314 +
120315 +static struct attribute *fm_dev_stats_attributes[] = {
120316 + &dev_attr_enq_total_frame.attr,
120317 + &dev_attr_deq_total_frame.attr,
120318 + &dev_attr_deq_0.attr,
120319 + &dev_attr_deq_1.attr,
120320 + &dev_attr_deq_2.attr,
120321 + &dev_attr_deq_3.attr,
120322 + &dev_attr_deq_from_default.attr,
120323 + &dev_attr_deq_from_context.attr,
120324 + &dev_attr_deq_from_fd.attr,
120325 + &dev_attr_deq_confirm.attr,
120326 + &dev_attr_cmq_not_empty.attr,
120327 + &dev_attr_bus_error.attr,
120328 + &dev_attr_read_buf_ecc_error.attr,
120329 + &dev_attr_write_buf_ecc_sys_error.attr,
120330 + &dev_attr_write_buf_ecc_fm_error.attr,
120331 + &dev_attr_pcd_kg_total.attr,
120332 + &dev_attr_pcd_plcr_yellow.attr,
120333 + &dev_attr_pcd_plcr_red.attr,
120334 + &dev_attr_pcd_plcr_recolored_to_red.attr,
120335 + &dev_attr_pcd_plcr_recolored_to_yellow.attr,
120336 + &dev_attr_pcd_plcr_total.attr,
120337 + &dev_attr_pcd_plcr_length_mismatch.attr,
120338 + &dev_attr_pcd_prs_parse_dispatch.attr,
120339 + &dev_attr_pcd_prs_l2_parse_result_returned.attr,
120340 + &dev_attr_pcd_prs_l3_parse_result_returned.attr,
120341 + &dev_attr_pcd_prs_l4_parse_result_returned.attr,
120342 + &dev_attr_pcd_prs_shim_parse_result_returned.attr,
120343 + &dev_attr_pcd_prs_l2_parse_result_returned_with_err.attr,
120344 + &dev_attr_pcd_prs_l3_parse_result_returned_with_err.attr,
120345 + &dev_attr_pcd_prs_l4_parse_result_returned_with_err.attr,
120346 + &dev_attr_pcd_prs_shim_parse_result_returned_with_err.attr,
120347 + &dev_attr_pcd_prs_soft_prs_cycles.attr,
120348 + &dev_attr_pcd_prs_soft_prs_stall_cycles.attr,
120349 + &dev_attr_pcd_prs_hard_prs_cycle_incl_stall_cycles.attr,
120350 + &dev_attr_pcd_prs_muram_read_cycles.attr,
120351 + &dev_attr_pcd_prs_muram_read_stall_cycles.attr,
120352 + &dev_attr_pcd_prs_muram_write_cycles.attr,
120353 + &dev_attr_pcd_prs_muram_write_stall_cycles.attr,
120354 + &dev_attr_pcd_prs_fpm_command_stall_cycles.attr,
120355 + NULL
120356 +};
120357 +
120358 +static struct attribute *fm_dev_tnums_dbg_attributes[] = {
120359 + &dev_attr_tnum_dbg_0.attr,
120360 + &dev_attr_tnum_dbg_16.attr,
120361 + &dev_attr_tnum_dbg_32.attr,
120362 + &dev_attr_tnum_dbg_48.attr,
120363 + &dev_attr_tnum_dbg_64.attr,
120364 + &dev_attr_tnum_dbg_80.attr,
120365 + &dev_attr_tnum_dbg_96.attr,
120366 + &dev_attr_tnum_dbg_112.attr,
120367 + NULL
120368 +};
120369 +
120370 +static struct attribute *fm_dev_cls_plans_attributes[] = {
120371 + &dev_attr_cls_plan_0.attr,
120372 + &dev_attr_cls_plan_1.attr,
120373 + &dev_attr_cls_plan_2.attr,
120374 + &dev_attr_cls_plan_3.attr,
120375 + &dev_attr_cls_plan_4.attr,
120376 + &dev_attr_cls_plan_5.attr,
120377 + &dev_attr_cls_plan_6.attr,
120378 + &dev_attr_cls_plan_7.attr,
120379 + &dev_attr_cls_plan_8.attr,
120380 + &dev_attr_cls_plan_9.attr,
120381 + &dev_attr_cls_plan_10.attr,
120382 + &dev_attr_cls_plan_11.attr,
120383 + &dev_attr_cls_plan_12.attr,
120384 + &dev_attr_cls_plan_13.attr,
120385 + &dev_attr_cls_plan_14.attr,
120386 + &dev_attr_cls_plan_15.attr,
120387 + &dev_attr_cls_plan_16.attr,
120388 + &dev_attr_cls_plan_17.attr,
120389 + &dev_attr_cls_plan_18.attr,
120390 + &dev_attr_cls_plan_19.attr,
120391 + &dev_attr_cls_plan_20.attr,
120392 + &dev_attr_cls_plan_21.attr,
120393 + &dev_attr_cls_plan_22.attr,
120394 + &dev_attr_cls_plan_23.attr,
120395 + &dev_attr_cls_plan_24.attr,
120396 + &dev_attr_cls_plan_25.attr,
120397 + &dev_attr_cls_plan_26.attr,
120398 + &dev_attr_cls_plan_27.attr,
120399 + &dev_attr_cls_plan_28.attr,
120400 + &dev_attr_cls_plan_29.attr,
120401 + &dev_attr_cls_plan_30.attr,
120402 + &dev_attr_cls_plan_31.attr,
120403 + NULL
120404 +};
120405 +
120406 +static struct attribute *fm_dev_profiles_attributes[] = {
120407 + &dev_attr_profile_0.attr,
120408 + &dev_attr_profile_1.attr,
120409 + &dev_attr_profile_2.attr,
120410 + &dev_attr_profile_3.attr,
120411 + &dev_attr_profile_4.attr,
120412 + &dev_attr_profile_5.attr,
120413 + &dev_attr_profile_6.attr,
120414 + &dev_attr_profile_7.attr,
120415 + &dev_attr_profile_8.attr,
120416 + &dev_attr_profile_9.attr,
120417 + &dev_attr_profile_10.attr,
120418 + &dev_attr_profile_11.attr,
120419 + &dev_attr_profile_12.attr,
120420 + &dev_attr_profile_13.attr,
120421 + &dev_attr_profile_14.attr,
120422 + &dev_attr_profile_15.attr,
120423 + &dev_attr_profile_16.attr,
120424 + &dev_attr_profile_17.attr,
120425 + &dev_attr_profile_18.attr,
120426 + &dev_attr_profile_19.attr,
120427 + &dev_attr_profile_20.attr,
120428 + &dev_attr_profile_21.attr,
120429 + &dev_attr_profile_22.attr,
120430 + &dev_attr_profile_23.attr,
120431 + &dev_attr_profile_24.attr,
120432 + &dev_attr_profile_25.attr,
120433 + &dev_attr_profile_26.attr,
120434 + &dev_attr_profile_27.attr,
120435 + &dev_attr_profile_28.attr,
120436 + &dev_attr_profile_29.attr,
120437 + &dev_attr_profile_30.attr,
120438 + &dev_attr_profile_31.attr,
120439 + NULL
120440 +};
120441 +
120442 +static struct attribute *fm_dev_schemes_attributes[] = {
120443 + &dev_attr_scheme_0.attr,
120444 + &dev_attr_scheme_1.attr,
120445 + &dev_attr_scheme_2.attr,
120446 + &dev_attr_scheme_3.attr,
120447 + &dev_attr_scheme_4.attr,
120448 + &dev_attr_scheme_5.attr,
120449 + &dev_attr_scheme_6.attr,
120450 + &dev_attr_scheme_7.attr,
120451 + &dev_attr_scheme_8.attr,
120452 + &dev_attr_scheme_9.attr,
120453 + &dev_attr_scheme_10.attr,
120454 + &dev_attr_scheme_11.attr,
120455 + &dev_attr_scheme_12.attr,
120456 + &dev_attr_scheme_13.attr,
120457 + &dev_attr_scheme_14.attr,
120458 + &dev_attr_scheme_15.attr,
120459 + &dev_attr_scheme_16.attr,
120460 + &dev_attr_scheme_17.attr,
120461 + &dev_attr_scheme_18.attr,
120462 + &dev_attr_scheme_19.attr,
120463 + &dev_attr_scheme_20.attr,
120464 + &dev_attr_scheme_21.attr,
120465 + &dev_attr_scheme_22.attr,
120466 + &dev_attr_scheme_23.attr,
120467 + &dev_attr_scheme_24.attr,
120468 + &dev_attr_scheme_25.attr,
120469 + &dev_attr_scheme_26.attr,
120470 + &dev_attr_scheme_27.attr,
120471 + &dev_attr_scheme_28.attr,
120472 + &dev_attr_scheme_29.attr,
120473 + &dev_attr_scheme_30.attr,
120474 + &dev_attr_scheme_31.attr,
120475 + NULL
120476 +};
120477 +
120478 +static const struct attribute_group fm_dev_stats_attr_grp = {
120479 + .name = "statistics",
120480 + .attrs = fm_dev_stats_attributes
120481 +};
120482 +
120483 +static const struct attribute_group fm_dev_tnums_dbg_attr_grp = {
120484 + .name = "tnums_dbg",
120485 + .attrs = fm_dev_tnums_dbg_attributes
120486 +};
120487 +
120488 +static const struct attribute_group fm_dev_cls_plans_attr_grp = {
120489 + .name = "cls_plans",
120490 + .attrs = fm_dev_cls_plans_attributes
120491 +};
120492 +
120493 +static const struct attribute_group fm_dev_schemes_attr_grp = {
120494 + .name = "schemes",
120495 + .attrs = fm_dev_schemes_attributes
120496 +};
120497 +
120498 +static const struct attribute_group fm_dev_profiles_attr_grp = {
120499 + .name = "profiles",
120500 + .attrs = fm_dev_profiles_attributes
120501 +};
120502 +
120503 +static ssize_t show_fm_regs(struct device *dev,
120504 + struct device_attribute *attr,
120505 + char *buf)
120506 +{
120507 + unsigned long flags;
120508 + unsigned n = 0;
120509 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120510 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120511 +#endif
120512 + if (attr == NULL || buf == NULL || dev == NULL)
120513 + return -EINVAL;
120514 +
120515 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120516 +
120517 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120518 + if (WARN_ON(p_wrp_fm_dev == NULL))
120519 + return -EINVAL;
120520 +
120521 + local_irq_save(flags);
120522 +
120523 + n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n");
120524 +
120525 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120526 + return -EIO;
120527 + else
120528 + n = fm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
120529 +
120530 + local_irq_restore(flags);
120531 +#else
120532 +
120533 + local_irq_save(flags);
120534 + n = snprintf(buf, PAGE_SIZE,
120535 + "Debug level is too low to dump registers!!!\n");
120536 + local_irq_restore(flags);
120537 +#endif /* (defined(DEBUG_ERRORS) && ... */
120538 +
120539 + return n;
120540 +}
120541 +
120542 +static ssize_t show_fm_kg_pe_regs(struct device *dev,
120543 + struct device_attribute *attr,
120544 + char *buf)
120545 +{
120546 + unsigned long flags;
120547 + unsigned n = 0;
120548 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120549 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120550 +#endif
120551 +
120552 + if (attr == NULL || buf == NULL || dev == NULL)
120553 + return -EINVAL;
120554 +
120555 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120556 +
120557 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120558 + if (WARN_ON(p_wrp_fm_dev == NULL))
120559 + return -EINVAL;
120560 +
120561 + local_irq_save(flags);
120562 +
120563 + n = snprintf(buf, PAGE_SIZE,
120564 + "\n FM-KG Port Partition Config registers dump.\n");
120565 +
120566 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120567 + return -EIO;
120568 + else
120569 + n = fm_kg_pe_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120570 +
120571 + local_irq_restore(flags);
120572 +#else
120573 +
120574 + local_irq_save(flags);
120575 + n = snprintf(buf, PAGE_SIZE,
120576 + "Debug level is too low to dump registers!!!\n");
120577 + local_irq_restore(flags);
120578 +#endif /* (defined(DEBUG_ERRORS) && ... */
120579 +
120580 + return n;
120581 +}
120582 +
120583 +static ssize_t show_fm_kg_regs(struct device *dev,
120584 + struct device_attribute *attr,
120585 + char *buf)
120586 +{
120587 + unsigned long flags;
120588 + unsigned n = 0;
120589 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120590 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120591 +#endif
120592 +
120593 + if (attr == NULL || buf == NULL || dev == NULL)
120594 + return -EINVAL;
120595 +
120596 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120597 +
120598 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120599 + if (WARN_ON(p_wrp_fm_dev == NULL))
120600 + return -EINVAL;
120601 +
120602 + local_irq_save(flags);
120603 +
120604 + n = snprintf(buf, PAGE_SIZE, "FM-KG registers dump.\n");
120605 +
120606 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120607 + return -EIO;
120608 + else
120609 + n = fm_kg_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120610 +
120611 + local_irq_restore(flags);
120612 +#else
120613 +
120614 + local_irq_save(flags);
120615 + n = snprintf(buf, PAGE_SIZE,
120616 + "Debug level is too low to dump registers!!!\n");
120617 + local_irq_restore(flags);
120618 +#endif /* (defined(DEBUG_ERRORS) && ... */
120619 +
120620 + return n;
120621 +}
120622 +
120623 +
120624 +static ssize_t show_fm_fpm_regs(struct device *dev,
120625 + struct device_attribute *attr,
120626 + char *buf)
120627 +{
120628 + unsigned long flags;
120629 + unsigned n = 0;
120630 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120631 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120632 +#endif
120633 +
120634 + if (attr == NULL || buf == NULL || dev == NULL)
120635 + return -EINVAL;
120636 +
120637 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120638 +
120639 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120640 + if (WARN_ON(p_wrp_fm_dev == NULL))
120641 + return -EINVAL;
120642 +
120643 + local_irq_save(flags);
120644 +
120645 + n = snprintf(buf, PAGE_SIZE, "FM-FPM registers dump.\n");
120646 +
120647 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120648 + return -EIO;
120649 + else
120650 + n = fm_fpm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
120651 +
120652 + local_irq_restore(flags);
120653 +#else
120654 +
120655 + local_irq_save(flags);
120656 + n = snprintf(buf, PAGE_SIZE,
120657 + "Debug level is too low to dump registers!!!\n");
120658 + local_irq_restore(flags);
120659 +#endif /* (defined(DEBUG_ERRORS) && ... */
120660 +
120661 + return n;
120662 +}
120663 +
120664 +static ssize_t show_prs_regs(struct device *dev,
120665 + struct device_attribute *attr, char *buf)
120666 +{
120667 + unsigned long flags;
120668 + unsigned n = 0;
120669 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120670 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120671 +#endif
120672 +
120673 + if (attr == NULL || buf == NULL || dev == NULL)
120674 + return -EINVAL;
120675 +
120676 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120677 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120678 + if (WARN_ON(p_wrp_fm_dev == NULL))
120679 + return -EINVAL;
120680 +
120681 + local_irq_save(flags);
120682 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
120683 +
120684 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120685 + return -EIO;
120686 + else
120687 + n = fm_prs_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120688 +
120689 + local_irq_restore(flags);
120690 +#else
120691 +
120692 + local_irq_save(flags);
120693 + n = snprintf(buf, PAGE_SIZE,
120694 + "Debug level is too low to dump registers!!!\n");
120695 + local_irq_restore(flags);
120696 +
120697 +#endif /* (defined(DEBUG_ERRORS) && ... */
120698 +
120699 + return n;
120700 +}
120701 +
120702 +static ssize_t show_plcr_regs(struct device *dev,
120703 + struct device_attribute *attr,
120704 + char *buf)
120705 +{
120706 + unsigned long flags;
120707 + unsigned n = 0;
120708 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120709 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120710 +#endif
120711 +
120712 + if (attr == NULL || buf == NULL || dev == NULL)
120713 + return -EINVAL;
120714 +
120715 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120716 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120717 + if (WARN_ON(p_wrp_fm_dev == NULL))
120718 + return -EINVAL;
120719 +
120720 + local_irq_save(flags);
120721 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
120722 +
120723 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120724 + return -EIO;
120725 + else
120726 + n = fm_plcr_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120727 +
120728 + local_irq_restore(flags);
120729 +#else
120730 +
120731 + local_irq_save(flags);
120732 + n = snprintf(buf, PAGE_SIZE,
120733 + "Debug level is too low to dump registers!!!\n");
120734 + local_irq_restore(flags);
120735 +
120736 +#endif /* (defined(DEBUG_ERRORS) && ... */
120737 +
120738 + return n;
120739 +}
120740 +
120741 +static DEVICE_ATTR(fm_regs, S_IRUGO, show_fm_regs, NULL);
120742 +static DEVICE_ATTR(fm_fpm_regs, S_IRUGO, show_fm_fpm_regs, NULL);
120743 +static DEVICE_ATTR(fm_kg_regs, S_IRUGO, show_fm_kg_regs, NULL);
120744 +static DEVICE_ATTR(fm_kg_pe_regs, S_IRUGO, show_fm_kg_pe_regs, NULL);
120745 +static DEVICE_ATTR(fm_plcr_regs, S_IRUGO, show_plcr_regs, NULL);
120746 +static DEVICE_ATTR(fm_prs_regs, S_IRUGO, show_prs_regs, NULL);
120747 +static DEVICE_ATTR(fm_muram_free_size, S_IRUGO, show_fm_muram_free_sz, NULL);
120748 +static DEVICE_ATTR(fm_ctrl_code_ver, S_IRUGO, show_fm_ctrl_code_ver, NULL);
120749 +
120750 +int fm_sysfs_create(struct device *dev)
120751 +{
120752 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120753 +
120754 + if (dev == NULL)
120755 + return -EIO;
120756 +
120757 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120758 +
120759 + /* store to remove them when module is disabled */
120760 + p_wrp_fm_dev->dev_attr_regs = &dev_attr_fm_regs;
120761 + p_wrp_fm_dev->dev_attr_risc_load = &dev_attr_fm_risc_load_val;
120762 + p_wrp_fm_dev->dev_fm_fpm_attr_regs = &dev_attr_fm_fpm_regs;
120763 + p_wrp_fm_dev->dev_fm_kg_attr_regs = &dev_attr_fm_kg_regs;
120764 + p_wrp_fm_dev->dev_fm_kg_pe_attr_regs = &dev_attr_fm_kg_pe_regs;
120765 + p_wrp_fm_dev->dev_plcr_attr_regs = &dev_attr_fm_plcr_regs;
120766 + p_wrp_fm_dev->dev_prs_attr_regs = &dev_attr_fm_prs_regs;
120767 + p_wrp_fm_dev->dev_attr_muram_free_size = &dev_attr_fm_muram_free_size;
120768 + p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver = &dev_attr_fm_ctrl_code_ver;
120769 +
120770 + /* Create sysfs statistics group for FM module */
120771 + if (sysfs_create_group(&dev->kobj, &fm_dev_stats_attr_grp) != 0)
120772 + return -EIO;
120773 +
120774 + if (sysfs_create_group(&dev->kobj, &fm_dev_schemes_attr_grp) != 0)
120775 + return -EIO;
120776 +
120777 + if (sysfs_create_group(&dev->kobj, &fm_dev_profiles_attr_grp) != 0)
120778 + return -EIO;
120779 +
120780 + if (sysfs_create_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp) != 0)
120781 + return -EIO;
120782 +
120783 + if (sysfs_create_group(&dev->kobj, &fm_dev_cls_plans_attr_grp) != 0)
120784 + return -EIO;
120785 +
120786 + /* Registers dump entry - in future will be moved to debugfs */
120787 + if (device_create_file(dev, &dev_attr_fm_regs) != 0)
120788 + return -EIO;
120789 +
120790 + if (device_create_file(dev, &dev_attr_fm_risc_load_val) != 0)
120791 + return -EIO;
120792 +
120793 + if (device_create_file(dev, &dev_attr_fm_fpm_regs) != 0)
120794 + return -EIO;
120795 +
120796 + if (device_create_file(dev, &dev_attr_fm_kg_regs) != 0)
120797 + return -EIO;
120798 +
120799 + if (device_create_file(dev, &dev_attr_fm_kg_pe_regs) != 0)
120800 + return -EIO;
120801 +
120802 + if (device_create_file(dev, &dev_attr_fm_plcr_regs) != 0)
120803 + return -EIO;
120804 +
120805 + if (device_create_file(dev, &dev_attr_fm_prs_regs) != 0)
120806 + return -EIO;
120807 +
120808 + /* muram free size */
120809 + if (device_create_file(dev, &dev_attr_fm_muram_free_size) != 0)
120810 + return -EIO;
120811 +
120812 + /* fm ctrl code version */
120813 + if (device_create_file(dev, &dev_attr_fm_ctrl_code_ver) != 0)
120814 + return -EIO;
120815 +
120816 + return 0;
120817 +}
120818 +
120819 +void fm_sysfs_destroy(struct device *dev)
120820 +{
120821 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120822 +
120823 + if (WARN_ON(dev == NULL))
120824 + return;
120825 +
120826 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120827 + if (WARN_ON(p_wrp_fm_dev == NULL))
120828 + return;
120829 +
120830 + sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp);
120831 + sysfs_remove_group(&dev->kobj, &fm_dev_schemes_attr_grp);
120832 + sysfs_remove_group(&dev->kobj, &fm_dev_profiles_attr_grp);
120833 + sysfs_remove_group(&dev->kobj, &fm_dev_cls_plans_attr_grp);
120834 + sysfs_remove_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp);
120835 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_regs);
120836 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_fpm_attr_regs);
120837 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_attr_regs);
120838 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_pe_attr_regs);
120839 + device_remove_file(dev, p_wrp_fm_dev->dev_plcr_attr_regs);
120840 + device_remove_file(dev, p_wrp_fm_dev->dev_prs_attr_regs);
120841 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_muram_free_size);
120842 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver);
120843 +}
120844 +
120845 +int fm_dump_regs(void *h_fm, char *buf, int nn)
120846 +{
120847 + t_Fm *p_Fm = (t_Fm *)h_fm;
120848 + uint8_t i = 0;
120849 + int n = nn;
120850 +
120851 + FM_DMP_SUBTITLE(buf, n, "\n");
120852 +
120853 + FM_DMP_TITLE(buf, n, p_Fm->p_FmDmaRegs, "FM-DMA Regs");
120854 +
120855 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsr);
120856 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmemsr);
120857 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmmr);
120858 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtr);
120859 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmhy);
120860 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsetr);
120861 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtah);
120862 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtal);
120863 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtcid);
120864 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmra);
120865 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmrd);
120866 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmwcr);
120867 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmebcr);
120868 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmdcr);
120869 +
120870 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr, "fmdmplr");
120871 +
120872 + for (i = 0; i < FM_MAX_NUM_OF_HW_PORT_IDS / 2 ; ++i)
120873 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[i]);
120874 +
120875 + FM_DMP_TITLE(buf, n, p_Fm->p_FmBmiRegs, "FM-BMI COMMON Regs");
120876 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_init);
120877 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg1);
120878 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg2);
120879 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ievr);
120880 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ier);
120881 +
120882 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb, "fmbm_arb");
120883 + for (i = 0; i < 8 ; ++i)
120884 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb[i]);
120885 +
120886 + FM_DMP_TITLE(buf, n, p_Fm->p_FmQmiRegs, "FM-QMI COMMON Regs");
120887 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gc);
120888 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eie);
120889 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eien);
120890 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eif);
120891 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ie);
120892 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ien);
120893 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_if);
120894 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gs);
120895 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_etfc);
120896 +
120897 + return n;
120898 +}
120899 +
120900 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn)
120901 +{
120902 + t_Fm *p_Fm = (t_Fm *)h_fm;
120903 + uint8_t i, j = 0;
120904 + int n = nn;
120905 +
120906 + FM_DMP_TITLE(buf, n, NULL, "Tnums and Tnum dbg regs %d - %d",
120907 + tn_s, tn_e);
120908 +
120909 + iowrite32be(tn_s << 24, &p_Fm->p_FmFpmRegs->fmfp_dra);
120910 +
120911 + mb();
120912 +
120913 + for (j = tn_s; j <= tn_e; j++) {
120914 + FM_DMP_LN(buf, n, "> fmfp_ts[%d]\n", j);
120915 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ts[j]);
120916 + FM_DMP_V32(buf, n, p_Fm->p_FmFpmRegs, fmfp_dra);
120917 + FM_DMP_LN(buf, n, "> fmfp_drd[0-3]\n");
120918 +
120919 + for (i = 0; i < 4 ; ++i)
120920 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_drd[i]);
120921 +
120922 + FM_DMP_LN(buf, n, "\n");
120923 +
120924 + }
120925 +
120926 + return n;
120927 +}
120928 +
120929 +int fm_dump_cls_plan(void *h_fm_pcd, int cpn, char *buf, int nn)
120930 +{
120931 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120932 + int i = 0;
120933 + uint32_t tmp;
120934 + unsigned long i_flg;
120935 + int n = nn;
120936 + u_FmPcdKgIndirectAccessRegs *idac;
120937 + spinlock_t *p_lk;
120938 +
120939 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120940 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120941 +
120942 + spin_lock_irqsave(p_lk, i_flg);
120943 +
120944 + /* Read ClsPlan Block Action Regs */
120945 + tmp = (uint32_t)(FM_KG_KGAR_GO |
120946 + FM_KG_KGAR_READ |
120947 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
120948 + DUMMY_PORT_ID |
120949 + ((uint32_t)cpn << FM_PCD_KG_KGAR_NUM_SHIFT) |
120950 + FM_PCD_KG_KGAR_WSEL_MASK);
120951 +
120952 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp)) {
120953 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120954 + spin_unlock_irqrestore(p_lk, i_flg);
120955 + return nn;
120956 + }
120957 + FM_DMP_TITLE(buf, n, &idac->clsPlanRegs,
120958 + "ClsPlan %d Indirect Access Regs", cpn);
120959 +
120960 + for (i = 0; i < 8; i++)
120961 + FM_DMP_MEM_32(buf, n, &idac->clsPlanRegs.kgcpe[i]);
120962 +
120963 + spin_unlock_irqrestore(p_lk, i_flg);
120964 +
120965 + return n;
120966 +}
120967 +
120968 +int fm_profile_dump_regs(void *h_fm_pcd, int ppn, char *buf, int nn)
120969 +{
120970 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120971 + t_FmPcdPlcrProfileRegs *p_prof_regs;
120972 + t_FmPcdPlcrRegs *p_plcr_regs;
120973 + t_FmPcdPlcr *p_plcr;
120974 + uint32_t tmp;
120975 + unsigned long i_flg;
120976 + int n = nn;
120977 + int toc = 10;
120978 + spinlock_t *p_lk;
120979 +
120980 + p_plcr = p_pcd->p_FmPcdPlcr;
120981 + p_prof_regs = &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs;
120982 + p_plcr_regs = p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
120983 +
120984 + p_lk = (spinlock_t *)((t_FmPcdPlcr *)p_plcr)->h_HwSpinlock;
120985 +
120986 + FM_DMP_SUBTITLE(buf, n, "\n");
120987 + FM_DMP_TITLE(buf, n, p_plcr_regs, "FM-PCD policer-profile regs");
120988 +
120989 + tmp = (uint32_t)(FM_PCD_PLCR_PAR_GO |
120990 + FM_PCD_PLCR_PAR_R |
120991 + ((uint32_t)ppn << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
120992 + FM_PCD_PLCR_PAR_PWSEL_MASK);
120993 +
120994 + spin_lock_irqsave(p_lk, i_flg);
120995 +
120996 + iowrite32be(tmp, &p_plcr_regs->fmpl_par);
120997 +
120998 + mb();
120999 +
121000 + /* wait for the porfile regs to be present */
121001 + do {
121002 + --toc;
121003 + udelay(10);
121004 + if (!toc) {
121005 + /* looks like PLCR_PAR_GO refuses to clear */
121006 + spin_unlock_irqrestore(p_lk, i_flg);
121007 + FM_DMP_LN(buf, n, "Profile regs not accessible -");
121008 + FM_DMP_LN(buf, n, " check profile init process\n");
121009 + return n;
121010 + }
121011 + } while ((ioread32be(&p_plcr_regs->fmpl_par) & FM_PCD_PLCR_PAR_GO));
121012 +
121013 + FM_DMP_TITLE(buf, n, p_prof_regs, "Profile %d regs", ppn);
121014 +
121015 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pemode);
121016 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegnia);
121017 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peynia);
121018 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pernia);
121019 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecir);
121020 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecbs);
121021 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepepir_eir);
121022 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepbs_ebs);
121023 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pelts);
121024 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pects);
121025 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepts_ets);
121026 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegpc);
121027 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peypc);
121028 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perpc);
121029 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perypc);
121030 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perrpc);
121031 +
121032 + spin_unlock_irqrestore(p_lk, i_flg);
121033 +
121034 + return n;
121035 +}
121036 +
121037 +int fm_dump_scheme(void *h_fm_pcd, int scnum, char *buf, int nn)
121038 +{
121039 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
121040 + uint32_t tmp_ar;
121041 + unsigned long i_flg;
121042 + int i, n = nn;
121043 + spinlock_t *p_lk;
121044 + u_FmPcdKgIndirectAccessRegs *idac;
121045 +
121046 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
121047 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
121048 +
121049 + spin_lock_irqsave(p_lk, i_flg);
121050 +
121051 + tmp_ar = FmPcdKgBuildReadSchemeActionReg((uint8_t)scnum);
121052 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp_ar)) {
121053 + FM_DMP_LN(buf, nn,
121054 + "Keygen scheme access violation or no such scheme");
121055 + spin_unlock_irqrestore(p_lk, i_flg);
121056 + return nn;
121057 + }
121058 +
121059 + FM_DMP_TITLE(buf, n, &idac->schemeRegs,
121060 + "Scheme %d Indirect Access Regs", scnum);
121061 +
121062 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mode);
121063 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekfc);
121064 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekdv);
121065 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmch);
121066 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmcl);
121067 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_fqb);
121068 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_hc);
121069 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ppc);
121070 +
121071 + FM_DMP_TITLE(buf, n, &idac->schemeRegs.kgse_gec, "kgse_gec");
121072 +
121073 + for (i = 0; i < FM_KG_NUM_OF_GENERIC_REGS; i++)
121074 + FM_DMP_MEM_32(buf, n, &idac->schemeRegs.kgse_gec[i]);
121075 +
121076 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_spc);
121077 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv0);
121078 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv1);
121079 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ccbs);
121080 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mv);
121081 +
121082 + FM_DMP_SUBTITLE(buf, n, "\n");
121083 +
121084 + spin_unlock_irqrestore(p_lk, i_flg);
121085 +
121086 + return n;
121087 +}
121088 +
121089 +int fm_kg_pe_dump_regs(void *h_fm_pcd, char *buf, int nn)
121090 +{
121091 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
121092 + int i = 0;
121093 + uint8_t prt_id = 0;
121094 + uint32_t tmp_ar;
121095 + unsigned long i_flg;
121096 + int n = nn;
121097 + u_FmPcdKgIndirectAccessRegs *idac;
121098 + t_FmPcdKg *p_kg;
121099 + spinlock_t *p_lk;
121100 +
121101 + p_kg = p_pcd->p_FmPcdKg;
121102 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
121103 + p_lk = (spinlock_t *)p_kg->h_HwSpinlock;
121104 +
121105 + spin_lock_irqsave(p_lk, i_flg);
121106 +
121107 + FM_DMP_SUBTITLE(buf, n, "\n");
121108 +
121109 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) {
121110 + SW_PORT_INDX_TO_HW_PORT_ID(prt_id, i);
121111 +
121112 + tmp_ar = FmPcdKgBuildReadPortSchemeBindActionReg(prt_id);
121113 +
121114 + if (fman_kg_write_ar_wait(p_kg->p_FmPcdKgRegs, tmp_ar)) {
121115 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
121116 + spin_unlock_irqrestore(p_lk, i_flg);
121117 + return nn;
121118 + }
121119 + FM_DMP_TITLE(buf, n, &idac->portRegs, "Port %d regs", prt_id);
121120 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_sp);
121121 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_cpp);
121122 + }
121123 +
121124 + FM_DMP_SUBTITLE(buf, n, "\n");
121125 +
121126 + spin_unlock_irqrestore(p_lk, i_flg);
121127 +
121128 + return n;
121129 +}
121130 +
121131 +int fm_kg_dump_regs(void *h_fm_pcd, char *buf, int nn)
121132 +{
121133 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
121134 + int n = nn;
121135 +
121136 + FM_DMP_SUBTITLE(buf, n, "\n");
121137 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs,
121138 + "FmPcdKgRegs Regs");
121139 +
121140 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gcr);
121141 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eer);
121142 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eeer);
121143 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seer);
121144 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seeer);
121145 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gsr);
121146 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_tpc);
121147 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_serc);
121148 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_fdor);
121149 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv0r);
121150 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv1r);
121151 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_feer);
121152 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_ar);
121153 +
121154 + FM_DMP_SUBTITLE(buf, n, "\n");
121155 +
121156 + return n;
121157 +}
121158 +
121159 +
121160 +int fm_fpm_dump_regs(void *h_fm, char *buf, int nn)
121161 +{
121162 + t_Fm *p_fm = (t_Fm *)h_fm;
121163 + uint8_t i;
121164 + int n = nn;
121165 +
121166 + FM_DMP_SUBTITLE(buf, n, "\n");
121167 +
121168 + FM_DMP_TITLE(buf, n, p_fm->p_FmFpmRegs, "FM-FPM Regs");
121169 +
121170 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tnc);
121171 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_prc);
121172 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_brkc);
121173 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_mxd);
121174 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist1);
121175 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist2);
121176 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_epi);
121177 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rie);
121178 +
121179 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev, "fmfp_fcev");
121180 + for (i = 0; i < 4; ++i)
121181 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev[i]);
121182 +
121183 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee, "fmfp_cee");
121184 + for (i = 0; i < 4; ++i)
121185 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee[i]);
121186 +
121187 + FM_DMP_SUBTITLE(buf, n, "\n");
121188 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc1);
121189 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc2);
121190 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsp);
121191 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsf);
121192 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rcr);
121193 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_extc);
121194 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext1);
121195 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext2);
121196 +
121197 + FM_DMP_SUBTITLE(buf, n, "\n");
121198 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_1);
121199 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_2);
121200 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rstc);
121201 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_cld);
121202 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_npi);
121203 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ee);
121204 +
121205 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev, "fmfp_cev");
121206 + for (i = 0; i < 4; ++i)
121207 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev[i]);
121208 +
121209 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps, "fmfp_ps");
121210 + for (i = 0; i < 64; ++i)
121211 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps[i]);
121212 +
121213 + return n;
121214 +}
121215 +
121216 +int fm_prs_dump_regs(void *h_fm_pcd, char *buf, int nn)
121217 +{
121218 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
121219 + int n = nn;
121220 +
121221 + FM_DMP_SUBTITLE(buf, n, "\n");
121222 +
121223 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs,
121224 + "FM-PCD parser regs");
121225 +
121226 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpclim);
121227 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpimac);
121228 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, pmeec);
121229 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pevr);
121230 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pever);
121231 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perr);
121232 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perer);
121233 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_ppsc);
121234 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pds);
121235 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rrs);
121236 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rrs);
121237 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rrs);
121238 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srrs);
121239 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rres);
121240 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rres);
121241 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rres);
121242 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srres);
121243 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spcs);
121244 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spscs);
121245 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_hxscs);
121246 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrcs);
121247 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwcs);
121248 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrscs);
121249 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwscs);
121250 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_fcscs);
121251 +
121252 + return n;
121253 +}
121254 +
121255 +int fm_plcr_dump_regs(void *h_fm_pcd, char *buf, int nn)
121256 +{
121257 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
121258 + int i = 0;
121259 + int n = nn;
121260 +
121261 + FM_DMP_SUBTITLE(buf, n, "\n");
121262 +
121263 + FM_DMP_TITLE(buf, n,
121264 + p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,
121265 + "FM policer regs");
121266 +
121267 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gcr);
121268 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gsr);
121269 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_evr);
121270 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ier);
121271 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ifr);
121272 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eevr);
121273 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eier);
121274 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eifr);
121275 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rpcnt);
121276 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ypcnt);
121277 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rrpcnt);
121278 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rypcnt);
121279 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_tpcnt);
121280 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_flmcnt);
121281 +
121282 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_serc);
121283 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_upcr);
121284 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_dpmr);
121285 +
121286 + FM_DMP_TITLE(buf, n,
121287 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr,
121288 + "fmpl_pmr");
121289 +
121290 + for (i = 0; i < 63; ++i)
121291 + FM_DMP_MEM_32(buf, n,
121292 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i]);
121293 +
121294 + return n;
121295 +}
121296 +
121297 +int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val)
121298 +{
121299 + t_Fm *p_fm = (t_Fm *)h_fm;
121300 +
121301 + /* When applicable (when there is an "enable counters" bit),
121302 + check that counters are enabled */
121303 +
121304 + switch (cnt_e) {
121305 + case (e_FM_COUNTERS_DEQ_1):
121306 + case (e_FM_COUNTERS_DEQ_2):
121307 + case (e_FM_COUNTERS_DEQ_3):
121308 + if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6)
121309 + return -EINVAL; /* counter not available */
121310 +
121311 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
121312 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
121313 + case (e_FM_COUNTERS_DEQ_0):
121314 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
121315 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
121316 + case (e_FM_COUNTERS_DEQ_FROM_FD):
121317 + case (e_FM_COUNTERS_DEQ_CONFIRM):
121318 + if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) &
121319 + QMI_CFG_EN_COUNTERS))
121320 + return -EINVAL; /* Requested counter not available */
121321 + break;
121322 + default:
121323 + break;
121324 + }
121325 +
121326 + switch (cnt_e) {
121327 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
121328 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_etfc);
121329 + return 0;
121330 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
121331 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dtfc);
121332 + return 0;
121333 + case (e_FM_COUNTERS_DEQ_0):
121334 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc0);
121335 + return 0;
121336 + case (e_FM_COUNTERS_DEQ_1):
121337 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc1);
121338 + return 0;
121339 + case (e_FM_COUNTERS_DEQ_2):
121340 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc2);
121341 + return 0;
121342 + case (e_FM_COUNTERS_DEQ_3):
121343 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc3);
121344 + return 0;
121345 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
121346 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfdc);
121347 + return 0;
121348 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
121349 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfcc);
121350 + return 0;
121351 + case (e_FM_COUNTERS_DEQ_FROM_FD):
121352 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dffc);
121353 + return 0;
121354 + case (e_FM_COUNTERS_DEQ_CONFIRM):
121355 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dcc);
121356 + return 0;
121357 + }
121358 + /* should never get here */
121359 + return -EINVAL; /* counter not available */
121360 +}
121361 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
121362 new file mode 100644
121363 index 00000000..137653e9
121364 --- /dev/null
121365 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
121366 @@ -0,0 +1,136 @@
121367 +/*
121368 + * Copyright 2008-2012 Freescale Semiconductor Inc.
121369 + *
121370 + * Redistribution and use in source and binary forms, with or without
121371 + * modification, are permitted provided that the following conditions are met:
121372 + * * Redistributions of source code must retain the above copyright
121373 + * notice, this list of conditions and the following disclaimer.
121374 + * * Redistributions in binary form must reproduce the above copyright
121375 + * notice, this list of conditions and the following disclaimer in the
121376 + * documentation and/or other materials provided with the distribution.
121377 + * * Neither the name of Freescale Semiconductor nor the
121378 + * names of its contributors may be used to endorse or promote products
121379 + * derived from this software without specific prior written permission.
121380 + *
121381 + *
121382 + * ALTERNATIVELY, this software may be distributed under the terms of the
121383 + * GNU General Public License ("GPL") as published by the Free Software
121384 + * Foundation, either version 2 of that License or (at your option) any
121385 + * later version.
121386 + *
121387 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
121388 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
121389 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
121390 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
121391 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
121392 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
121393 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
121394 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
121395 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
121396 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
121397 + */
121398 +
121399 +
121400 +#ifndef LNXWRP_SYSFS_FM_H_
121401 +#define LNXWRP_SYSFS_FM_H_
121402 +
121403 +#include "lnxwrp_sysfs.h"
121404 +
121405 +int fm_sysfs_create(struct device *dev);
121406 +void fm_sysfs_destroy(struct device *dev);
121407 +int fm_dump_regs(void *h_dev, char *buf, int nn);
121408 +int fm_fpm_dump_regs(void *h_dev, char *buf, int nn);
121409 +int fm_kg_dump_regs(void *h_pcd, char *buf, int nn);
121410 +int fm_kg_pe_dump_regs(void *h_pcd, char *buf, int nn);
121411 +int fm_dump_scheme(void *h_pcd, int scnum, char *buf, int nn);
121412 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn);
121413 +int fm_dump_cls_plan(void *h_pcd, int cpn, char *buf, int nn);
121414 +int fm_plcr_dump_regs(void *h_pcd, char *buf, int nn);
121415 +int fm_prs_dump_regs(void *h_pcd, char *buf, int nn);
121416 +int fm_profile_dump_regs(void *h_pcd, int ppnum, char *buf, int nn);
121417 +
121418 +#define FM_DMP_PGSZ_ERR { \
121419 + snprintf(&buf[PAGE_SIZE - 80], 70, \
121420 + "\n Err: current sysfs buffer reached PAGE_SIZE\n");\
121421 + n = PAGE_SIZE - 2; \
121422 + }
121423 +
121424 +#define FM_DMP_LN(buf, n, ...) \
121425 + do { \
121426 + int k, m = n; \
121427 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
121428 + if (k < 0 || m > PAGE_SIZE - 90) \
121429 + FM_DMP_PGSZ_ERR \
121430 + n = m; \
121431 + } while (0)
121432 +
121433 +#define FM_DMP_TITLE(buf, n, addr, ...) \
121434 + do { \
121435 + int k, m = n; \
121436 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
121437 + if (k < 0 || m > PAGE_SIZE - 90) \
121438 + FM_DMP_PGSZ_ERR \
121439 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
121440 + if (k < 0 || m > PAGE_SIZE - 90) \
121441 + FM_DMP_PGSZ_ERR \
121442 + if (addr) { \
121443 + phys_addr_t pa; \
121444 + pa = virt_to_phys(addr); \
121445 + m += k = \
121446 + snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \
121447 + (long unsigned int)(pa)); \
121448 + if (k < 0 || m > PAGE_SIZE - 90) \
121449 + FM_DMP_PGSZ_ERR \
121450 + } \
121451 + m += k = snprintf(&buf[m], PAGE_SIZE - m, \
121452 + "\n----------------------------------------\n\n"); \
121453 + if (k < 0 || m > PAGE_SIZE - 90) \
121454 + FM_DMP_PGSZ_ERR \
121455 + n = m; \
121456 + } while (0)
121457 +
121458 +#define FM_DMP_SUBTITLE(buf, n, ...) \
121459 + do { \
121460 + int k, m = n; \
121461 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \
121462 + if (k < 0 || m > PAGE_SIZE - 90) \
121463 + FM_DMP_PGSZ_ERR \
121464 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
121465 + if (k < 0 || m > PAGE_SIZE - 90) \
121466 + FM_DMP_PGSZ_ERR \
121467 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
121468 + if (k < 0 || m > PAGE_SIZE - 90) \
121469 + FM_DMP_PGSZ_ERR \
121470 + n = m; \
121471 + } while (0)
121472 +
121473 +#define FM_DMP_MEM_32(buf, n, addr) \
121474 + { \
121475 + uint32_t val; \
121476 + phys_addr_t pa; \
121477 + int k, m = n; \
121478 + pa = virt_to_phys(addr); \
121479 + val = ioread32be((addr)); \
121480 + do { \
121481 + m += k = snprintf(&buf[m], \
121482 + PAGE_SIZE - m, "0x%010llX: 0x%08x\n", \
121483 + pa, val); \
121484 + if (k < 0 || m > PAGE_SIZE - 90) \
121485 + FM_DMP_PGSZ_ERR \
121486 + n += k; \
121487 + } while (0) ;\
121488 + }
121489 +
121490 +#define FM_DMP_V32(buf, n, st, phrase) \
121491 + do { \
121492 + int k, m = n; \
121493 + phys_addr_t pa = virt_to_phys(&((st)->phrase)); \
121494 + k = snprintf(&buf[m], PAGE_SIZE - m, \
121495 + "0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \
121496 + ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \
121497 + if (k < 0 || m > PAGE_SIZE - 90) \
121498 + FM_DMP_PGSZ_ERR \
121499 + n += k; \
121500 + } while (0)
121501 +
121502 +#endif /* LNXWRP_SYSFS_FM_H_ */
121503 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
121504 new file mode 100644
121505 index 00000000..db8e824c
121506 --- /dev/null
121507 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
121508 @@ -0,0 +1,1268 @@
121509 +/*
121510 + * Copyright 2008-2012 Freescale Semiconductor Inc.
121511 + *
121512 + * Redistribution and use in source and binary forms, with or without
121513 + * modification, are permitted provided that the following conditions are met:
121514 + * * Redistributions of source code must retain the above copyright
121515 + * notice, this list of conditions and the following disclaimer.
121516 + * * Redistributions in binary form must reproduce the above copyright
121517 + * notice, this list of conditions and the following disclaimer in the
121518 + * documentation and/or other materials provided with the distribution.
121519 + * * Neither the name of Freescale Semiconductor nor the
121520 + * names of its contributors may be used to endorse or promote products
121521 + * derived from this software without specific prior written permission.
121522 + *
121523 + *
121524 + * ALTERNATIVELY, this software may be distributed under the terms of the
121525 + * GNU General Public License ("GPL") as published by the Free Software
121526 + * Foundation, either version 2 of that License or (at your option) any
121527 + * later version.
121528 + *
121529 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
121530 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
121531 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
121532 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
121533 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
121534 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
121535 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
121536 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
121537 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
121538 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
121539 + */
121540 +
121541 +#include "lnxwrp_sysfs.h"
121542 +#include "lnxwrp_fm.h"
121543 +#include "debug_ext.h"
121544 +#include "lnxwrp_sysfs_fm_port.h"
121545 +#include "lnxwrp_sysfs_fm.h"
121546 +
121547 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port.h"
121548 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h"
121549 +
121550 +#if defined(__ERR_MODULE__)
121551 +#undef __ERR_MODULE__
121552 +#endif
121553 +
121554 +#include "../../sdk_fman/Peripherals/FM/fm.h"
121555 +
121556 +static const struct sysfs_stats_t portSysfsStats[] = {
121557 + /* RX/TX/OH common statistics */
121558 + {
121559 + .stat_name = "port_frame",
121560 + .stat_counter = e_FM_PORT_COUNTERS_FRAME,
121561 + },
121562 + {
121563 + .stat_name = "port_discard_frame",
121564 + .stat_counter = e_FM_PORT_COUNTERS_DISCARD_FRAME,
121565 + },
121566 + {
121567 + .stat_name = "port_dealloc_buf",
121568 + .stat_counter = e_FM_PORT_COUNTERS_DEALLOC_BUF,
121569 + },
121570 + {
121571 + .stat_name = "port_enq_total",
121572 + .stat_counter = e_FM_PORT_COUNTERS_ENQ_TOTAL,
121573 + },
121574 + /* TX/OH */
121575 + {
121576 + .stat_name = "port_length_err",
121577 + .stat_counter = e_FM_PORT_COUNTERS_LENGTH_ERR,
121578 + },
121579 + {
121580 + .stat_name = "port_unsupprted_format",
121581 + .stat_counter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT,
121582 + },
121583 + {
121584 + .stat_name = "port_deq_total",
121585 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_TOTAL,
121586 + },
121587 + {
121588 + .stat_name = "port_deq_from_default",
121589 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT,
121590 + },
121591 + {
121592 + .stat_name = "port_deq_confirm",
121593 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_CONFIRM,
121594 + },
121595 + /* RX/OH */
121596 + {
121597 + .stat_name = "port_rx_bad_frame",
121598 + .stat_counter = e_FM_PORT_COUNTERS_RX_BAD_FRAME,
121599 + },
121600 + {
121601 + .stat_name = "port_rx_large_frame",
121602 + .stat_counter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME,
121603 + },
121604 + {
121605 + .stat_name = "port_rx_out_of_buffers_discard",
121606 + .stat_counter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD,
121607 + },
121608 + {
121609 + .stat_name = "port_rx_filter_frame",
121610 + .stat_counter = e_FM_PORT_COUNTERS_RX_FILTER_FRAME,
121611 + },
121612 + /* TODO: Particular statistics for OH ports */
121613 + {}
121614 +};
121615 +
121616 +static ssize_t show_fm_port_stats(struct device *dev,
121617 + struct device_attribute *attr, char *buf)
121618 +{
121619 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121620 + t_LnxWrpFmDev *p_LnxWrpFmDev;
121621 + unsigned long flags;
121622 + int n = 0;
121623 + uint8_t counter = 0;
121624 +
121625 + if (attr == NULL || buf == NULL || dev == NULL)
121626 + return -EINVAL;
121627 +
121628 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121629 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121630 + return -EINVAL;
121631 +
121632 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
121633 + if (WARN_ON(p_LnxWrpFmDev == NULL))
121634 + return -EINVAL;
121635 +
121636 + if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev)
121637 + return -EIO;
121638 +
121639 + if (!p_LnxWrpFmPortDev->h_Dev) {
121640 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121641 + return n;
121642 + }
121643 +
121644 + counter = fm_find_statistic_counter_by_name(
121645 + attr->attr.name,
121646 + portSysfsStats, NULL);
121647 +
121648 + if (counter == e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR) {
121649 + uint32_t fmRev = 0;
121650 + fmRev = 0xffff &
121651 + ioread32(UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr +
121652 + 0x000c30c4));
121653 +
121654 + if (fmRev == 0x0100) {
121655 + local_irq_save(flags);
121656 + n = snprintf(buf, PAGE_SIZE,
121657 + "counter not available for revision 1\n");
121658 + local_irq_restore(flags);
121659 + }
121660 + return n;
121661 + }
121662 +
121663 + local_irq_save(flags);
121664 + n = snprintf(buf, PAGE_SIZE, "\t%s counter: %u\n",
121665 + p_LnxWrpFmPortDev->name,
121666 + FM_PORT_GetCounter(p_LnxWrpFmPortDev->h_Dev,
121667 + (e_FmPortCounters) counter));
121668 + local_irq_restore(flags);
121669 +
121670 + return n;
121671 +}
121672 +
121673 +/* FM PORT RX/TX/OH statistics */
121674 +static DEVICE_ATTR(port_frame, S_IRUGO, show_fm_port_stats, NULL);
121675 +static DEVICE_ATTR(port_discard_frame, S_IRUGO, show_fm_port_stats, NULL);
121676 +static DEVICE_ATTR(port_dealloc_buf, S_IRUGO, show_fm_port_stats, NULL);
121677 +static DEVICE_ATTR(port_enq_total, S_IRUGO, show_fm_port_stats, NULL);
121678 +/* FM PORT TX/OH statistics */
121679 +static DEVICE_ATTR(port_length_err, S_IRUGO, show_fm_port_stats, NULL);
121680 +static DEVICE_ATTR(port_unsupprted_format, S_IRUGO, show_fm_port_stats, NULL);
121681 +static DEVICE_ATTR(port_deq_total, S_IRUGO, show_fm_port_stats, NULL);
121682 +static DEVICE_ATTR(port_deq_from_default, S_IRUGO, show_fm_port_stats, NULL);
121683 +static DEVICE_ATTR(port_deq_confirm, S_IRUGO, show_fm_port_stats, NULL);
121684 +/* FM PORT RX/OH statistics */
121685 +static DEVICE_ATTR(port_rx_bad_frame, S_IRUGO, show_fm_port_stats, NULL);
121686 +static DEVICE_ATTR(port_rx_large_frame, S_IRUGO, show_fm_port_stats, NULL);
121687 +static DEVICE_ATTR(port_rx_out_of_buffers_discard, S_IRUGO,
121688 + show_fm_port_stats, NULL);
121689 +static DEVICE_ATTR(port_rx_filter_frame, S_IRUGO, show_fm_port_stats, NULL);
121690 +
121691 +/* FM PORT TX statistics */
121692 +static struct attribute *fm_tx_port_dev_stats_attributes[] = {
121693 + &dev_attr_port_frame.attr,
121694 + &dev_attr_port_discard_frame.attr,
121695 + &dev_attr_port_dealloc_buf.attr,
121696 + &dev_attr_port_enq_total.attr,
121697 + &dev_attr_port_length_err.attr,
121698 + &dev_attr_port_unsupprted_format.attr,
121699 + &dev_attr_port_deq_total.attr,
121700 + &dev_attr_port_deq_from_default.attr,
121701 + &dev_attr_port_deq_confirm.attr,
121702 + NULL
121703 +};
121704 +
121705 +static const struct attribute_group fm_tx_port_dev_stats_attr_grp = {
121706 + .name = "statistics",
121707 + .attrs = fm_tx_port_dev_stats_attributes
121708 +};
121709 +
121710 +/* FM PORT RX statistics */
121711 +static struct attribute *fm_rx_port_dev_stats_attributes[] = {
121712 + &dev_attr_port_frame.attr,
121713 + &dev_attr_port_discard_frame.attr,
121714 + &dev_attr_port_dealloc_buf.attr,
121715 + &dev_attr_port_enq_total.attr,
121716 + &dev_attr_port_rx_bad_frame.attr,
121717 + &dev_attr_port_rx_large_frame.attr,
121718 + &dev_attr_port_rx_out_of_buffers_discard.attr,
121719 + &dev_attr_port_rx_filter_frame.attr,
121720 + NULL
121721 +};
121722 +
121723 +static const struct attribute_group fm_rx_port_dev_stats_attr_grp = {
121724 + .name = "statistics",
121725 + .attrs = fm_rx_port_dev_stats_attributes
121726 +};
121727 +
121728 +/* TODO: add particular OH ports statistics */
121729 +static struct attribute *fm_oh_port_dev_stats_attributes[] = {
121730 + &dev_attr_port_frame.attr,
121731 + &dev_attr_port_discard_frame.attr,
121732 + &dev_attr_port_dealloc_buf.attr,
121733 + &dev_attr_port_enq_total.attr,
121734 + /*TX*/ &dev_attr_port_length_err.attr,
121735 + &dev_attr_port_unsupprted_format.attr,
121736 + &dev_attr_port_deq_total.attr,
121737 + &dev_attr_port_deq_from_default.attr,
121738 + &dev_attr_port_deq_confirm.attr,
121739 + /* &dev_attr_port_rx_bad_frame.attr, */
121740 + /* &dev_attr_port_rx_large_frame.attr, */
121741 + &dev_attr_port_rx_out_of_buffers_discard.attr,
121742 + /*&dev_attr_port_rx_filter_frame.attr, */
121743 + NULL
121744 +};
121745 +
121746 +static const struct attribute_group fm_oh_port_dev_stats_attr_grp = {
121747 + .name = "statistics",
121748 + .attrs = fm_oh_port_dev_stats_attributes
121749 +};
121750 +
121751 +static ssize_t show_fm_port_regs(struct device *dev,
121752 + struct device_attribute *attr, char *buf)
121753 +{
121754 + unsigned long flags;
121755 + unsigned n = 0;
121756 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121757 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121758 +#endif
121759 + if (attr == NULL || buf == NULL || dev == NULL)
121760 + return -EINVAL;
121761 +
121762 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121763 + p_LnxWrpFmPortDev =
121764 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121765 +
121766 +
121767 + local_irq_save(flags);
121768 +
121769 + if (!p_LnxWrpFmPortDev->h_Dev) {
121770 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121771 + return n;
121772 + } else {
121773 + n = snprintf(buf, PAGE_SIZE,
121774 + "FM port driver registers dump.\n");
121775 + n = fm_port_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
121776 + }
121777 +
121778 + local_irq_restore(flags);
121779 +
121780 + return n;
121781 +#else
121782 +
121783 + local_irq_save(flags);
121784 + n = snprintf(buf, PAGE_SIZE,
121785 + "Debug level is too low to dump registers!!!\n");
121786 + local_irq_restore(flags);
121787 +
121788 + return n;
121789 +#endif
121790 +}
121791 +static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
121792 +{
121793 + t_FmPort *p_FmPort;
121794 + t_Fm *p_Fm;
121795 + uint8_t hardwarePortId;
121796 + uint32_t *param_page;
121797 + t_ArCommonDesc *ArCommonDescPtr;
121798 + uint32_t *mem;
121799 + int i, n = nn;
121800 +
121801 + p_FmPort = (t_FmPort *)h_dev;
121802 + hardwarePortId = p_FmPort->hardwarePortId;
121803 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121804 +
121805 + if (!FM_PORT_IsInDsar(p_FmPort))
121806 + {
121807 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121808 + hardwarePortId);
121809 + return n;
121810 + }
121811 + FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId);
121812 + FM_DMP_LN(buf, n, "========================\n");
121813 +
121814 + /* do I need request_mem_region here? */
121815 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121816 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* this should be changed*/
121817 + mem = (uint32_t*)ArCommonDescPtr;
121818 + for (i = 0; i < 300; i+=4)
121819 + FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
121820 + iounmap(ArCommonDescPtr);
121821 + iounmap(param_page);
121822 + return n;
121823 +}
121824 +
121825 +static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn)
121826 +{
121827 + t_FmPort *p_FmPort;
121828 + t_Fm *p_Fm;
121829 + uint8_t hardwarePortId;
121830 + uint32_t *param_page;
121831 + t_ArCommonDesc *ArCommonDescPtr;
121832 + int i, n = nn;
121833 +
121834 + p_FmPort = (t_FmPort *)h_dev;
121835 + hardwarePortId = p_FmPort->hardwarePortId;
121836 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121837 +
121838 + if (!FM_PORT_IsInDsar(p_FmPort))
121839 + {
121840 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121841 + hardwarePortId);
121842 + return n;
121843 + }
121844 + FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId);
121845 + FM_DMP_LN(buf, n, "========================\n");
121846 +
121847 + /* do I need request_mem_region here? */
121848 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121849 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
121850 + FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort);
121851 + FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA);
121852 + FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort);
121853 + FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0],
121854 + ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2],
121855 + ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4],
121856 + ArCommonDescPtr->macStationAddr[5]);
121857 + FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl);
121858 + FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass);
121859 + FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize);
121860 + FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize);
121861 + FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize);
121862 + if (ArCommonDescPtr->p_ArStats)
121863 + {
121864 + t_ArStatistics *arStatistics = (t_ArStatistics*)
121865 + ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) +
121866 + p_FmPort->fmMuramPhysBaseAddr,
121867 + sizeof (t_ArStatistics));
121868 + FM_DMP_LN(buf, n, "\nDSAR statistics\n");
121869 + FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded);
121870 + FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded);
121871 + FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded);
121872 + FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded);
121873 + FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded);
121874 + FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded);
121875 + FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded);
121876 + FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded);
121877 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr);
121878 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType);
121879 + FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType);
121880 +
121881 + iounmap(arStatistics);
121882 + }
121883 + if (ArCommonDescPtr->p_ArpDescriptor)
121884 + {
121885 + t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*)
121886 + ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) +
121887 + p_FmPort->fmMuramPhysBaseAddr,
121888 + sizeof (t_DsarArpDescriptor));
121889 + FM_DMP_LN(buf, n, "\nARP\n");
121890 + FM_DMP_LN(buf, n, "===\n");
121891 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control);
121892 + if (ArpDescriptor->numOfBindings)
121893 + {
121894 + char ip_str[100];
121895 + t_DsarArpBindingEntry* bindings = ioremap(
121896 + ioread32be(&ArpDescriptor->p_Bindings) +
121897 + p_FmPort->fmMuramPhysBaseAddr,
121898 + ArpDescriptor->numOfBindings *
121899 + sizeof(t_DsarArpBindingEntry));
121900 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121901 + FM_DMP_LN(buf, n, " ip vlan id\n");
121902 + for (i = 0; i < ArpDescriptor->numOfBindings; i++)
121903 + {
121904 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121905 + ip_addr[0], ip_addr[1],
121906 + ip_addr[2], ip_addr[3]);
121907 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121908 + ip_str, bindings->vlanId);
121909 + }
121910 + iounmap(bindings);
121911 + }
121912 + if (ArpDescriptor->p_Statistics)
121913 + {
121914 + t_DsarArpStatistics* arpStats = ioremap(
121915 + ioread32be(&ArpDescriptor->p_Statistics) +
121916 + p_FmPort->fmMuramPhysBaseAddr,
121917 + sizeof(t_DsarArpStatistics));
121918 + FM_DMP_LN(buf, n, "statistics\n");
121919 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt);
121920 + FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt);
121921 + FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt);
121922 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt);
121923 + FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt);
121924 + FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt);
121925 + FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt);
121926 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt);
121927 + iounmap(arpStats);
121928 + }
121929 +
121930 + iounmap(ArpDescriptor);
121931 + }
121932 + if (ArCommonDescPtr->p_IcmpV4Descriptor)
121933 + {
121934 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor =
121935 + (t_DsarIcmpV4Descriptor*)ioremap(ioread32be(
121936 + &ArCommonDescPtr->p_IcmpV4Descriptor) +
121937 + p_FmPort->fmMuramPhysBaseAddr,
121938 + sizeof (t_DsarIcmpV4Descriptor));
121939 + FM_DMP_LN(buf, n, "\nEcho ICMPv4\n");
121940 + FM_DMP_LN(buf, n, "===========\n");
121941 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control);
121942 + if (ICMPV4Descriptor->numOfBindings)
121943 + {
121944 + char ip_str[100];
121945 + t_DsarArpBindingEntry* bindings = ioremap(
121946 + ioread32be(&ICMPV4Descriptor->p_Bindings) +
121947 + p_FmPort->fmMuramPhysBaseAddr,
121948 + ICMPV4Descriptor->numOfBindings *
121949 + sizeof(t_DsarArpBindingEntry));
121950 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121951 + FM_DMP_LN(buf, n, " ip vlan id\n");
121952 + for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++)
121953 + {
121954 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121955 + ip_addr[0], ip_addr[1],
121956 + ip_addr[2], ip_addr[3]);
121957 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121958 + ip_str, bindings->vlanId);
121959 + }
121960 + iounmap(bindings);
121961 + }
121962 + if (ICMPV4Descriptor->p_Statistics)
121963 + {
121964 + t_DsarIcmpV4Statistics* icmpv4Stats = ioremap(
121965 + ioread32be(&ICMPV4Descriptor->p_Statistics) +
121966 + p_FmPort->fmMuramPhysBaseAddr,
121967 + sizeof(t_DsarIcmpV4Statistics));
121968 + FM_DMP_LN(buf, n, "statistics\n");
121969 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt);
121970 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt);
121971 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt);
121972 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt);
121973 + FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt);
121974 + iounmap(icmpv4Stats);
121975 + }
121976 + iounmap(ICMPV4Descriptor);
121977 + }
121978 + if (ArCommonDescPtr->p_NdDescriptor)
121979 + {
121980 + t_DsarNdDescriptor *NDDescriptor =
121981 + (t_DsarNdDescriptor*)ioremap(ioread32be(
121982 + &ArCommonDescPtr->p_NdDescriptor) + p_FmPort->
121983 + fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor));
121984 + FM_DMP_LN(buf, n, "\nNDP\n");
121985 + FM_DMP_LN(buf, n, "===\n");
121986 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control);
121987 + FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr);
121988 + if (NDDescriptor->numOfBindings)
121989 + {
121990 + char ip_str[100];
121991 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121992 + ioread32be(&NDDescriptor->p_Bindings) +
121993 + p_FmPort->fmMuramPhysBaseAddr,
121994 + NDDescriptor->numOfBindings *
121995 + sizeof(t_DsarIcmpV6BindingEntry));
121996 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121997 + FM_DMP_LN(buf, n, " ip vlan id\n");
121998 + for (i = 0; i < NDDescriptor->numOfBindings; i++)
121999 + {
122000 + n += snprintf(ip_str, 100,
122001 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
122002 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
122003 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
122004 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
122005 + }
122006 + iounmap(bindings);
122007 + }
122008 + if (NDDescriptor->p_Statistics)
122009 + {
122010 + t_NdStatistics* ndStats = ioremap(
122011 + ioread32be(&NDDescriptor->p_Statistics) +
122012 + p_FmPort->fmMuramPhysBaseAddr,
122013 + sizeof(t_NdStatistics));
122014 + FM_DMP_LN(buf, n, "statistics\n");
122015 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt);
122016 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt);
122017 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt);
122018 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt);
122019 + FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt);
122020 + FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt);
122021 + FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt);
122022 + iounmap(ndStats);
122023 + }
122024 + iounmap(NDDescriptor);
122025 + }
122026 + if (ArCommonDescPtr->p_IcmpV6Descriptor)
122027 + {
122028 + t_DsarIcmpV6Descriptor *ICMPV6Descriptor =
122029 + (t_DsarIcmpV6Descriptor*)ioremap(ioread32be(
122030 + &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort->
122031 + fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor));
122032 + FM_DMP_LN(buf, n, "\nEcho ICMPv6\n");
122033 + FM_DMP_LN(buf, n, "===========\n");
122034 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control);
122035 + if (ICMPV6Descriptor->numOfBindings)
122036 + {
122037 + char ip_str[100];
122038 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
122039 + ioread32be(&ICMPV6Descriptor->p_Bindings) +
122040 + p_FmPort->fmMuramPhysBaseAddr,
122041 + ICMPV6Descriptor->numOfBindings *
122042 + sizeof(t_DsarIcmpV6BindingEntry));
122043 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
122044 + FM_DMP_LN(buf, n, " ip vlan id\n");
122045 + for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++)
122046 + {
122047 + n += snprintf(ip_str, 100,
122048 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
122049 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
122050 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
122051 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
122052 + }
122053 + iounmap(bindings);
122054 + }
122055 + if (ICMPV6Descriptor->p_Statistics)
122056 + {
122057 + t_DsarIcmpV6Statistics* icmpv6Stats = ioremap(
122058 + ioread32be(&ICMPV6Descriptor->p_Statistics) +
122059 + p_FmPort->fmMuramPhysBaseAddr,
122060 + sizeof(t_DsarIcmpV6Statistics));
122061 + FM_DMP_LN(buf, n, "statistics\n");
122062 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt);
122063 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt);
122064 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt);
122065 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt);
122066 + iounmap(icmpv6Stats);
122067 + }
122068 + iounmap(ICMPV6Descriptor);
122069 + }
122070 + if (ArCommonDescPtr->p_SnmpDescriptor)
122071 + {
122072 + t_DsarSnmpDescriptor *SnmpDescriptor =
122073 + (t_DsarSnmpDescriptor*)ioremap(ioread32be(
122074 + &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort->
122075 + fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor));
122076 + FM_DMP_LN(buf, n, "\nSNMP\n");
122077 + FM_DMP_LN(buf, n, "===========\n");
122078 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control);
122079 + FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength);
122080 + if (SnmpDescriptor->numOfIpv4Addresses)
122081 + {
122082 + char ip_str[100];
122083 + t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap(
122084 + ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) +
122085 + p_FmPort->fmMuramPhysBaseAddr,
122086 + SnmpDescriptor->numOfIpv4Addresses *
122087 + sizeof(t_DsarSnmpIpv4AddrTblEntry));
122088 + uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr;
122089 + FM_DMP_LN(buf, n, " ip vlan id\n");
122090 + for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++)
122091 + {
122092 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
122093 + ip_addr[0], ip_addr[1],
122094 + ip_addr[2], ip_addr[3]);
122095 + FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId);
122096 + }
122097 + iounmap(addrs);
122098 + }
122099 + if (SnmpDescriptor->p_Statistics)
122100 + {
122101 + t_DsarSnmpStatistics* snmpStats = ioremap(
122102 + ioread32be(&SnmpDescriptor->p_Statistics) +
122103 + p_FmPort->fmMuramPhysBaseAddr,
122104 + sizeof(t_DsarSnmpStatistics));
122105 + FM_DMP_LN(buf, n, "statistics\n");
122106 + FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt);
122107 + FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt);
122108 + FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt);
122109 + FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt);
122110 + FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt);
122111 + iounmap(snmpStats);
122112 + }
122113 + iounmap(SnmpDescriptor);
122114 + }
122115 + iounmap(ArCommonDescPtr);
122116 + iounmap(param_page);
122117 + return n;
122118 +}
122119 +
122120 +static ssize_t show_fm_port_dsar_mem(struct device *dev,
122121 + struct device_attribute *attr, char *buf)
122122 +{
122123 + unsigned long flags;
122124 + unsigned n = 0;
122125 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122126 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122127 +#endif
122128 + if (attr == NULL || buf == NULL || dev == NULL)
122129 + return -EINVAL;
122130 +
122131 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122132 + p_LnxWrpFmPortDev =
122133 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122134 +
122135 + local_irq_save(flags);
122136 +
122137 + if (!p_LnxWrpFmPortDev->h_Dev) {
122138 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122139 + return n;
122140 + } else {
122141 + n = snprintf(buf, PAGE_SIZE,
122142 + "FM port driver registers dump.\n");
122143 + n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n);
122144 + }
122145 +
122146 + local_irq_restore(flags);
122147 +
122148 + return n;
122149 +#else
122150 +
122151 + local_irq_save(flags);
122152 + n = snprintf(buf, PAGE_SIZE,
122153 + "Debug level is too low to dump registers!!!\n");
122154 + local_irq_restore(flags);
122155 +
122156 + return n;
122157 +#endif
122158 +}
122159 +
122160 +static ssize_t show_fm_port_dsar_regs(struct device *dev,
122161 + struct device_attribute *attr, char *buf)
122162 +{
122163 + unsigned long flags;
122164 + unsigned n = 0;
122165 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122166 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122167 +#endif
122168 + if (attr == NULL || buf == NULL || dev == NULL)
122169 + return -EINVAL;
122170 +
122171 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122172 + p_LnxWrpFmPortDev =
122173 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122174 +
122175 + local_irq_save(flags);
122176 +
122177 + if (!p_LnxWrpFmPortDev->h_Dev) {
122178 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122179 + return n;
122180 + } else {
122181 + n = snprintf(buf, PAGE_SIZE,
122182 + "FM port driver registers dump.\n");
122183 + n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
122184 + }
122185 +
122186 + local_irq_restore(flags);
122187 +
122188 + return n;
122189 +#else
122190 +
122191 + local_irq_save(flags);
122192 + n = snprintf(buf, PAGE_SIZE,
122193 + "Debug level is too low to dump registers!!!\n");
122194 + local_irq_restore(flags);
122195 +
122196 + return n;
122197 +#endif
122198 +}
122199 +
122200 +#if (DPAA_VERSION >= 11)
122201 +static ssize_t show_fm_port_ipv4_options(struct device *dev,
122202 + struct device_attribute *attr, char *buf)
122203 +{
122204 + unsigned long flags;
122205 + unsigned n = 0;
122206 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122207 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122208 +#endif
122209 +
122210 + if (attr == NULL || buf == NULL || dev == NULL)
122211 + return -EINVAL;
122212 +
122213 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122214 + p_LnxWrpFmPortDev =
122215 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122216 +
122217 + local_irq_save(flags);
122218 +
122219 + if (!p_LnxWrpFmPortDev->h_Dev) {
122220 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122221 + return n;
122222 + } else if (((t_FmPort *)p_LnxWrpFmPortDev->h_Dev)->p_ParamsPage
122223 + == NULL) {
122224 + n = snprintf(buf, PAGE_SIZE,
122225 + "\tPort: FMan-controller params page not set\n");
122226 + return n;
122227 + } else {
122228 + n = snprintf(buf, PAGE_SIZE,
122229 + "Counter for fragmented pkt with IP header options\n");
122230 + n = fm_port_dump_ipv4_opt(p_LnxWrpFmPortDev->h_Dev, buf, n);
122231 + }
122232 +
122233 + local_irq_restore(flags);
122234 +
122235 + return n;
122236 +#else
122237 +
122238 + local_irq_save(flags);
122239 + n = snprintf(buf, PAGE_SIZE,
122240 + "Debug level is too low to dump registers!!!\n");
122241 + local_irq_restore(flags);
122242 +
122243 + return n;
122244 +#endif
122245 +}
122246 +
122247 +#endif
122248 +
122249 +static ssize_t show_fm_port_bmi_regs(struct device *dev,
122250 + struct device_attribute *attr, char *buf)
122251 +{
122252 + unsigned long flags;
122253 + unsigned n = 0;
122254 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122255 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122256 +#endif
122257 +
122258 + if (attr == NULL || buf == NULL || dev == NULL)
122259 + return -EINVAL;
122260 +
122261 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122262 + p_LnxWrpFmPortDev =
122263 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122264 +
122265 + local_irq_save(flags);
122266 +
122267 + if (!p_LnxWrpFmPortDev->h_Dev) {
122268 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122269 + return n;
122270 + } else {
122271 + n = snprintf(buf, PAGE_SIZE,
122272 + "FM port driver registers dump.\n");
122273 + n = fm_port_dump_regs_bmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
122274 + }
122275 +
122276 + local_irq_restore(flags);
122277 +
122278 + return n;
122279 +#else
122280 +
122281 + local_irq_save(flags);
122282 + n = snprintf(buf, PAGE_SIZE,
122283 + "Debug level is too low to dump registers!!!\n");
122284 + local_irq_restore(flags);
122285 +
122286 + return n;
122287 +#endif
122288 +}
122289 +
122290 +static ssize_t show_fm_port_qmi_regs(struct device *dev,
122291 + struct device_attribute *attr, char *buf)
122292 +{
122293 + unsigned long flags;
122294 + unsigned n = 0;
122295 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122296 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122297 +#endif
122298 +
122299 + if (attr == NULL || buf == NULL || dev == NULL)
122300 + return -EINVAL;
122301 +
122302 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122303 + p_LnxWrpFmPortDev =
122304 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122305 +
122306 + local_irq_save(flags);
122307 +
122308 + if (!p_LnxWrpFmPortDev->h_Dev) {
122309 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122310 + return n;
122311 + } else {
122312 + n = snprintf(buf, PAGE_SIZE,
122313 + "FM port driver registers dump.\n");
122314 + n = fm_port_dump_regs_qmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
122315 + }
122316 +
122317 + local_irq_restore(flags);
122318 +
122319 + return n;
122320 +#else
122321 +
122322 + local_irq_save(flags);
122323 + n = snprintf(buf, PAGE_SIZE,
122324 + "Debug level is too low to dump registers!!!\n");
122325 + local_irq_restore(flags);
122326 +
122327 + return n;
122328 +#endif
122329 +}
122330 +
122331 +static DEVICE_ATTR(fm_port_regs, S_IRUGO | S_IRUSR, show_fm_port_regs, NULL);
122332 +static DEVICE_ATTR(fm_port_qmi_regs, S_IRUGO | S_IRUSR, show_fm_port_qmi_regs, NULL);
122333 +static DEVICE_ATTR(fm_port_bmi_regs, S_IRUGO | S_IRUSR, show_fm_port_bmi_regs, NULL);
122334 +#if (DPAA_VERSION >= 11)
122335 +static DEVICE_ATTR(fm_port_ipv4_opt, S_IRUGO | S_IRUSR, show_fm_port_ipv4_options, NULL);
122336 +#endif
122337 +static DEVICE_ATTR(fm_port_dsar_regs, S_IRUGO | S_IRUSR, show_fm_port_dsar_regs, NULL);
122338 +static DEVICE_ATTR(fm_port_dsar_mem, S_IRUGO | S_IRUSR, show_fm_port_dsar_mem, NULL);
122339 +
122340 +int fm_port_sysfs_create(struct device *dev)
122341 +{
122342 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122343 +
122344 + if (dev == NULL)
122345 + return -EINVAL;
122346 +
122347 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122348 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
122349 + return -EINVAL;
122350 +
122351 + /* store to remove them when module is disabled */
122352 + p_LnxWrpFmPortDev->dev_attr_regs = &dev_attr_fm_port_regs;
122353 + p_LnxWrpFmPortDev->dev_attr_qmi_regs = &dev_attr_fm_port_qmi_regs;
122354 + p_LnxWrpFmPortDev->dev_attr_bmi_regs = &dev_attr_fm_port_bmi_regs;
122355 +#if (DPAA_VERSION >= 11)
122356 + p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt;
122357 +#endif
122358 + p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs;
122359 + p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem;
122360 + /* Registers dump entry - in future will be moved to debugfs */
122361 + if (device_create_file(dev, &dev_attr_fm_port_regs) != 0)
122362 + return -EIO;
122363 + if (device_create_file(dev, &dev_attr_fm_port_qmi_regs) != 0)
122364 + return -EIO;
122365 + if (device_create_file(dev, &dev_attr_fm_port_bmi_regs) != 0)
122366 + return -EIO;
122367 +#if (DPAA_VERSION >= 11)
122368 + if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0)
122369 + return -EIO;
122370 +#endif
122371 + if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0)
122372 + return -EIO;
122373 + if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0)
122374 + return -EIO;
122375 +
122376 + /* FM Ports statistics */
122377 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
122378 + case e_FM_PORT_TYPE_TX:
122379 + case e_FM_PORT_TYPE_TX_10G:
122380 + if (sysfs_create_group
122381 + (&dev->kobj, &fm_tx_port_dev_stats_attr_grp) != 0)
122382 + return -EIO;
122383 + break;
122384 + case e_FM_PORT_TYPE_RX:
122385 + case e_FM_PORT_TYPE_RX_10G:
122386 + if (sysfs_create_group
122387 + (&dev->kobj, &fm_rx_port_dev_stats_attr_grp) != 0)
122388 + return -EIO;
122389 + break;
122390 + case e_FM_PORT_TYPE_DUMMY:
122391 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
122392 + if (sysfs_create_group
122393 + (&dev->kobj, &fm_oh_port_dev_stats_attr_grp) != 0)
122394 + return -EIO;
122395 + break;
122396 + default:
122397 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
122398 + __func__);
122399 + return -EINVAL;
122400 + break;
122401 + };
122402 +
122403 + return 0;
122404 +}
122405 +
122406 +void fm_port_sysfs_destroy(struct device *dev)
122407 +{
122408 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
122409 +
122410 + /* this function has never been tested !!! */
122411 +
122412 + if (WARN_ON(dev == NULL))
122413 + return;
122414 +
122415 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122416 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
122417 + return;
122418 +
122419 + /* The name attribute will be freed also by these 2 functions? */
122420 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
122421 + case e_FM_PORT_TYPE_TX:
122422 + case e_FM_PORT_TYPE_TX_10G:
122423 + sysfs_remove_group(&dev->kobj, &fm_tx_port_dev_stats_attr_grp);
122424 + break;
122425 + case e_FM_PORT_TYPE_RX:
122426 + case e_FM_PORT_TYPE_RX_10G:
122427 + sysfs_remove_group(&dev->kobj, &fm_rx_port_dev_stats_attr_grp);
122428 + break;
122429 + case e_FM_PORT_TYPE_DUMMY:
122430 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
122431 + sysfs_remove_group(&dev->kobj, &fm_oh_port_dev_stats_attr_grp);
122432 + break;
122433 + default:
122434 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
122435 + __func__);
122436 + break;
122437 + };
122438 +
122439 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_regs);
122440 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_qmi_regs);
122441 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_bmi_regs);
122442 +#if (DPAA_VERSION >= 11)
122443 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt);
122444 +#endif
122445 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs);
122446 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem);
122447 +}
122448 +
122449 +
122450 +int fm_port_dump_regs(void *h_dev, char *buf, int nn)
122451 +{
122452 + t_FmPort *p_FmPort;
122453 + t_Fm *p_Fm;
122454 + uint8_t hardwarePortId;
122455 + int n = nn;
122456 +
122457 + p_FmPort = (t_FmPort *)h_dev;
122458 + hardwarePortId = p_FmPort->hardwarePortId;
122459 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
122460 +
122461 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1],
122462 + "fmbm_pp for port %u", hardwarePortId);
122463 + FM_DMP_MEM_32(buf, n,
122464 + &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1]);
122465 +
122466 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1],
122467 + "fmbm_pfs for port %u", hardwarePortId);
122468 + FM_DMP_MEM_32(buf, n,
122469 + &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1]);
122470 +
122471 + FM_DMP_TITLE(buf, n,
122472 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1],
122473 + "fmbm_spliodn for port %u", hardwarePortId);
122474 + FM_DMP_MEM_32(buf, n,
122475 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1]);
122476 +
122477 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId],
122478 + "fmfp_psfor port %u", hardwarePortId);
122479 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
122480 +
122481 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2],
122482 + "fmdmplrfor port %u", hardwarePortId);
122483 + FM_DMP_MEM_32(buf, n,
122484 + &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2]);
122485 + return n;
122486 +}
122487 +
122488 +#if (DPAA_VERSION >= 11)
122489 +
122490 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int nn)
122491 +{
122492 + t_FmPort *p_FmPort;
122493 + int n = nn;
122494 +
122495 + p_FmPort = (t_FmPort *)h_dev;
122496 +
122497 + FM_DMP_V32(buf, n, p_FmPort->p_ParamsPage, ipfOptionsCounter);
122498 +
122499 + FM_DMP_SUBTITLE(buf, n, "\n");
122500 +
122501 + return n;
122502 +}
122503 +#endif
122504 +
122505 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int nn)
122506 +{
122507 + t_FmPort *p_FmPort;
122508 + u_FmPortBmiRegs *p_bmi;
122509 +
122510 + char arr[20];
122511 + uint8_t flag;
122512 + int i = 0;
122513 + int n = nn;
122514 +
122515 + p_FmPort = (t_FmPort *)h_dev;
122516 + p_bmi = p_FmPort->p_FmPortBmiRegs;
122517 +
122518 + memset(arr, 0, sizeof(arr));
122519 + switch (p_FmPort->portType) {
122520 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
122521 + strcpy(arr, "OFFLINE-PARSING");
122522 + flag = 0;
122523 + break;
122524 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
122525 + strcpy(arr, "HOST-COMMAND");
122526 + flag = 0;
122527 + break;
122528 + case (e_FM_PORT_TYPE_RX):
122529 + strcpy(arr, "RX");
122530 + flag = 1;
122531 + break;
122532 + case (e_FM_PORT_TYPE_RX_10G):
122533 + strcpy(arr, "RX-10G");
122534 + flag = 1;
122535 + break;
122536 + case (e_FM_PORT_TYPE_TX):
122537 + strcpy(arr, "TX");
122538 + flag = 2;
122539 + break;
122540 + case (e_FM_PORT_TYPE_TX_10G):
122541 + strcpy(arr, "TX-10G");
122542 + flag = 2;
122543 + break;
122544 + default:
122545 + return -EINVAL;
122546 + }
122547 +
122548 + FM_DMP_TITLE(buf, n, NULL,
122549 + "FMan-Port (%s #%d) registers:",
122550 + arr, p_FmPort->portId);
122551 +
122552 + FM_DMP_TITLE(buf, n, p_bmi, "Bmi Port Regs");
122553 +
122554 + switch (flag) {
122555 + case (0):
122556 + FM_DMP_SUBTITLE(buf, n, "\n");
122557 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocfg);
122558 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ost);
122559 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oda);
122560 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oicp);
122561 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdne);
122562 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofne);
122563 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofca);
122564 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofpne);
122565 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opso);
122566 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opp);
122567 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occb);
122568 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oim);
122569 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofp);
122570 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofed);
122571 +
122572 + FM_DMP_TITLE(buf, n,
122573 + &(p_bmi->ohPortBmiRegs.fmbm_oprai), "fmbm_oprai");
122574 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
122575 + FM_DMP_MEM_32(buf, n,
122576 + &(p_bmi->ohPortBmiRegs.fmbm_oprai[i]));
122577 + }
122578 + FM_DMP_SUBTITLE(buf, n, "\n");
122579 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofqid);
122580 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oefqid);
122581 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsdm);
122582 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsem);
122583 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofene);
122584 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmts);
122585 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmt);
122586 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocmne);
122587 + {
122588 +#ifndef FM_NO_OP_OBSERVED_POOLS
122589 + if (p_FmPort->fmRevInfo.majorRev == 4) {
122590 + FM_DMP_TITLE(buf, n,
122591 + &p_bmi->ohPortBmiRegs.fmbm_oebmpi,
122592 + "fmbm_oebmpi");
122593 +
122594 + for (i = 0; i < FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS; ++i) {
122595 + FM_DMP_MEM_32(buf, n,
122596 + &(p_bmi->ohPortBmiRegs.fmbm_oebmpi[i]));
122597 + }
122598 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocgm);
122599 + }
122600 +#endif /* !FM_NO_OP_OBSERVED_POOLS */
122601 + }
122602 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ostc);
122603 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofrc);
122604 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdc);
122605 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofledc);
122606 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofufdc);
122607 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_offc);
122608 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofwdc);
122609 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofldec);
122610 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opc);
122611 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opcp);
122612 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occn);
122613 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_otuc);
122614 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oduc);
122615 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofuc);
122616 + FM_DMP_TITLE(buf, n, &(p_bmi->ohPortBmiRegs.fmbm_odcfg),
122617 + "fmbm_odcfg");
122618 + for (i = 0; i < 3; ++i) {
122619 + FM_DMP_MEM_32(buf, n,
122620 + &(p_bmi->ohPortBmiRegs.fmbm_odcfg[i]));
122621 + }
122622 + FM_DMP_SUBTITLE(buf, n, "\n");
122623 +
122624 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ogpr);
122625 + break;
122626 + case (1):
122627 + FM_DMP_SUBTITLE(buf, n, "\n");
122628 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcfg);
122629 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rst);
122630 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rda);
122631 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfp);
122632 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_reth);
122633 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfed);
122634 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_ricp);
122635 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rebm);
122636 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfne);
122637 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfca);
122638 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfpne);
122639 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpso);
122640 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpp);
122641 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rprai),
122642 + "fmbm_rprai");
122643 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
122644 + FM_DMP_MEM_32(buf, n,
122645 + &(p_bmi->rxPortBmiRegs.fmbm_rprai[i]));
122646 + }
122647 + FM_DMP_SUBTITLE(buf, n, "\n");
122648 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfqid);
122649 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_refqid);
122650 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsdm);
122651 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsem);
122652 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfene);
122653 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcmne);
122654 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_ebmpi,
122655 + "fmbm_ebmpi");
122656 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
122657 + FM_DMP_MEM_32(buf, n,
122658 + &(p_bmi->rxPortBmiRegs.fmbm_ebmpi[i]));
122659 + }
122660 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_acnt,
122661 + "fmbm_acnt");
122662 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
122663 + FM_DMP_MEM_32(buf, n,
122664 + &(p_bmi->rxPortBmiRegs.fmbm_acnt[i]));
122665 + }
122666 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_rcgm,
122667 + "fmbm_rcgm");
122668 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS / 32; ++i) {
122669 + FM_DMP_MEM_32(buf, n,
122670 + &(p_bmi->rxPortBmiRegs.fmbm_rcgm[i]));
122671 + }
122672 +
122673 + FM_DMP_SUBTITLE(buf, n, "\n");
122674 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rmpd);
122675 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rstc);
122676 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfrc);
122677 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfbc);
122678 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rlfc);
122679 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rffc);
122680 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfcd);
122681 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfldec);
122682 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rodc);
122683 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpc);
122684 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpcp);
122685 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rccn);
122686 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rtuc);
122687 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rrquc);
122688 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rduc);
122689 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfuc);
122690 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpac);
122691 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rdcfg),
122692 + "fmbm_rdcfg");
122693 + for (i = 0; i < 3; ++i) {
122694 + FM_DMP_MEM_32(buf, n,
122695 + &(p_bmi->rxPortBmiRegs.fmbm_rdcfg[i]));
122696 + }
122697 + FM_DMP_SUBTITLE(buf, n, "\n");
122698 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rgpr);
122699 + break;
122700 + case (2):
122701 + FM_DMP_SUBTITLE(buf, n, "\n");
122702 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfg);
122703 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tst);
122704 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tda);
122705 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfp);
122706 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfed);
122707 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ticp);
122708 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdne);
122709 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfca);
122710 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfqid);
122711 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfeqid);
122712 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfene);
122713 +#if (DPAA_VERSION >= 11)
122714 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfne);
122715 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcmne);
122716 +#endif /* (DPAA_VERSION >= 11) */
122717 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmts);
122718 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmt);
122719 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tstc);
122720 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfrc);
122721 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdc);
122722 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfledc);
122723 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfufdc);
122724 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpc);
122725 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpcp);
122726 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tccn);
122727 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttuc);
122728 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttcquc);
122729 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tduc);
122730 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfuc);
122731 + FM_DMP_TITLE(buf, n, &(p_bmi->txPortBmiRegs.fmbm_tdcfg),
122732 + "fmbm_tdcfg");
122733 + for (i = 0; i < 3 ; ++i) {
122734 + FM_DMP_MEM_32(buf, n,
122735 + &(p_bmi->txPortBmiRegs.fmbm_tdcfg[i]));
122736 + }
122737 + FM_DMP_SUBTITLE(buf, n, "\n");
122738 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tgpr);
122739 + break;
122740 + }
122741 +
122742 + FM_DMP_SUBTITLE(buf, n, "\n");
122743 +
122744 + return n;
122745 +}
122746 +
122747 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int nn)
122748 +{
122749 + t_FmPort *p_FmPort;
122750 + int n = nn;
122751 +
122752 + p_FmPort = (t_FmPort *)h_dev;
122753 +
122754 + FM_DMP_TITLE(buf, n, p_FmPort->p_FmPortQmiRegs, "Qmi Port Regs");
122755 +
122756 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnc);
122757 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pns);
122758 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnts);
122759 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnen);
122760 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnetfc);
122761 + FM_DMP_V32(buf, n,
122762 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndn);
122763 + FM_DMP_V32(buf, n,
122764 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndc);
122765 + FM_DMP_V32(buf, n,
122766 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndtfc);
122767 + FM_DMP_V32(buf, n,
122768 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndfdc);
122769 + FM_DMP_V32(buf, n,
122770 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndcc);
122771 +
122772 + FM_DMP_SUBTITLE(buf, n, "\n");
122773 +
122774 + return n;
122775 +}
122776 +
122777 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
122778 new file mode 100644
122779 index 00000000..1e7636f4
122780 --- /dev/null
122781 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
122782 @@ -0,0 +1,56 @@
122783 +/*
122784 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122785 + *
122786 + * Redistribution and use in source and binary forms, with or without
122787 + * modification, are permitted provided that the following conditions are met:
122788 + * * Redistributions of source code must retain the above copyright
122789 + * notice, this list of conditions and the following disclaimer.
122790 + * * Redistributions in binary form must reproduce the above copyright
122791 + * notice, this list of conditions and the following disclaimer in the
122792 + * documentation and/or other materials provided with the distribution.
122793 + * * Neither the name of Freescale Semiconductor nor the
122794 + * names of its contributors may be used to endorse or promote products
122795 + * derived from this software without specific prior written permission.
122796 + *
122797 + *
122798 + * ALTERNATIVELY, this software may be distributed under the terms of the
122799 + * GNU General Public License ("GPL") as published by the Free Software
122800 + * Foundation, either version 2 of that License or (at your option) any
122801 + * later version.
122802 + *
122803 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122804 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122805 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122806 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122807 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122808 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122809 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122810 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122811 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122812 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122813 + */
122814 +
122815 +/*
122816 + @File lnxwrp_sysfs_fm_port.h
122817 +
122818 + @Description FM port sysfs functions.
122819 +
122820 +*/
122821 +
122822 +#ifndef LNXWRP_SYSFS_FM_PORT_H_
122823 +#define LNXWRP_SYSFS_FM_PORT_H_
122824 +
122825 +#include "lnxwrp_sysfs.h"
122826 +
122827 +int fm_port_sysfs_create(struct device *dev);
122828 +void fm_port_sysfs_destroy(struct device *dev);
122829 +
122830 +int fm_port_dump_regs(void *h_dev, char *buf, int n);
122831 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int n);
122832 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int n);
122833 +
122834 +#if (DPAA_VERSION >= 11)
122835 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int n);
122836 +#endif
122837 +
122838 +#endif /* LNXWRP_SYSFS_FM_PORT_H_ */
122839 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
122840 new file mode 100644
122841 index 00000000..1071c22a
122842 --- /dev/null
122843 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
122844 @@ -0,0 +1,18 @@
122845 +#
122846 +# Makefile for the Freescale Ethernet controllers
122847 +#
122848 +ccflags-y += -DVERSION=\"\"
122849 +#
122850 +#Include netcomm SW specific definitions
122851 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
122852 +
122853 +obj-y += fsl-ncsw-xx.o
122854 +
122855 +ifneq ($(CONFIG_FMAN_ARM),y)
122856 +fsl-ncsw-xx-objs := xx_linux.o \
122857 + module_strings.o
122858 +else
122859 +fsl-ncsw-xx-objs := xx_arm_linux.o \
122860 + module_strings.o
122861 +endif
122862 +
122863 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
122864 new file mode 100644
122865 index 00000000..d7fed170
122866 --- /dev/null
122867 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
122868 @@ -0,0 +1,46 @@
122869 +/*
122870 + * Copyright 2012 Freescale Semiconductor Inc.
122871 + *
122872 + * Redistribution and use in source and binary forms, with or without
122873 + * modification, are permitted provided that the following conditions are met:
122874 + * * Redistributions of source code must retain the above copyright
122875 + * notice, this list of conditions and the following disclaimer.
122876 + * * Redistributions in binary form must reproduce the above copyright
122877 + * notice, this list of conditions and the following disclaimer in the
122878 + * documentation and/or other materials provided with the distribution.
122879 + * * Neither the name of Freescale Semiconductor nor the
122880 + * names of its contributors may be used to endorse or promote products
122881 + * derived from this software without specific prior written permission.
122882 + *
122883 + *
122884 + * ALTERNATIVELY, this software may be distributed under the terms of the
122885 + * GNU General Public License ("GPL") as published by the Free Software
122886 + * Foundation, either version 2 of that License or (at your option) any
122887 + * later version.
122888 + *
122889 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122890 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122891 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122892 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122893 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122894 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122895 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122896 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122897 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122898 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122899 + */
122900 +
122901 +/* Module names for debug messages */
122902 +const char *moduleStrings[] =
122903 +{
122904 + "", /* MODULE_UNKNOWN */
122905 + "FM", /* MODULE_FM */
122906 + "FM-MURAM", /* MODULE_FM_MURAM */
122907 + "FM-PCD", /* MODULE_FM_PCD */
122908 + "FM-RTC", /* MODULE_FM_RTC */
122909 + "FM-MAC", /* MODULE_FM_MAC */
122910 + "FM-Port", /* MODULE_FM_PORT */
122911 + "MM", /* MODULE_MM */
122912 + "FM-SP", /* MODULE_FM_SP */
122913 + "FM-MACSEC" /* MODULE_FM_MACSEC */
122914 +};
122915 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
122916 new file mode 100644
122917 index 00000000..dd3e376e
122918 --- /dev/null
122919 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
122920 @@ -0,0 +1,905 @@
122921 +/*
122922 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122923 + *
122924 + * Redistribution and use in source and binary forms, with or without
122925 + * modification, are permitted provided that the following conditions are met:
122926 + * * Redistributions of source code must retain the above copyright
122927 + * notice, this list of conditions and the following disclaimer.
122928 + * * Redistributions in binary form must reproduce the above copyright
122929 + * notice, this list of conditions and the following disclaimer in the
122930 + * documentation and/or other materials provided with the distribution.
122931 + * * Neither the name of Freescale Semiconductor nor the
122932 + * names of its contributors may be used to endorse or promote products
122933 + * derived from this software without specific prior written permission.
122934 + *
122935 + *
122936 + * ALTERNATIVELY, this software may be distributed under the terms of the
122937 + * GNU General Public License ("GPL") as published by the Free Software
122938 + * Foundation, either version 2 of that License or (at your option) any
122939 + * later version.
122940 + *
122941 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122942 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122943 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122944 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122945 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122946 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122947 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122948 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122949 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122950 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122951 + */
122952 +
122953 +/**************************************************************************//**
122954 + @File xx_arm_linux.c
122955 +
122956 + @Description XX routines implementation for Linux.
122957 +*//***************************************************************************/
122958 +#include <linux/version.h>
122959 +
122960 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
122961 +#define MODVERSIONS
122962 +#endif
122963 +#ifdef MODVERSIONS
122964 +#include <config/modversions.h>
122965 +#endif /* MODVERSIONS */
122966 +
122967 +#include <linux/module.h>
122968 +#include <linux/kernel.h>
122969 +#include <linux/sched.h>
122970 +#include <linux/string.h>
122971 +#include <linux/ptrace.h>
122972 +#include <linux/errno.h>
122973 +#include <linux/ioport.h>
122974 +#include <linux/slab.h>
122975 +#include <linux/interrupt.h>
122976 +#include <linux/fs.h>
122977 +#include <linux/vmalloc.h>
122978 +#include <linux/init.h>
122979 +#include <linux/timer.h>
122980 +#include <linux/spinlock.h>
122981 +#include <linux/delay.h>
122982 +#include <linux/proc_fs.h>
122983 +#include <linux/smp.h>
122984 +#include <linux/of.h>
122985 +#include <linux/irqdomain.h>
122986 +
122987 +#include <linux/workqueue.h>
122988 +
122989 +#ifdef BIGPHYSAREA_ENABLE
122990 +#include <linux/bigphysarea.h>
122991 +#endif /* BIGPHYSAREA_ENABLE */
122992 +
122993 +//#include <sysdev/fsl_soc.h>
122994 +#include <asm/pgtable.h>
122995 +#include <asm/irq.h>
122996 +#include <asm/bitops.h>
122997 +#include <asm/uaccess.h>
122998 +#include <asm/io.h>
122999 +#include <asm/atomic.h>
123000 +#include <asm/string.h>
123001 +#include <asm/byteorder.h>
123002 +#include <asm/page.h>
123003 +
123004 +#include "error_ext.h"
123005 +#include "std_ext.h"
123006 +#include "list_ext.h"
123007 +#include "mm_ext.h"
123008 +#include "sys_io_ext.h"
123009 +#include "xx.h"
123010 +
123011 +
123012 +#define __ERR_MODULE__ MODULE_UNKNOWN
123013 +
123014 +#ifdef BIGPHYSAREA_ENABLE
123015 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
123016 +
123017 +
123018 +/* TODO: large allocations => use big phys area */
123019 +/******************************************************************************
123020 + * routine: get_nr_pages
123021 + *
123022 + * description:
123023 + * calculates the number of memory pages for a given size (in bytes)
123024 + *
123025 + * arguments:
123026 + * size - the number of bytes
123027 + *
123028 + * return code:
123029 + * The number of pages
123030 + *
123031 + *****************************************************************************/
123032 +static __inline__ uint32_t get_nr_pages (uint32_t size)
123033 +{
123034 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
123035 +}
123036 +
123037 +static bool in_big_phys_area (uint32_t addr)
123038 +{
123039 + uint32_t base, size;
123040 +
123041 + bigphysarea_get_details (&base, &size);
123042 + return ((addr >= base) && (addr < base + size));
123043 +}
123044 +#endif /* BIGPHYSAREA_ENABLE */
123045 +
123046 +void * xx_Malloc(uint32_t n)
123047 +{
123048 + void *a;
123049 + uint32_t flags;
123050 +
123051 + flags = XX_DisableAllIntr();
123052 +#ifdef BIGPHYSAREA_ENABLE
123053 + if (n >= MAX_ALLOCATION_SIZE)
123054 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
123055 + else
123056 +#endif /* BIGPHYSAREA_ENABLE */
123057 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
123058 + if (!a)
123059 + XX_Print("No memory for XX_Malloc\n");
123060 + XX_RestoreAllIntr(flags);
123061 +
123062 + return a;
123063 +}
123064 +
123065 +void xx_Free(void *p)
123066 +{
123067 +#ifdef BIGPHYSAREA_ENABLE
123068 + if (in_big_phys_area ((uint32_t)p))
123069 + bigphysarea_free_pages(p);
123070 + else
123071 +#endif /* BIGPHYSAREA_ENABLE */
123072 + kfree(p);
123073 +}
123074 +
123075 +void XX_Exit(int status)
123076 +{
123077 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
123078 +}
123079 +
123080 +#define BUF_SIZE 512
123081 +void XX_Print(char *str, ...)
123082 +{
123083 + va_list args;
123084 +#ifdef CONFIG_SMP
123085 + char buf[BUF_SIZE];
123086 +#endif /* CONFIG_SMP */
123087 +
123088 + va_start(args, str);
123089 +#ifdef CONFIG_SMP
123090 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123091 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123092 + printk(KERN_CRIT "cpu %d: %s", raw_smp_processor_id(), buf);
123093 +#else
123094 + vprintk(str, args);
123095 +#endif /* CONFIG_SMP */
123096 + va_end(args);
123097 +}
123098 +
123099 +void XX_Fprint(void *file, char *str, ...)
123100 +{
123101 + va_list args;
123102 +#ifdef CONFIG_SMP
123103 + char buf[BUF_SIZE];
123104 +#endif /* CONFIG_SMP */
123105 +
123106 + va_start(args, str);
123107 +#ifdef CONFIG_SMP
123108 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123109 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123110 + printk (KERN_CRIT "cpu %d: %s", smp_processor_id(), buf);
123111 +
123112 +#else
123113 + vprintk(str, args);
123114 +#endif /* CONFIG_SMP */
123115 + va_end(args);
123116 +}
123117 +
123118 +#ifdef DEBUG_XX_MALLOC
123119 +typedef void (*t_ffn)(void *);
123120 +typedef struct {
123121 + t_ffn f_free;
123122 + void *mem;
123123 + char *fname;
123124 + int fline;
123125 + uint32_t size;
123126 + t_List node;
123127 +} t_MemDebug;
123128 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
123129 +
123130 +LIST(memDbgLst);
123131 +
123132 +
123133 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
123134 +{
123135 + void *mem;
123136 + t_MemDebug *p_MemDbg;
123137 +
123138 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
123139 + if (p_MemDbg == NULL)
123140 + return NULL;
123141 +
123142 + mem = xx_Malloc(size);
123143 + if (mem == NULL)
123144 + {
123145 + XX_Free(p_MemDbg);
123146 + return NULL;
123147 + }
123148 +
123149 + INIT_LIST(&p_MemDbg->node);
123150 + p_MemDbg->f_free = xx_Free;
123151 + p_MemDbg->mem = mem;
123152 + p_MemDbg->fname = fname;
123153 + p_MemDbg->fline = line;
123154 + p_MemDbg->size = size+sizeof(t_MemDebug);
123155 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123156 +
123157 + return mem;
123158 +}
123159 +
123160 +void * XX_MallocSmartDebug(uint32_t size,
123161 + int memPartitionId,
123162 + uint32_t align,
123163 + char *fname,
123164 + int line)
123165 +{
123166 + void *mem;
123167 + t_MemDebug *p_MemDbg;
123168 +
123169 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
123170 + if (p_MemDbg == NULL)
123171 + return NULL;
123172 +
123173 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
123174 + if (mem == NULL)
123175 + {
123176 + XX_Free(p_MemDbg);
123177 + return NULL;
123178 + }
123179 +
123180 + INIT_LIST(&p_MemDbg->node);
123181 + p_MemDbg->f_free = xx_FreeSmart;
123182 + p_MemDbg->mem = mem;
123183 + p_MemDbg->fname = fname;
123184 + p_MemDbg->fline = line;
123185 + p_MemDbg->size = size+sizeof(t_MemDebug);
123186 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123187 +
123188 + return mem;
123189 +}
123190 +
123191 +static void debug_free(void *mem)
123192 +{
123193 + t_List *p_MemDbgLh = NULL;
123194 + t_MemDebug *p_MemDbg;
123195 + bool found = FALSE;
123196 +
123197 + if (LIST_IsEmpty(&memDbgLst))
123198 + {
123199 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
123200 + return;
123201 + }
123202 +
123203 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
123204 + {
123205 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
123206 + if (p_MemDbg->mem == mem)
123207 + {
123208 + found = TRUE;
123209 + break;
123210 + }
123211 + }
123212 +
123213 + if (!found)
123214 + {
123215 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
123216 + ("Attempt to free unallocated address (0x%08x)",mem));
123217 + dump_stack();
123218 + return;
123219 + }
123220 +
123221 + LIST_Del(p_MemDbgLh);
123222 + p_MemDbg->f_free(mem);
123223 + p_MemDbg->f_free(p_MemDbg);
123224 +}
123225 +
123226 +void XX_FreeSmart(void *p)
123227 +{
123228 + debug_free(p);
123229 +}
123230 +
123231 +
123232 +void XX_Free(void *p)
123233 +{
123234 + debug_free(p);
123235 +}
123236 +
123237 +#else /* not DEBUG_XX_MALLOC */
123238 +void * XX_Malloc(uint32_t size)
123239 +{
123240 + return xx_Malloc(size);
123241 +}
123242 +
123243 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123244 +{
123245 + return xx_MallocSmart(size,memPartitionId, alignment);
123246 +}
123247 +
123248 +void XX_FreeSmart(void *p)
123249 +{
123250 + xx_FreeSmart(p);
123251 +}
123252 +
123253 +
123254 +void XX_Free(void *p)
123255 +{
123256 + xx_Free(p);
123257 +}
123258 +#endif /* not DEBUG_XX_MALLOC */
123259 +
123260 +
123261 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
123262 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
123263 +{
123264 + e_Event eventCode = (e_Event)event;
123265 +
123266 + UNUSED(eventCode);
123267 + UNUSED(appId);
123268 + UNUSED(flags);
123269 + UNUSED(msg);
123270 +}
123271 +#endif /* (defined(REPORT_EVENTS) && ... */
123272 +
123273 +
123274 +uint32_t XX_DisableAllIntr(void)
123275 +{
123276 + unsigned long flags;
123277 +
123278 +#ifdef local_irq_save_nort
123279 + local_irq_save_nort(flags);
123280 +#else
123281 + local_irq_save(flags);
123282 +#endif
123283 +
123284 + return (uint32_t)flags;
123285 +}
123286 +
123287 +void XX_RestoreAllIntr(uint32_t flags)
123288 +{
123289 +#ifdef local_irq_restore_nort
123290 + local_irq_restore_nort((unsigned long)flags);
123291 +#else
123292 + local_irq_restore((unsigned long)flags);
123293 +#endif
123294 +}
123295 +
123296 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
123297 +{
123298 + UNUSED(qid);
123299 + UNUSED(appId);
123300 + UNUSED(flags);
123301 +
123302 + return f(id);
123303 +}
123304 +
123305 +int XX_IsICacheEnable(void)
123306 +{
123307 + return TRUE;
123308 +}
123309 +
123310 +int XX_IsDCacheEnable(void)
123311 +{
123312 + return TRUE;
123313 +}
123314 +
123315 +
123316 +typedef struct {
123317 + t_Isr *f_Isr;
123318 + t_Handle handle;
123319 +} t_InterruptHandler;
123320 +
123321 +
123322 +t_Handle interruptHandlers[0x00010000];
123323 +
123324 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
123325 +{
123326 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
123327 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
123328 + return IRQ_HANDLED;
123329 +}
123330 +
123331 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
123332 +{
123333 + const char *device;
123334 + t_InterruptHandler *p_IntrHndl;
123335 +
123336 + device = GetDeviceName(irq);
123337 + if (device == NULL)
123338 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
123339 +
123340 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
123341 + if (p_IntrHndl == NULL)
123342 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
123343 + p_IntrHndl->f_Isr = f_Isr;
123344 + p_IntrHndl->handle = handle;
123345 + interruptHandlers[irq] = p_IntrHndl;
123346 +
123347 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
123348 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
123349 + disable_irq(GetDeviceIrqNum(irq));
123350 +
123351 + return E_OK;
123352 +}
123353 +
123354 +t_Error XX_FreeIntr(int irq)
123355 +{
123356 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
123357 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
123358 + XX_Free(p_IntrHndl);
123359 + interruptHandlers[irq] = 0;
123360 + return E_OK;
123361 +}
123362 +
123363 +t_Error XX_EnableIntr(int irq)
123364 +{
123365 + enable_irq(GetDeviceIrqNum(irq));
123366 + return E_OK;
123367 +}
123368 +
123369 +t_Error XX_DisableIntr(int irq)
123370 +{
123371 + disable_irq(GetDeviceIrqNum(irq));
123372 + return E_OK;
123373 +}
123374 +
123375 +
123376 +/*****************************************************************************/
123377 +/* Tasklet Service Routines */
123378 +/*****************************************************************************/
123379 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
123380 +typedef struct
123381 +{
123382 + t_Handle h_Data;
123383 + void (*f_Callback) (void *);
123384 + struct delayed_work dwork;
123385 +} t_Tasklet;
123386 +
123387 +static void GenericTaskletCallback(struct work_struct *p_Work)
123388 +{
123389 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
123390 +
123391 + p_Task->f_Callback(p_Task->h_Data);
123392 +}
123393 +#endif /* LINUX_VERSION_CODE */
123394 +
123395 +
123396 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
123397 +{
123398 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123399 + struct work_struct *p_Task;
123400 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
123401 + INIT_WORK(p_Task, routine, data);
123402 +#else
123403 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
123404 + p_Task->h_Data = data;
123405 + p_Task->f_Callback = routine;
123406 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
123407 +#endif /* LINUX_VERSION_CODE */
123408 +
123409 + return (t_TaskletHandle)p_Task;
123410 +}
123411 +
123412 +
123413 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
123414 +{
123415 + if (h_Tasklet)
123416 + XX_Free(h_Tasklet);
123417 +}
123418 +
123419 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
123420 +{
123421 + int ans;
123422 +
123423 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123424 + if (immediate)
123425 + ans = schedule_work(h_Tasklet);
123426 + else
123427 + ans = schedule_delayed_work(h_Tasklet, 1);
123428 +#else
123429 + if (immediate)
123430 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
123431 + else
123432 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
123433 +#endif /* LINUX_VERSION_CODE */
123434 +
123435 + return ans;
123436 +}
123437 +
123438 +void XX_FlushScheduledTasks(void)
123439 +{
123440 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123441 + flush_scheduled_tasks();
123442 +#else
123443 + flush_scheduled_work();
123444 +#endif /* LINUX_VERSION_CODE */
123445 +}
123446 +
123447 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
123448 +{
123449 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123450 + return (int)(((struct work_struct *)h_Tasklet)->pending);
123451 +#else
123452 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
123453 +#endif /* LINUX_VERSION_CODE */
123454 +}
123455 +
123456 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
123457 +{
123458 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123459 + ((struct tq_struct *)h_Tasklet)->data = data;
123460 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123461 + ((struct work_struct *)h_Tasklet)->data = data;
123462 +#else
123463 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
123464 +#endif /* LINUX_VERSION_CODE */
123465 +}
123466 +
123467 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
123468 +{
123469 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123470 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
123471 +#else
123472 + return ((t_Tasklet *)h_Tasklet)->h_Data;
123473 +#endif /* LINUX_VERSION_CODE */
123474 +}
123475 +
123476 +
123477 +/*****************************************************************************/
123478 +/* Spinlock Service Routines */
123479 +/*****************************************************************************/
123480 +
123481 +t_Handle XX_InitSpinlock(void)
123482 +{
123483 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
123484 + if (!p_Spinlock)
123485 + return NULL;
123486 +
123487 + spin_lock_init(p_Spinlock);
123488 +
123489 + return (t_Handle)p_Spinlock;
123490 +}
123491 +
123492 +void XX_FreeSpinlock(t_Handle h_Spinlock)
123493 +{
123494 + if (h_Spinlock)
123495 + XX_Free(h_Spinlock);
123496 +}
123497 +
123498 +void XX_LockSpinlock(t_Handle h_Spinlock)
123499 +{
123500 + spin_lock((spinlock_t *)h_Spinlock);
123501 +}
123502 +
123503 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
123504 +{
123505 + spin_unlock((spinlock_t *)h_Spinlock);
123506 +}
123507 +
123508 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
123509 +{
123510 + unsigned long intrFlags;
123511 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
123512 + return intrFlags;
123513 +}
123514 +
123515 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
123516 +{
123517 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
123518 +}
123519 +
123520 +
123521 +/*****************************************************************************/
123522 +/* Timers Service Routines */
123523 +/*****************************************************************************/
123524 +/* The time now is in mili sec. resolution */
123525 +uint32_t XX_CurrentTime(void)
123526 +{
123527 + return (jiffies*1000)/HZ;
123528 +}
123529 +
123530 +
123531 +t_Handle XX_CreateTimer(void)
123532 +{
123533 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
123534 + if (p_Timer)
123535 + {
123536 + memset(p_Timer, 0, sizeof(struct timer_list));
123537 + init_timer(p_Timer);
123538 + }
123539 + return (t_Handle)p_Timer;
123540 +}
123541 +
123542 +void XX_FreeTimer(t_Handle h_Timer)
123543 +{
123544 + if (h_Timer)
123545 + XX_Free(h_Timer);
123546 +}
123547 +
123548 +void XX_StartTimer(t_Handle h_Timer,
123549 + uint32_t msecs,
123550 + bool periodic,
123551 + void (*f_TimerExpired)(t_Handle),
123552 + t_Handle h_Arg)
123553 +{
123554 + int tmp_jiffies = (msecs*HZ)/1000;
123555 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123556 +
123557 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
123558 +
123559 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
123560 + p_Timer->data = (unsigned long)h_Arg;
123561 + if ((msecs*HZ)%1000)
123562 + tmp_jiffies++;
123563 + p_Timer->expires = (jiffies + tmp_jiffies);
123564 +
123565 + add_timer((struct timer_list *)h_Timer);
123566 +}
123567 +
123568 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
123569 +{
123570 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123571 +
123572 + p_Timer->data = (unsigned long)data;
123573 +}
123574 +
123575 +t_Handle XX_GetTimerData(t_Handle h_Timer)
123576 +{
123577 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123578 +
123579 + return (t_Handle)p_Timer->data;
123580 +}
123581 +
123582 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
123583 +{
123584 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123585 +
123586 + return (uint32_t)p_Timer->expires;
123587 +}
123588 +
123589 +void XX_StopTimer(t_Handle h_Timer)
123590 +{
123591 + del_timer((struct timer_list *)h_Timer);
123592 +}
123593 +
123594 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
123595 +{
123596 + int tmp_jiffies = (msecs*HZ)/1000;
123597 +
123598 + if ((msecs*HZ)%1000)
123599 + tmp_jiffies++;
123600 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
123601 +}
123602 +
123603 +int XX_TimerIsActive(t_Handle h_Timer)
123604 +{
123605 + return timer_pending((struct timer_list *)h_Timer);
123606 +}
123607 +
123608 +uint32_t XX_Sleep(uint32_t msecs)
123609 +{
123610 + int tmp_jiffies = (msecs*HZ)/1000;
123611 +
123612 + if ((msecs*HZ)%1000)
123613 + tmp_jiffies++;
123614 + return schedule_timeout(tmp_jiffies);
123615 +}
123616 +
123617 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
123618 +void XX_UDelay(uint32_t usecs)
123619 +{
123620 + udelay(usecs);
123621 +}
123622 +
123623 +/* TODO: verify that these are correct */
123624 +#define MSG_BODY_SIZE 512
123625 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
123626 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
123627 +t_Error XX_SendMessage(char *p_DestAddr,
123628 + uint32_t msgId,
123629 + uint8_t msgBody[MSG_BODY_SIZE],
123630 + t_MsgCompletionCB *f_CompletionCB,
123631 + t_Handle h_CBArg);
123632 +
123633 +typedef struct {
123634 + char *p_Addr;
123635 + t_MsgHandler *f_MsgHandlerCB;
123636 + t_Handle h_Mod;
123637 + t_List node;
123638 +} t_MsgHndlr;
123639 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
123640 +
123641 +LIST(msgHndlrList);
123642 +
123643 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
123644 +{
123645 + uint32_t intFlags;
123646 +
123647 + intFlags = XX_DisableAllIntr();
123648 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
123649 + XX_RestoreAllIntr(intFlags);
123650 +}
123651 +/* TODO: add this for multi-platform support
123652 +static t_MsgHndlr * DequeueMsgHndlr(void)
123653 +{
123654 + t_MsgHndlr *p_MsgHndlr = NULL;
123655 + uint32_t intFlags;
123656 +
123657 + intFlags = XX_DisableAllIntr();
123658 + if (!LIST_IsEmpty(&msgHndlrList))
123659 + {
123660 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
123661 + LIST_DelAndInit(&p_MsgHndlr->node);
123662 + }
123663 + XX_RestoreAllIntr(intFlags);
123664 +
123665 + return p_MsgHndlr;
123666 +}
123667 +*/
123668 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
123669 +{
123670 + t_MsgHndlr *p_MsgHndlr;
123671 + t_List *p_Pos;
123672 +
123673 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
123674 + {
123675 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
123676 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
123677 + return p_MsgHndlr;
123678 + }
123679 +
123680 + return NULL;
123681 +}
123682 +
123683 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
123684 +{
123685 + t_MsgHndlr *p_MsgHndlr;
123686 + uint32_t len;
123687 +
123688 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
123689 + if (!p_MsgHndlr)
123690 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
123691 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
123692 +
123693 + len = strlen(p_Addr);
123694 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
123695 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
123696 +
123697 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
123698 + p_MsgHndlr->h_Mod = h_Mod;
123699 + INIT_LIST(&p_MsgHndlr->node);
123700 + EnqueueMsgHndlr(p_MsgHndlr);
123701 +
123702 + return E_OK;
123703 +}
123704 +
123705 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
123706 +{
123707 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
123708 + if (!p_MsgHndlr)
123709 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123710 +
123711 + LIST_Del(&p_MsgHndlr->node);
123712 + XX_Free(p_MsgHndlr->p_Addr);
123713 + XX_Free(p_MsgHndlr);
123714 +
123715 + return E_OK;
123716 +}
123717 +
123718 +t_Error XX_SendMessage(char *p_DestAddr,
123719 + uint32_t msgId,
123720 + uint8_t msgBody[MSG_BODY_SIZE],
123721 + t_MsgCompletionCB *f_CompletionCB,
123722 + t_Handle h_CBArg)
123723 +{
123724 + t_Error ans;
123725 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
123726 + if (!p_MsgHndlr)
123727 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123728 +
123729 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
123730 +
123731 + if (f_CompletionCB)
123732 + f_CompletionCB(h_CBArg, msgBody);
123733 +
123734 + return ans;
123735 +}
123736 +
123737 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123738 + t_IpcMsgHandler *f_MsgHandler,
123739 + t_Handle h_Module,
123740 + uint32_t replyLength)
123741 +{
123742 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
123743 + return E_OK;
123744 +}
123745 +
123746 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123747 +{
123748 + UNUSED(addr);
123749 + return E_OK;
123750 +}
123751 +
123752 +
123753 +t_Error XX_IpcSendMessage(t_Handle h_Session,
123754 + uint8_t *p_Msg,
123755 + uint32_t msgLength,
123756 + uint8_t *p_Reply,
123757 + uint32_t *p_ReplyLength,
123758 + t_IpcMsgCompletion *f_Completion,
123759 + t_Handle h_Arg)
123760 +{
123761 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
123762 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
123763 + return E_OK;
123764 +}
123765 +
123766 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123767 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123768 +{
123769 + UNUSED(destAddr); UNUSED(srcAddr);
123770 + return E_OK;
123771 +}
123772 +
123773 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
123774 +int GetDeviceIrqNum(int irq)
123775 +{
123776 + struct device_node *iPar;
123777 + struct irq_domain *irqHost;
123778 + uint32_t hwIrq;
123779 +
123780 + /* Get the interrupt controller */
123781 + iPar = of_find_node_by_name(NULL, "mpic");
123782 + hwIrq = 0;
123783 +
123784 + ASSERT_COND(iPar != NULL);
123785 + /* Get the irq host */
123786 + irqHost = irq_find_host(iPar);
123787 + of_node_put(iPar);
123788 +
123789 + /* Create irq mapping */
123790 + return irq_create_mapping(irqHost, hwIrq);
123791 +}
123792 +#else
123793 +#error "kernel not supported!!!"
123794 +#endif /* LINUX_VERSION_CODE */
123795 +
123796 +void * XX_PhysToVirt(physAddress_t addr)
123797 +{
123798 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
123799 +}
123800 +
123801 +physAddress_t XX_VirtToPhys(void * addr)
123802 +{
123803 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
123804 +}
123805 +
123806 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123807 +{
123808 + uintptr_t *returnCode, tmp;
123809 +
123810 + if (alignment < sizeof(uintptr_t))
123811 + alignment = sizeof(uintptr_t);
123812 + size += alignment + sizeof(returnCode);
123813 + tmp = (uintptr_t)xx_Malloc(size);
123814 + if (tmp == 0)
123815 + return NULL;
123816 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
123817 + *(returnCode - 1) = tmp;
123818 +
123819 + return (void*)returnCode;
123820 +}
123821 +
123822 +void xx_FreeSmart(void *p)
123823 +{
123824 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
123825 +}
123826 diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
123827 new file mode 100644
123828 index 00000000..992757d4
123829 --- /dev/null
123830 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
123831 @@ -0,0 +1,918 @@
123832 +/*
123833 + * Copyright 2008-2012 Freescale Semiconductor Inc.
123834 + *
123835 + * Redistribution and use in source and binary forms, with or without
123836 + * modification, are permitted provided that the following conditions are met:
123837 + * * Redistributions of source code must retain the above copyright
123838 + * notice, this list of conditions and the following disclaimer.
123839 + * * Redistributions in binary form must reproduce the above copyright
123840 + * notice, this list of conditions and the following disclaimer in the
123841 + * documentation and/or other materials provided with the distribution.
123842 + * * Neither the name of Freescale Semiconductor nor the
123843 + * names of its contributors may be used to endorse or promote products
123844 + * derived from this software without specific prior written permission.
123845 + *
123846 + *
123847 + * ALTERNATIVELY, this software may be distributed under the terms of the
123848 + * GNU General Public License ("GPL") as published by the Free Software
123849 + * Foundation, either version 2 of that License or (at your option) any
123850 + * later version.
123851 + *
123852 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
123853 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
123854 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
123855 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
123856 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
123857 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
123858 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
123859 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
123860 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
123861 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123862 + */
123863 +
123864 +/**************************************************************************//**
123865 + @File xx_linux.c
123866 +
123867 + @Description XX routines implementation for Linux.
123868 +*//***************************************************************************/
123869 +#include <linux/version.h>
123870 +
123871 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
123872 +#define MODVERSIONS
123873 +#endif
123874 +#ifdef MODVERSIONS
123875 +#include <config/modversions.h>
123876 +#endif /* MODVERSIONS */
123877 +
123878 +#include <linux/module.h>
123879 +#include <linux/kernel.h>
123880 +#include <linux/sched.h>
123881 +#include <linux/string.h>
123882 +#include <linux/ptrace.h>
123883 +#include <linux/errno.h>
123884 +#include <linux/ioport.h>
123885 +#include <linux/slab.h>
123886 +#include <linux/interrupt.h>
123887 +#include <linux/fs.h>
123888 +#include <linux/vmalloc.h>
123889 +#include <linux/init.h>
123890 +#include <linux/timer.h>
123891 +#include <linux/spinlock.h>
123892 +#include <linux/delay.h>
123893 +#include <linux/proc_fs.h>
123894 +#include <linux/smp.h>
123895 +#include <linux/of.h>
123896 +#ifdef CONFIG_FMAN_ARM
123897 +#include <linux/irqdomain.h>
123898 +#endif
123899 +
123900 +#include <linux/workqueue.h>
123901 +
123902 +#ifdef BIGPHYSAREA_ENABLE
123903 +#include <linux/bigphysarea.h>
123904 +#endif /* BIGPHYSAREA_ENABLE */
123905 +
123906 +#ifndef CONFIG_FMAN_ARM
123907 +#include <sysdev/fsl_soc.h>
123908 +#endif
123909 +#include <asm/pgtable.h>
123910 +#include <asm/irq.h>
123911 +#include <asm/bitops.h>
123912 +#include <asm/uaccess.h>
123913 +#include <asm/io.h>
123914 +#include <asm/atomic.h>
123915 +#include <asm/string.h>
123916 +#include <asm/byteorder.h>
123917 +#include <asm/page.h>
123918 +
123919 +#include "error_ext.h"
123920 +#include "std_ext.h"
123921 +#include "list_ext.h"
123922 +#include "mm_ext.h"
123923 +#include "sys_io_ext.h"
123924 +#include "xx.h"
123925 +
123926 +
123927 +#define __ERR_MODULE__ MODULE_UNKNOWN
123928 +
123929 +#ifdef BIGPHYSAREA_ENABLE
123930 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
123931 +
123932 +
123933 +/* TODO: large allocations => use big phys area */
123934 +/******************************************************************************
123935 + * routine: get_nr_pages
123936 + *
123937 + * description:
123938 + * calculates the number of memory pages for a given size (in bytes)
123939 + *
123940 + * arguments:
123941 + * size - the number of bytes
123942 + *
123943 + * return code:
123944 + * The number of pages
123945 + *
123946 + *****************************************************************************/
123947 +static __inline__ uint32_t get_nr_pages (uint32_t size)
123948 +{
123949 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
123950 +}
123951 +
123952 +static bool in_big_phys_area (uint32_t addr)
123953 +{
123954 + uint32_t base, size;
123955 +
123956 + bigphysarea_get_details (&base, &size);
123957 + return ((addr >= base) && (addr < base + size));
123958 +}
123959 +#endif /* BIGPHYSAREA_ENABLE */
123960 +
123961 +void * xx_Malloc(uint32_t n)
123962 +{
123963 + void *a;
123964 + uint32_t flags;
123965 +
123966 + flags = XX_DisableAllIntr();
123967 +#ifdef BIGPHYSAREA_ENABLE
123968 + if (n >= MAX_ALLOCATION_SIZE)
123969 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
123970 + else
123971 +#endif /* BIGPHYSAREA_ENABLE */
123972 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
123973 + if (!a)
123974 + XX_Print("No memory for XX_Malloc\n");
123975 + XX_RestoreAllIntr(flags);
123976 +
123977 + return a;
123978 +}
123979 +
123980 +void xx_Free(void *p)
123981 +{
123982 +#ifdef BIGPHYSAREA_ENABLE
123983 + if (in_big_phys_area ((uint32_t)p))
123984 + bigphysarea_free_pages(p);
123985 + else
123986 +#endif /* BIGPHYSAREA_ENABLE */
123987 + kfree(p);
123988 +}
123989 +
123990 +void XX_Exit(int status)
123991 +{
123992 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
123993 +}
123994 +
123995 +#define BUF_SIZE 512
123996 +void XX_Print(char *str, ...)
123997 +{
123998 + va_list args;
123999 +#ifdef CONFIG_SMP
124000 + char buf[BUF_SIZE];
124001 +#endif /* CONFIG_SMP */
124002 +
124003 + va_start(args, str);
124004 +#ifdef CONFIG_SMP
124005 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
124006 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
124007 + printk(KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
124008 +#else
124009 + vprintk(str, args);
124010 +#endif /* CONFIG_SMP */
124011 + va_end(args);
124012 +}
124013 +
124014 +void XX_Fprint(void *file, char *str, ...)
124015 +{
124016 + va_list args;
124017 +#ifdef CONFIG_SMP
124018 + char buf[BUF_SIZE];
124019 +#endif /* CONFIG_SMP */
124020 +
124021 + va_start(args, str);
124022 +#ifdef CONFIG_SMP
124023 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
124024 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
124025 + printk (KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
124026 +
124027 +#else
124028 + vprintk(str, args);
124029 +#endif /* CONFIG_SMP */
124030 + va_end(args);
124031 +}
124032 +
124033 +#ifdef DEBUG_XX_MALLOC
124034 +typedef void (*t_ffn)(void *);
124035 +typedef struct {
124036 + t_ffn f_free;
124037 + void *mem;
124038 + char *fname;
124039 + int fline;
124040 + uint32_t size;
124041 + t_List node;
124042 +} t_MemDebug;
124043 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
124044 +
124045 +LIST(memDbgLst);
124046 +
124047 +
124048 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
124049 +{
124050 + void *mem;
124051 + t_MemDebug *p_MemDbg;
124052 +
124053 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
124054 + if (p_MemDbg == NULL)
124055 + return NULL;
124056 +
124057 + mem = xx_Malloc(size);
124058 + if (mem == NULL)
124059 + {
124060 + XX_Free(p_MemDbg);
124061 + return NULL;
124062 + }
124063 +
124064 + INIT_LIST(&p_MemDbg->node);
124065 + p_MemDbg->f_free = xx_Free;
124066 + p_MemDbg->mem = mem;
124067 + p_MemDbg->fname = fname;
124068 + p_MemDbg->fline = line;
124069 + p_MemDbg->size = size+sizeof(t_MemDebug);
124070 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
124071 +
124072 + return mem;
124073 +}
124074 +
124075 +void * XX_MallocSmartDebug(uint32_t size,
124076 + int memPartitionId,
124077 + uint32_t align,
124078 + char *fname,
124079 + int line)
124080 +{
124081 + void *mem;
124082 + t_MemDebug *p_MemDbg;
124083 +
124084 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
124085 + if (p_MemDbg == NULL)
124086 + return NULL;
124087 +
124088 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
124089 + if (mem == NULL)
124090 + {
124091 + XX_Free(p_MemDbg);
124092 + return NULL;
124093 + }
124094 +
124095 + INIT_LIST(&p_MemDbg->node);
124096 + p_MemDbg->f_free = xx_FreeSmart;
124097 + p_MemDbg->mem = mem;
124098 + p_MemDbg->fname = fname;
124099 + p_MemDbg->fline = line;
124100 + p_MemDbg->size = size+sizeof(t_MemDebug);
124101 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
124102 +
124103 + return mem;
124104 +}
124105 +
124106 +static void debug_free(void *mem)
124107 +{
124108 + t_List *p_MemDbgLh = NULL;
124109 + t_MemDebug *p_MemDbg;
124110 + bool found = FALSE;
124111 +
124112 + if (LIST_IsEmpty(&memDbgLst))
124113 + {
124114 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
124115 + return;
124116 + }
124117 +
124118 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
124119 + {
124120 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
124121 + if (p_MemDbg->mem == mem)
124122 + {
124123 + found = TRUE;
124124 + break;
124125 + }
124126 + }
124127 +
124128 + if (!found)
124129 + {
124130 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
124131 + ("Attempt to free unallocated address (0x%08x)",mem));
124132 + dump_stack();
124133 + return;
124134 + }
124135 +
124136 + LIST_Del(p_MemDbgLh);
124137 + p_MemDbg->f_free(mem);
124138 + p_MemDbg->f_free(p_MemDbg);
124139 +}
124140 +
124141 +void XX_FreeSmart(void *p)
124142 +{
124143 + debug_free(p);
124144 +}
124145 +
124146 +
124147 +void XX_Free(void *p)
124148 +{
124149 + debug_free(p);
124150 +}
124151 +
124152 +#else /* not DEBUG_XX_MALLOC */
124153 +void * XX_Malloc(uint32_t size)
124154 +{
124155 + return xx_Malloc(size);
124156 +}
124157 +
124158 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
124159 +{
124160 + return xx_MallocSmart(size,memPartitionId, alignment);
124161 +}
124162 +
124163 +void XX_FreeSmart(void *p)
124164 +{
124165 + xx_FreeSmart(p);
124166 +}
124167 +
124168 +
124169 +void XX_Free(void *p)
124170 +{
124171 + xx_Free(p);
124172 +}
124173 +#endif /* not DEBUG_XX_MALLOC */
124174 +
124175 +
124176 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
124177 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
124178 +{
124179 + e_Event eventCode = (e_Event)event;
124180 +
124181 + UNUSED(eventCode);
124182 + UNUSED(appId);
124183 + UNUSED(flags);
124184 + UNUSED(msg);
124185 +}
124186 +#endif /* (defined(REPORT_EVENTS) && ... */
124187 +
124188 +
124189 +uint32_t XX_DisableAllIntr(void)
124190 +{
124191 + unsigned long flags;
124192 +
124193 +#ifdef local_irq_save_nort
124194 + local_irq_save_nort(flags);
124195 +#else
124196 + local_irq_save(flags);
124197 +#endif
124198 +
124199 + return (uint32_t)flags;
124200 +}
124201 +
124202 +void XX_RestoreAllIntr(uint32_t flags)
124203 +{
124204 +#ifdef local_irq_restore_nort
124205 + local_irq_restore_nort((unsigned long)flags);
124206 +#else
124207 + local_irq_restore((unsigned long)flags);
124208 +#endif
124209 +}
124210 +
124211 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
124212 +{
124213 + UNUSED(qid);
124214 + UNUSED(appId);
124215 + UNUSED(flags);
124216 +
124217 + return f(id);
124218 +}
124219 +
124220 +int XX_IsICacheEnable(void)
124221 +{
124222 + return TRUE;
124223 +}
124224 +
124225 +int XX_IsDCacheEnable(void)
124226 +{
124227 + return TRUE;
124228 +}
124229 +
124230 +
124231 +typedef struct {
124232 + t_Isr *f_Isr;
124233 + t_Handle handle;
124234 +} t_InterruptHandler;
124235 +
124236 +
124237 +t_Handle interruptHandlers[0x00010000];
124238 +
124239 +#ifdef CONFIG_FMAN_ARM
124240 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
124241 +{
124242 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
124243 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
124244 + return IRQ_HANDLED;
124245 +}
124246 +#endif
124247 +
124248 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
124249 +{
124250 +#ifdef CONFIG_FMAN_ARM
124251 + const char *device;
124252 + t_InterruptHandler *p_IntrHndl;
124253 +
124254 + device = GetDeviceName(irq);
124255 + if (device == NULL)
124256 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
124257 +
124258 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
124259 + if (p_IntrHndl == NULL)
124260 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
124261 + p_IntrHndl->f_Isr = f_Isr;
124262 + p_IntrHndl->handle = handle;
124263 + interruptHandlers[irq] = p_IntrHndl;
124264 +
124265 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
124266 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
124267 + disable_irq(GetDeviceIrqNum(irq));
124268 +#endif
124269 + return E_OK;
124270 +}
124271 +
124272 +t_Error XX_FreeIntr(int irq)
124273 +{
124274 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
124275 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
124276 + XX_Free(p_IntrHndl);
124277 + interruptHandlers[irq] = 0;
124278 + return E_OK;
124279 +}
124280 +
124281 +t_Error XX_EnableIntr(int irq)
124282 +{
124283 + enable_irq(GetDeviceIrqNum(irq));
124284 + return E_OK;
124285 +}
124286 +
124287 +t_Error XX_DisableIntr(int irq)
124288 +{
124289 + disable_irq(GetDeviceIrqNum(irq));
124290 + return E_OK;
124291 +}
124292 +
124293 +
124294 +/*****************************************************************************/
124295 +/* Tasklet Service Routines */
124296 +/*****************************************************************************/
124297 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
124298 +typedef struct
124299 +{
124300 + t_Handle h_Data;
124301 + void (*f_Callback) (void *);
124302 + struct delayed_work dwork;
124303 +} t_Tasklet;
124304 +
124305 +static void GenericTaskletCallback(struct work_struct *p_Work)
124306 +{
124307 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
124308 +
124309 + p_Task->f_Callback(p_Task->h_Data);
124310 +}
124311 +#endif /* LINUX_VERSION_CODE */
124312 +
124313 +
124314 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
124315 +{
124316 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124317 + struct work_struct *p_Task;
124318 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
124319 + INIT_WORK(p_Task, routine, data);
124320 +#else
124321 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
124322 + p_Task->h_Data = data;
124323 + p_Task->f_Callback = routine;
124324 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
124325 +#endif /* LINUX_VERSION_CODE */
124326 +
124327 + return (t_TaskletHandle)p_Task;
124328 +}
124329 +
124330 +
124331 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
124332 +{
124333 + if (h_Tasklet)
124334 + XX_Free(h_Tasklet);
124335 +}
124336 +
124337 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
124338 +{
124339 + int ans;
124340 +
124341 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124342 + if (immediate)
124343 + ans = schedule_work(h_Tasklet);
124344 + else
124345 + ans = schedule_delayed_work(h_Tasklet, 1);
124346 +#else
124347 + if (immediate)
124348 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
124349 + else
124350 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
124351 +#endif /* LINUX_VERSION_CODE */
124352 +
124353 + return ans;
124354 +}
124355 +
124356 +void XX_FlushScheduledTasks(void)
124357 +{
124358 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
124359 + flush_scheduled_tasks();
124360 +#else
124361 + flush_scheduled_work();
124362 +#endif /* LINUX_VERSION_CODE */
124363 +}
124364 +
124365 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
124366 +{
124367 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124368 + return (int)(((struct work_struct *)h_Tasklet)->pending);
124369 +#else
124370 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
124371 +#endif /* LINUX_VERSION_CODE */
124372 +}
124373 +
124374 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
124375 +{
124376 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
124377 + ((struct tq_struct *)h_Tasklet)->data = data;
124378 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124379 + ((struct work_struct *)h_Tasklet)->data = data;
124380 +#else
124381 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
124382 +#endif /* LINUX_VERSION_CODE */
124383 +}
124384 +
124385 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
124386 +{
124387 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124388 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
124389 +#else
124390 + return ((t_Tasklet *)h_Tasklet)->h_Data;
124391 +#endif /* LINUX_VERSION_CODE */
124392 +}
124393 +
124394 +
124395 +/*****************************************************************************/
124396 +/* Spinlock Service Routines */
124397 +/*****************************************************************************/
124398 +
124399 +t_Handle XX_InitSpinlock(void)
124400 +{
124401 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
124402 + if (!p_Spinlock)
124403 + return NULL;
124404 +
124405 + spin_lock_init(p_Spinlock);
124406 +
124407 + return (t_Handle)p_Spinlock;
124408 +}
124409 +
124410 +void XX_FreeSpinlock(t_Handle h_Spinlock)
124411 +{
124412 + if (h_Spinlock)
124413 + XX_Free(h_Spinlock);
124414 +}
124415 +
124416 +void XX_LockSpinlock(t_Handle h_Spinlock)
124417 +{
124418 + spin_lock((spinlock_t *)h_Spinlock);
124419 +}
124420 +
124421 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
124422 +{
124423 + spin_unlock((spinlock_t *)h_Spinlock);
124424 +}
124425 +
124426 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
124427 +{
124428 + unsigned long intrFlags;
124429 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
124430 + return intrFlags;
124431 +}
124432 +
124433 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
124434 +{
124435 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
124436 +}
124437 +
124438 +
124439 +/*****************************************************************************/
124440 +/* Timers Service Routines */
124441 +/*****************************************************************************/
124442 +/* The time now is in mili sec. resolution */
124443 +uint32_t XX_CurrentTime(void)
124444 +{
124445 + return (jiffies*1000)/HZ;
124446 +}
124447 +
124448 +
124449 +t_Handle XX_CreateTimer(void)
124450 +{
124451 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
124452 + if (p_Timer)
124453 + {
124454 + memset(p_Timer, 0, sizeof(struct timer_list));
124455 + init_timer(p_Timer);
124456 + }
124457 + return (t_Handle)p_Timer;
124458 +}
124459 +
124460 +void XX_FreeTimer(t_Handle h_Timer)
124461 +{
124462 + if (h_Timer)
124463 + XX_Free(h_Timer);
124464 +}
124465 +
124466 +void XX_StartTimer(t_Handle h_Timer,
124467 + uint32_t msecs,
124468 + bool periodic,
124469 + void (*f_TimerExpired)(t_Handle),
124470 + t_Handle h_Arg)
124471 +{
124472 + int tmp_jiffies = (msecs*HZ)/1000;
124473 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124474 +
124475 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
124476 +
124477 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
124478 + p_Timer->data = (unsigned long)h_Arg;
124479 + if ((msecs*HZ)%1000)
124480 + tmp_jiffies++;
124481 + p_Timer->expires = (jiffies + tmp_jiffies);
124482 +
124483 + add_timer((struct timer_list *)h_Timer);
124484 +}
124485 +
124486 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
124487 +{
124488 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124489 +
124490 + p_Timer->data = (unsigned long)data;
124491 +}
124492 +
124493 +t_Handle XX_GetTimerData(t_Handle h_Timer)
124494 +{
124495 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124496 +
124497 + return (t_Handle)p_Timer->data;
124498 +}
124499 +
124500 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
124501 +{
124502 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124503 +
124504 + return (uint32_t)p_Timer->expires;
124505 +}
124506 +
124507 +void XX_StopTimer(t_Handle h_Timer)
124508 +{
124509 + del_timer((struct timer_list *)h_Timer);
124510 +}
124511 +
124512 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
124513 +{
124514 + int tmp_jiffies = (msecs*HZ)/1000;
124515 +
124516 + if ((msecs*HZ)%1000)
124517 + tmp_jiffies++;
124518 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
124519 +}
124520 +
124521 +int XX_TimerIsActive(t_Handle h_Timer)
124522 +{
124523 + return timer_pending((struct timer_list *)h_Timer);
124524 +}
124525 +
124526 +uint32_t XX_Sleep(uint32_t msecs)
124527 +{
124528 + int tmp_jiffies = (msecs*HZ)/1000;
124529 +
124530 + if ((msecs*HZ)%1000)
124531 + tmp_jiffies++;
124532 + return schedule_timeout(tmp_jiffies);
124533 +}
124534 +
124535 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
124536 +void XX_UDelay(uint32_t usecs)
124537 +{
124538 + udelay(usecs);
124539 +}
124540 +
124541 +/* TODO: verify that these are correct */
124542 +#define MSG_BODY_SIZE 512
124543 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
124544 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
124545 +t_Error XX_SendMessage(char *p_DestAddr,
124546 + uint32_t msgId,
124547 + uint8_t msgBody[MSG_BODY_SIZE],
124548 + t_MsgCompletionCB *f_CompletionCB,
124549 + t_Handle h_CBArg);
124550 +
124551 +typedef struct {
124552 + char *p_Addr;
124553 + t_MsgHandler *f_MsgHandlerCB;
124554 + t_Handle h_Mod;
124555 + t_List node;
124556 +} t_MsgHndlr;
124557 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
124558 +
124559 +LIST(msgHndlrList);
124560 +
124561 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
124562 +{
124563 + uint32_t intFlags;
124564 +
124565 + intFlags = XX_DisableAllIntr();
124566 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
124567 + XX_RestoreAllIntr(intFlags);
124568 +}
124569 +/* TODO: add this for multi-platform support
124570 +static t_MsgHndlr * DequeueMsgHndlr(void)
124571 +{
124572 + t_MsgHndlr *p_MsgHndlr = NULL;
124573 + uint32_t intFlags;
124574 +
124575 + intFlags = XX_DisableAllIntr();
124576 + if (!LIST_IsEmpty(&msgHndlrList))
124577 + {
124578 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
124579 + LIST_DelAndInit(&p_MsgHndlr->node);
124580 + }
124581 + XX_RestoreAllIntr(intFlags);
124582 +
124583 + return p_MsgHndlr;
124584 +}
124585 +*/
124586 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
124587 +{
124588 + t_MsgHndlr *p_MsgHndlr;
124589 + t_List *p_Pos;
124590 +
124591 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
124592 + {
124593 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
124594 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
124595 + return p_MsgHndlr;
124596 + }
124597 +
124598 + return NULL;
124599 +}
124600 +
124601 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
124602 +{
124603 + t_MsgHndlr *p_MsgHndlr;
124604 + uint32_t len;
124605 +
124606 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
124607 + if (!p_MsgHndlr)
124608 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
124609 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
124610 +
124611 + len = strlen(p_Addr);
124612 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
124613 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
124614 +
124615 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
124616 + p_MsgHndlr->h_Mod = h_Mod;
124617 + INIT_LIST(&p_MsgHndlr->node);
124618 + EnqueueMsgHndlr(p_MsgHndlr);
124619 +
124620 + return E_OK;
124621 +}
124622 +
124623 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
124624 +{
124625 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
124626 + if (!p_MsgHndlr)
124627 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124628 +
124629 + LIST_Del(&p_MsgHndlr->node);
124630 + XX_Free(p_MsgHndlr->p_Addr);
124631 + XX_Free(p_MsgHndlr);
124632 +
124633 + return E_OK;
124634 +}
124635 +
124636 +t_Error XX_SendMessage(char *p_DestAddr,
124637 + uint32_t msgId,
124638 + uint8_t msgBody[MSG_BODY_SIZE],
124639 + t_MsgCompletionCB *f_CompletionCB,
124640 + t_Handle h_CBArg)
124641 +{
124642 + t_Error ans;
124643 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
124644 + if (!p_MsgHndlr)
124645 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124646 +
124647 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
124648 +
124649 + if (f_CompletionCB)
124650 + f_CompletionCB(h_CBArg, msgBody);
124651 +
124652 + return ans;
124653 +}
124654 +
124655 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124656 + t_IpcMsgHandler *f_MsgHandler,
124657 + t_Handle h_Module,
124658 + uint32_t replyLength)
124659 +{
124660 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
124661 + return E_OK;
124662 +}
124663 +
124664 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124665 +{
124666 + UNUSED(addr);
124667 + return E_OK;
124668 +}
124669 +
124670 +
124671 +t_Error XX_IpcSendMessage(t_Handle h_Session,
124672 + uint8_t *p_Msg,
124673 + uint32_t msgLength,
124674 + uint8_t *p_Reply,
124675 + uint32_t *p_ReplyLength,
124676 + t_IpcMsgCompletion *f_Completion,
124677 + t_Handle h_Arg)
124678 +{
124679 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
124680 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
124681 + return E_OK;
124682 +}
124683 +
124684 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124685 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124686 +{
124687 + UNUSED(destAddr); UNUSED(srcAddr);
124688 + return E_OK;
124689 +}
124690 +
124691 +/*Forced to introduce due to PRINT_FMT_PARAMS define*/
124692 +uint32_t E500_GetId(void)
124693 +{
124694 + return raw_smp_processor_id();
124695 +}
124696 +
124697 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
124698 +int GetDeviceIrqNum(int irq)
124699 +{
124700 + struct device_node *iPar;
124701 + struct irq_domain *irqHost;
124702 + uint32_t hwIrq;
124703 +
124704 + /* Get the interrupt controller */
124705 + iPar = of_find_node_by_name(NULL, "mpic");
124706 + hwIrq = 0;
124707 +
124708 + ASSERT_COND(iPar != NULL);
124709 + /* Get the irq host */
124710 + irqHost = irq_find_host(iPar);
124711 + of_node_put(iPar);
124712 +
124713 + /* Create irq mapping */
124714 + return irq_create_mapping(irqHost, hwIrq);
124715 +}
124716 +#else
124717 +#error "kernel not supported!!!"
124718 +#endif /* LINUX_VERSION_CODE */
124719 +
124720 +void * XX_PhysToVirt(physAddress_t addr)
124721 +{
124722 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
124723 +}
124724 +
124725 +physAddress_t XX_VirtToPhys(void * addr)
124726 +{
124727 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
124728 +}
124729 +
124730 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
124731 +{
124732 + uintptr_t *returnCode, tmp;
124733 +
124734 + if (alignment < sizeof(uintptr_t))
124735 + alignment = sizeof(uintptr_t);
124736 + size += alignment + sizeof(returnCode);
124737 + tmp = (uintptr_t)xx_Malloc(size);
124738 + if (tmp == 0)
124739 + return NULL;
124740 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
124741 + *(returnCode - 1) = tmp;
124742 +
124743 + return (void*)returnCode;
124744 +}
124745 +
124746 +void xx_FreeSmart(void *p)
124747 +{
124748 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
124749 +}
124750 diff --git a/drivers/staging/fsl_qbman/Kconfig b/drivers/staging/fsl_qbman/Kconfig
124751 new file mode 100644
124752 index 00000000..93dcb7d3
124753 --- /dev/null
124754 +++ b/drivers/staging/fsl_qbman/Kconfig
124755 @@ -0,0 +1,228 @@
124756 +config FSL_SDK_DPA
124757 + bool "Freescale Datapath Queue and Buffer management"
124758 + depends on !FSL_DPAA
124759 + select FSL_QMAN_FQ_LOOKUP if PPC64
124760 + select FSL_QMAN_FQ_LOOKUP if ARM64
124761 +
124762 +
124763 +menu "Freescale Datapath QMan/BMan options"
124764 + depends on FSL_SDK_DPA
124765 +
124766 +config FSL_DPA_CHECKING
124767 + bool "additional driver checking"
124768 + default n
124769 + ---help---
124770 + Compiles in additional checks to sanity-check the drivers and any
124771 + use of it by other code. Not recommended for performance.
124772 +
124773 +config FSL_DPA_CAN_WAIT
124774 + bool
124775 + default y
124776 +
124777 +config FSL_DPA_CAN_WAIT_SYNC
124778 + bool
124779 + default y
124780 +
124781 +config FSL_DPA_PIRQ_FAST
124782 + bool
124783 + default y
124784 +
124785 +config FSL_DPA_PIRQ_SLOW
124786 + bool
124787 + default y
124788 +
124789 +config FSL_DPA_PORTAL_SHARE
124790 + bool
124791 + default y
124792 +
124793 +config FSL_SDK_BMAN
124794 + bool "Freescale Buffer Manager (BMan) support"
124795 + default y
124796 +
124797 +if FSL_SDK_BMAN
124798 +
124799 +config FSL_BMAN_CONFIG
124800 + bool "BMan device management"
124801 + default y
124802 + ---help---
124803 + If this linux image is running natively, you need this option. If this
124804 + linux image is running as a guest OS under the hypervisor, only one
124805 + guest OS ("the control plane") needs this option.
124806 +
124807 +config FSL_BMAN_TEST
124808 + tristate "BMan self-tests"
124809 + default n
124810 + ---help---
124811 + This option compiles self-test code for BMan.
124812 +
124813 +config FSL_BMAN_TEST_HIGH
124814 + bool "BMan high-level self-test"
124815 + depends on FSL_BMAN_TEST
124816 + default y
124817 + ---help---
124818 + This requires the presence of cpu-affine portals, and performs
124819 + high-level API testing with them (whichever portal(s) are affine to
124820 + the cpu(s) the test executes on).
124821 +
124822 +config FSL_BMAN_TEST_THRESH
124823 + bool "BMan threshold test"
124824 + depends on FSL_BMAN_TEST
124825 + default y
124826 + ---help---
124827 + Multi-threaded (SMP) test of BMan pool depletion. A pool is seeded
124828 + before multiple threads (one per cpu) create pool objects to track
124829 + depletion state changes. The pool is then drained to empty by a
124830 + "drainer" thread, and the other threads that they observe exactly
124831 + the depletion state changes that are expected.
124832 +
124833 +config FSL_BMAN_DEBUGFS
124834 + tristate "BMan debugfs interface"
124835 + depends on DEBUG_FS
124836 + default y
124837 + ---help---
124838 + This option compiles debugfs code for BMan.
124839 +
124840 +endif # FSL_SDK_BMAN
124841 +
124842 +config FSL_SDK_QMAN
124843 + bool "Freescale Queue Manager (QMan) support"
124844 + default y
124845 +
124846 +if FSL_SDK_QMAN
124847 +
124848 +config FSL_QMAN_POLL_LIMIT
124849 + int
124850 + default 32
124851 +
124852 +config FSL_QMAN_CONFIG
124853 + bool "QMan device management"
124854 + default y
124855 + ---help---
124856 + If this linux image is running natively, you need this option. If this
124857 + linux image is running as a guest OS under the hypervisor, only one
124858 + guest OS ("the control plane") needs this option.
124859 +
124860 +config FSL_QMAN_TEST
124861 + tristate "QMan self-tests"
124862 + default n
124863 + ---help---
124864 + This option compiles self-test code for QMan.
124865 +
124866 +config FSL_QMAN_TEST_STASH_POTATO
124867 + bool "QMan 'hot potato' data-stashing self-test"
124868 + depends on FSL_QMAN_TEST
124869 + default y
124870 + ---help---
124871 + This performs a "hot potato" style test enqueuing/dequeuing a frame
124872 + across a series of FQs scheduled to different portals (and cpus), with
124873 + DQRR, data and context stashing always on.
124874 +
124875 +config FSL_QMAN_TEST_HIGH
124876 + bool "QMan high-level self-test"
124877 + depends on FSL_QMAN_TEST
124878 + default y
124879 + ---help---
124880 + This requires the presence of cpu-affine portals, and performs
124881 + high-level API testing with them (whichever portal(s) are affine to
124882 + the cpu(s) the test executes on).
124883 +
124884 +config FSL_QMAN_DEBUGFS
124885 + tristate "QMan debugfs interface"
124886 + depends on DEBUG_FS
124887 + default y
124888 + ---help---
124889 + This option compiles debugfs code for QMan.
124890 +
124891 +# H/w settings that can be hard-coded for now.
124892 +config FSL_QMAN_FQD_SZ
124893 + int "size of Frame Queue Descriptor region"
124894 + default 10
124895 + ---help---
124896 + This is the size of the FQD region defined as: PAGE_SIZE * (2^value)
124897 + ex: 10 => PAGE_SIZE * (2^10)
124898 + Note: Default device-trees now require minimum Kconfig setting of 10.
124899 +
124900 +config FSL_QMAN_PFDR_SZ
124901 + int "size of the PFDR pool"
124902 + default 13
124903 + ---help---
124904 + This is the size of the PFDR pool defined as: PAGE_SIZE * (2^value)
124905 + ex: 13 => PAGE_SIZE * (2^13)
124906 +
124907 +# Corenet initiator settings. Stash request queues are 4-deep to match cores'
124908 +# ability to snart. Stash priority is 3, other priorities are 2.
124909 +config FSL_QMAN_CI_SCHED_CFG_SRCCIV
124910 + int
124911 + depends on FSL_QMAN_CONFIG
124912 + default 4
124913 +config FSL_QMAN_CI_SCHED_CFG_SRQ_W
124914 + int
124915 + depends on FSL_QMAN_CONFIG
124916 + default 3
124917 +config FSL_QMAN_CI_SCHED_CFG_RW_W
124918 + int
124919 + depends on FSL_QMAN_CONFIG
124920 + default 2
124921 +config FSL_QMAN_CI_SCHED_CFG_BMAN_W
124922 + int
124923 + depends on FSL_QMAN_CONFIG
124924 + default 2
124925 +
124926 +# portal interrupt settings
124927 +config FSL_QMAN_PIRQ_DQRR_ITHRESH
124928 + int
124929 + default 12
124930 +config FSL_QMAN_PIRQ_MR_ITHRESH
124931 + int
124932 + default 4
124933 +config FSL_QMAN_PIRQ_IPERIOD
124934 + int
124935 + default 100
124936 +
124937 +# 64 bit kernel support
124938 +config FSL_QMAN_FQ_LOOKUP
124939 + bool
124940 + default n
124941 +
124942 +config QMAN_CEETM_UPDATE_PERIOD
124943 + int "Token update period for shaping, in nanoseconds"
124944 + default 1000
124945 + ---help---
124946 + Traffic shaping works by performing token calculations (using
124947 + credits) on shaper instances periodically. This update period
124948 + sets the granularity for how often those token rate credit
124949 + updates are performed, and thus determines the accuracy and
124950 + range of traffic rates that can be configured by users. The
124951 + reference manual recommends a 1 microsecond period as providing
124952 + a good balance between granularity and range.
124953 +
124954 + Unless you know what you are doing, leave this value at its default.
124955 +
124956 +config FSL_QMAN_INIT_TIMEOUT
124957 + int "timeout for qman init stage, in seconds"
124958 + default 10
124959 + ---help---
124960 + The timeout setting to quit the initialization loop for non-control
124961 + partition in case the control partition fails to boot-up.
124962 +
124963 +endif # FSL_SDK_QMAN
124964 +
124965 +config FSL_USDPAA
124966 + bool "Freescale USDPAA process driver"
124967 + depends on FSL_SDK_DPA
124968 + default y
124969 + ---help---
124970 + This driver provides user-space access to kernel-managed
124971 + resource interfaces for USDPAA applications, on the assumption
124972 + that each process will open this device once. Specifically, this
124973 + device exposes functionality that would be awkward if exposed
124974 + via the portal devices - ie. this device exposes functionality
124975 + that is inherently process-wide rather than portal-specific.
124976 + This device is necessary for obtaining access to DMA memory and
124977 + for allocation of Qman and Bman resources. In short, if you wish
124978 + to use USDPAA applications, you need this.
124979 +
124980 + If unsure, say Y.
124981 +
124982 +
124983 +endmenu
124984 diff --git a/drivers/staging/fsl_qbman/Makefile b/drivers/staging/fsl_qbman/Makefile
124985 new file mode 100644
124986 index 00000000..777d7d34
124987 --- /dev/null
124988 +++ b/drivers/staging/fsl_qbman/Makefile
124989 @@ -0,0 +1,28 @@
124990 +subdir-ccflags-y := -Werror
124991 +
124992 +# Common
124993 +obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o
124994 +obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o
124995 +
124996 +# Bman
124997 +obj-$(CONFIG_FSL_SDK_BMAN) += bman_high.o
124998 +obj-$(CONFIG_FSL_BMAN_CONFIG) += bman_config.o bman_driver.o
124999 +obj-$(CONFIG_FSL_BMAN_TEST) += bman_tester.o
125000 +obj-$(CONFIG_FSL_BMAN_DEBUGFS) += bman_debugfs_interface.o
125001 +bman_tester-y = bman_test.o
125002 +bman_tester-$(CONFIG_FSL_BMAN_TEST_HIGH) += bman_test_high.o
125003 +bman_tester-$(CONFIG_FSL_BMAN_TEST_THRESH) += bman_test_thresh.o
125004 +bman_debugfs_interface-y = bman_debugfs.o
125005 +
125006 +# Qman
125007 +obj-$(CONFIG_FSL_SDK_QMAN) += qman_high.o qman_utility.o
125008 +obj-$(CONFIG_FSL_QMAN_CONFIG) += qman_config.o qman_driver.o
125009 +obj-$(CONFIG_FSL_QMAN_TEST) += qman_tester.o
125010 +qman_tester-y = qman_test.o
125011 +qman_tester-$(CONFIG_FSL_QMAN_TEST_STASH_POTATO) += qman_test_hotpotato.o
125012 +qman_tester-$(CONFIG_FSL_QMAN_TEST_HIGH) += qman_test_high.o
125013 +obj-$(CONFIG_FSL_QMAN_DEBUGFS) += qman_debugfs_interface.o
125014 +qman_debugfs_interface-y = qman_debugfs.o
125015 +
125016 +# USDPAA
125017 +obj-$(CONFIG_FSL_USDPAA) += fsl_usdpaa.o fsl_usdpaa_irq.o
125018 diff --git a/drivers/staging/fsl_qbman/bman_config.c b/drivers/staging/fsl_qbman/bman_config.c
125019 new file mode 100644
125020 index 00000000..bb397730
125021 --- /dev/null
125022 +++ b/drivers/staging/fsl_qbman/bman_config.c
125023 @@ -0,0 +1,720 @@
125024 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc.
125025 + *
125026 + * Redistribution and use in source and binary forms, with or without
125027 + * modification, are permitted provided that the following conditions are met:
125028 + * * Redistributions of source code must retain the above copyright
125029 + * notice, this list of conditions and the following disclaimer.
125030 + * * Redistributions in binary form must reproduce the above copyright
125031 + * notice, this list of conditions and the following disclaimer in the
125032 + * documentation and/or other materials provided with the distribution.
125033 + * * Neither the name of Freescale Semiconductor nor the
125034 + * names of its contributors may be used to endorse or promote products
125035 + * derived from this software without specific prior written permission.
125036 + *
125037 + *
125038 + * ALTERNATIVELY, this software may be distributed under the terms of the
125039 + * GNU General Public License ("GPL") as published by the Free Software
125040 + * Foundation, either version 2 of that License or (at your option) any
125041 + * later version.
125042 + *
125043 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125044 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125045 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125046 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125047 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125048 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125049 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125050 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125051 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125052 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125053 + */
125054 +
125055 +#include <asm/cacheflush.h>
125056 +#include "bman_private.h"
125057 +#include <linux/of_reserved_mem.h>
125058 +
125059 +/* Last updated for v00.79 of the BG */
125060 +
125061 +struct bman;
125062 +
125063 +/* Register offsets */
125064 +#define REG_POOL_SWDET(n) (0x0000 + ((n) * 0x04))
125065 +#define REG_POOL_HWDET(n) (0x0100 + ((n) * 0x04))
125066 +#define REG_POOL_SWDXT(n) (0x0200 + ((n) * 0x04))
125067 +#define REG_POOL_HWDXT(n) (0x0300 + ((n) * 0x04))
125068 +#define REG_POOL_CONTENT(n) (0x0600 + ((n) * 0x04))
125069 +#define REG_FBPR_FPC 0x0800
125070 +#define REG_STATE_IDLE 0x960
125071 +#define REG_STATE_STOP 0x964
125072 +#define REG_ECSR 0x0a00
125073 +#define REG_ECIR 0x0a04
125074 +#define REG_EADR 0x0a08
125075 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
125076 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
125077 +#define REG_IP_REV_1 0x0bf8
125078 +#define REG_IP_REV_2 0x0bfc
125079 +#define REG_FBPR_BARE 0x0c00
125080 +#define REG_FBPR_BAR 0x0c04
125081 +#define REG_FBPR_AR 0x0c10
125082 +#define REG_SRCIDR 0x0d04
125083 +#define REG_LIODNR 0x0d08
125084 +#define REG_ERR_ISR 0x0e00 /* + "enum bm_isr_reg" */
125085 +
125086 +/* Used by all error interrupt registers except 'inhibit' */
125087 +#define BM_EIRQ_IVCI 0x00000010 /* Invalid Command Verb */
125088 +#define BM_EIRQ_FLWI 0x00000008 /* FBPR Low Watermark */
125089 +#define BM_EIRQ_MBEI 0x00000004 /* Multi-bit ECC Error */
125090 +#define BM_EIRQ_SBEI 0x00000002 /* Single-bit ECC Error */
125091 +#define BM_EIRQ_BSCN 0x00000001 /* pool State Change Notification */
125092 +
125093 +/* BMAN_ECIR valid error bit */
125094 +#define PORTAL_ECSR_ERR (BM_EIRQ_IVCI)
125095 +
125096 +union bman_ecir {
125097 + u32 ecir_raw;
125098 + struct {
125099 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
125100 + u32 __reserved1:4;
125101 + u32 portal_num:4;
125102 + u32 __reserved2:12;
125103 + u32 numb:4;
125104 + u32 __reserved3:2;
125105 + u32 pid:6;
125106 +#else
125107 + u32 pid:6;
125108 + u32 __reserved3:2;
125109 + u32 numb:4;
125110 + u32 __reserved2:12;
125111 + u32 portal_num:4;
125112 + u32 __reserved1:4;
125113 +#endif
125114 + } __packed info;
125115 +};
125116 +
125117 +union bman_eadr {
125118 + u32 eadr_raw;
125119 + struct {
125120 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
125121 + u32 __reserved1:5;
125122 + u32 memid:3;
125123 + u32 __reserved2:14;
125124 + u32 eadr:10;
125125 +#else
125126 + u32 eadr:10;
125127 + u32 __reserved2:14;
125128 + u32 memid:3;
125129 + u32 __reserved1:5;
125130 +#endif
125131 + } __packed info;
125132 +};
125133 +
125134 +struct bman_hwerr_txt {
125135 + u32 mask;
125136 + const char *txt;
125137 +};
125138 +
125139 +#define BMAN_HWE_TXT(a, b) { .mask = BM_EIRQ_##a, .txt = b }
125140 +
125141 +static const struct bman_hwerr_txt bman_hwerr_txts[] = {
125142 + BMAN_HWE_TXT(IVCI, "Invalid Command Verb"),
125143 + BMAN_HWE_TXT(FLWI, "FBPR Low Watermark"),
125144 + BMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
125145 + BMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
125146 + BMAN_HWE_TXT(BSCN, "Pool State Change Notification"),
125147 +};
125148 +#define BMAN_HWE_COUNT (sizeof(bman_hwerr_txts)/sizeof(struct bman_hwerr_txt))
125149 +
125150 +struct bman_error_info_mdata {
125151 + u16 addr_mask;
125152 + u16 bits;
125153 + const char *txt;
125154 +};
125155 +
125156 +#define BMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
125157 +static const struct bman_error_info_mdata error_mdata[] = {
125158 + BMAN_ERR_MDATA(0x03FF, 192, "Stockpile memory"),
125159 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 1"),
125160 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 2"),
125161 +};
125162 +#define BMAN_ERR_MDATA_COUNT \
125163 + (sizeof(error_mdata)/sizeof(struct bman_error_info_mdata))
125164 +
125165 +/* Add this in Kconfig */
125166 +#define BMAN_ERRS_TO_UNENABLE (BM_EIRQ_FLWI)
125167 +
125168 +/**
125169 + * bm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
125170 + * @v: for accessors that write values, this is the 32-bit value
125171 + *
125172 + * Manipulates BMAN_ERR_ISR, BMAN_ERR_IER, BMAN_ERR_ISDR, BMAN_ERR_IIR. All
125173 + * manipulations except bm_err_isr_[un]inhibit() use 32-bit masks composed of
125174 + * the BM_EIRQ_*** definitions. Note that "bm_err_isr_enable_write" means
125175 + * "write the enable register" rather than "enable the write register"!
125176 + */
125177 +#define bm_err_isr_status_read(bm) \
125178 + __bm_err_isr_read(bm, bm_isr_status)
125179 +#define bm_err_isr_status_clear(bm, m) \
125180 + __bm_err_isr_write(bm, bm_isr_status, m)
125181 +#define bm_err_isr_enable_read(bm) \
125182 + __bm_err_isr_read(bm, bm_isr_enable)
125183 +#define bm_err_isr_enable_write(bm, v) \
125184 + __bm_err_isr_write(bm, bm_isr_enable, v)
125185 +#define bm_err_isr_disable_read(bm) \
125186 + __bm_err_isr_read(bm, bm_isr_disable)
125187 +#define bm_err_isr_disable_write(bm, v) \
125188 + __bm_err_isr_write(bm, bm_isr_disable, v)
125189 +#define bm_err_isr_inhibit(bm) \
125190 + __bm_err_isr_write(bm, bm_isr_inhibit, 1)
125191 +#define bm_err_isr_uninhibit(bm) \
125192 + __bm_err_isr_write(bm, bm_isr_inhibit, 0)
125193 +
125194 +/*
125195 + * TODO: unimplemented registers
125196 + *
125197 + * BMAN_POOLk_SDCNT, BMAN_POOLk_HDCNT, BMAN_FULT,
125198 + * BMAN_VLDPL, BMAN_EECC, BMAN_SBET, BMAN_EINJ
125199 + */
125200 +
125201 +/* Encapsulate "struct bman *" as a cast of the register space address. */
125202 +
125203 +static struct bman *bm_create(void *regs)
125204 +{
125205 + return (struct bman *)regs;
125206 +}
125207 +
125208 +static inline u32 __bm_in(struct bman *bm, u32 offset)
125209 +{
125210 + return in_be32((void *)bm + offset);
125211 +}
125212 +static inline void __bm_out(struct bman *bm, u32 offset, u32 val)
125213 +{
125214 + out_be32((void *)bm + offset, val);
125215 +}
125216 +#define bm_in(reg) __bm_in(bm, REG_##reg)
125217 +#define bm_out(reg, val) __bm_out(bm, REG_##reg, val)
125218 +
125219 +static u32 __bm_err_isr_read(struct bman *bm, enum bm_isr_reg n)
125220 +{
125221 + return __bm_in(bm, REG_ERR_ISR + (n << 2));
125222 +}
125223 +
125224 +static void __bm_err_isr_write(struct bman *bm, enum bm_isr_reg n, u32 val)
125225 +{
125226 + __bm_out(bm, REG_ERR_ISR + (n << 2), val);
125227 +}
125228 +
125229 +static void bm_get_version(struct bman *bm, u16 *id, u8 *major, u8 *minor)
125230 +{
125231 + u32 v = bm_in(IP_REV_1);
125232 + *id = (v >> 16);
125233 + *major = (v >> 8) & 0xff;
125234 + *minor = v & 0xff;
125235 +}
125236 +
125237 +static u32 __generate_thresh(u32 val, int roundup)
125238 +{
125239 + u32 e = 0; /* co-efficient, exponent */
125240 + int oddbit = 0;
125241 + while (val > 0xff) {
125242 + oddbit = val & 1;
125243 + val >>= 1;
125244 + e++;
125245 + if (roundup && oddbit)
125246 + val++;
125247 + }
125248 + DPA_ASSERT(e < 0x10);
125249 + return val | (e << 8);
125250 +}
125251 +
125252 +static void bm_set_pool(struct bman *bm, u8 pool, u32 swdet, u32 swdxt,
125253 + u32 hwdet, u32 hwdxt)
125254 +{
125255 + DPA_ASSERT(pool < bman_pool_max);
125256 + bm_out(POOL_SWDET(pool), __generate_thresh(swdet, 0));
125257 + bm_out(POOL_SWDXT(pool), __generate_thresh(swdxt, 1));
125258 + bm_out(POOL_HWDET(pool), __generate_thresh(hwdet, 0));
125259 + bm_out(POOL_HWDXT(pool), __generate_thresh(hwdxt, 1));
125260 +}
125261 +
125262 +static void bm_set_memory(struct bman *bm, u64 ba, int prio, u32 size)
125263 +{
125264 + u32 exp = ilog2(size);
125265 + /* choke if size isn't within range */
125266 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
125267 + is_power_of_2(size));
125268 + /* choke if '[e]ba' has lower-alignment than 'size' */
125269 + DPA_ASSERT(!(ba & (size - 1)));
125270 + bm_out(FBPR_BARE, upper_32_bits(ba));
125271 + bm_out(FBPR_BAR, lower_32_bits(ba));
125272 + bm_out(FBPR_AR, (prio ? 0x40000000 : 0) | (exp - 1));
125273 +}
125274 +
125275 +/*****************/
125276 +/* Config driver */
125277 +/*****************/
125278 +
125279 +/* TODO: Kconfig these? */
125280 +#define DEFAULT_FBPR_SZ (PAGE_SIZE << 12)
125281 +
125282 +/* We support only one of these. */
125283 +static struct bman *bm;
125284 +static struct device_node *bm_node;
125285 +
125286 +/* And this state belongs to 'bm'. It is set during fsl_bman_init(), but used
125287 + * during bman_init_ccsr(). */
125288 +static dma_addr_t fbpr_a;
125289 +static size_t fbpr_sz = DEFAULT_FBPR_SZ;
125290 +
125291 +static int bman_fbpr(struct reserved_mem *rmem)
125292 +{
125293 + fbpr_a = rmem->base;
125294 + fbpr_sz = rmem->size;
125295 +
125296 + WARN_ON(!(fbpr_a && fbpr_sz));
125297 +
125298 + return 0;
125299 +}
125300 +RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr);
125301 +
125302 +static int __init fsl_bman_init(struct device_node *node)
125303 +{
125304 + struct resource res;
125305 + u32 __iomem *regs;
125306 + const char *s;
125307 + int ret, standby = 0;
125308 + u16 id;
125309 + u8 major, minor;
125310 +
125311 + ret = of_address_to_resource(node, 0, &res);
125312 + if (ret) {
125313 + pr_err("Can't get %s property 'reg'\n",
125314 + node->full_name);
125315 + return ret;
125316 + }
125317 + s = of_get_property(node, "fsl,hv-claimable", &ret);
125318 + if (s && !strcmp(s, "standby"))
125319 + standby = 1;
125320 + /* Global configuration */
125321 + regs = ioremap(res.start, res.end - res.start + 1);
125322 + bm = bm_create(regs);
125323 + BUG_ON(!bm);
125324 + bm_node = node;
125325 + bm_get_version(bm, &id, &major, &minor);
125326 + pr_info("Bman ver:%04x,%02x,%02x\n", id, major, minor);
125327 + if ((major == 1) && (minor == 0)) {
125328 + bman_ip_rev = BMAN_REV10;
125329 + bman_pool_max = 64;
125330 + } else if ((major == 2) && (minor == 0)) {
125331 + bman_ip_rev = BMAN_REV20;
125332 + bman_pool_max = 8;
125333 + } else if ((major == 2) && (minor == 1)) {
125334 + bman_ip_rev = BMAN_REV21;
125335 + bman_pool_max = 64;
125336 + } else {
125337 + pr_warn("unknown Bman version, default to rev1.0\n");
125338 + }
125339 +
125340 + if (standby) {
125341 + pr_info(" -> in standby mode\n");
125342 + return 0;
125343 + }
125344 + return 0;
125345 +}
125346 +
125347 +int bman_have_ccsr(void)
125348 +{
125349 + return bm ? 1 : 0;
125350 +}
125351 +
125352 +int bm_pool_set(u32 bpid, const u32 *thresholds)
125353 +{
125354 + if (!bm)
125355 + return -ENODEV;
125356 + bm_set_pool(bm, bpid, thresholds[0],
125357 + thresholds[1], thresholds[2],
125358 + thresholds[3]);
125359 + return 0;
125360 +}
125361 +EXPORT_SYMBOL(bm_pool_set);
125362 +
125363 +__init int bman_init_early(void)
125364 +{
125365 + struct device_node *dn;
125366 + int ret;
125367 +
125368 + for_each_compatible_node(dn, NULL, "fsl,bman") {
125369 + if (bm)
125370 + pr_err("%s: only one 'fsl,bman' allowed\n",
125371 + dn->full_name);
125372 + else {
125373 + if (!of_device_is_available(dn))
125374 + continue;
125375 +
125376 + ret = fsl_bman_init(dn);
125377 + BUG_ON(ret);
125378 + }
125379 + }
125380 + return 0;
125381 +}
125382 +postcore_initcall_sync(bman_init_early);
125383 +
125384 +
125385 +static void log_edata_bits(u32 bit_count)
125386 +{
125387 + u32 i, j, mask = 0xffffffff;
125388 +
125389 + pr_warn("Bman ErrInt, EDATA:\n");
125390 + i = bit_count/32;
125391 + if (bit_count%32) {
125392 + i++;
125393 + mask = ~(mask << bit_count%32);
125394 + }
125395 + j = 16-i;
125396 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)) & mask);
125397 + j++;
125398 + for (; j < 16; j++)
125399 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)));
125400 +}
125401 +
125402 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
125403 +{
125404 + union bman_ecir ecir_val;
125405 + union bman_eadr eadr_val;
125406 +
125407 + ecir_val.ecir_raw = bm_in(ECIR);
125408 + /* Is portal info valid */
125409 + if (ecsr_val & PORTAL_ECSR_ERR) {
125410 + pr_warn("Bman ErrInt: SWP id %d, numb %d, pid %d\n",
125411 + ecir_val.info.portal_num, ecir_val.info.numb,
125412 + ecir_val.info.pid);
125413 + }
125414 + if (ecsr_val & (BM_EIRQ_SBEI|BM_EIRQ_MBEI)) {
125415 + eadr_val.eadr_raw = bm_in(EADR);
125416 + pr_warn("Bman ErrInt: EADR Memory: %s, 0x%x\n",
125417 + error_mdata[eadr_val.info.memid].txt,
125418 + error_mdata[eadr_val.info.memid].addr_mask
125419 + & eadr_val.info.eadr);
125420 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
125421 + }
125422 +}
125423 +
125424 +/* Bman interrupt handler */
125425 +static irqreturn_t bman_isr(int irq, void *ptr)
125426 +{
125427 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
125428 +
125429 + ier_val = bm_err_isr_enable_read(bm);
125430 + isr_val = bm_err_isr_status_read(bm);
125431 + ecsr_val = bm_in(ECSR);
125432 + isr_mask = isr_val & ier_val;
125433 +
125434 + if (!isr_mask)
125435 + return IRQ_NONE;
125436 + for (i = 0; i < BMAN_HWE_COUNT; i++) {
125437 + if (bman_hwerr_txts[i].mask & isr_mask) {
125438 + pr_warn("Bman ErrInt: %s\n", bman_hwerr_txts[i].txt);
125439 + if (bman_hwerr_txts[i].mask & ecsr_val) {
125440 + log_additional_error_info(isr_mask, ecsr_val);
125441 + /* Re-arm error capture registers */
125442 + bm_out(ECSR, ecsr_val);
125443 + }
125444 + if (bman_hwerr_txts[i].mask & BMAN_ERRS_TO_UNENABLE) {
125445 + pr_devel("Bman un-enabling error 0x%x\n",
125446 + bman_hwerr_txts[i].mask);
125447 + ier_val &= ~bman_hwerr_txts[i].mask;
125448 + bm_err_isr_enable_write(bm, ier_val);
125449 + }
125450 + }
125451 + }
125452 + bm_err_isr_status_clear(bm, isr_val);
125453 + return IRQ_HANDLED;
125454 +}
125455 +
125456 +static int __bind_irq(void)
125457 +{
125458 + int ret, err_irq;
125459 +
125460 + err_irq = of_irq_to_resource(bm_node, 0, NULL);
125461 + if (err_irq == 0) {
125462 + pr_info("Can't get %s property '%s'\n", bm_node->full_name,
125463 + "interrupts");
125464 + return -ENODEV;
125465 + }
125466 + ret = request_irq(err_irq, bman_isr, IRQF_SHARED, "bman-err", bm_node);
125467 + if (ret) {
125468 + pr_err("request_irq() failed %d for '%s'\n", ret,
125469 + bm_node->full_name);
125470 + return -ENODEV;
125471 + }
125472 + /* Disable Buffer Pool State Change */
125473 + bm_err_isr_disable_write(bm, BM_EIRQ_BSCN);
125474 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
125475 + * to resource allocation during driver init). */
125476 + bm_err_isr_status_clear(bm, 0xffffffff);
125477 + /* Enable Error Interrupts */
125478 + bm_err_isr_enable_write(bm, 0xffffffff);
125479 + return 0;
125480 +}
125481 +
125482 +int bman_init_ccsr(struct device_node *node)
125483 +{
125484 + int ret;
125485 + if (!bman_have_ccsr())
125486 + return 0;
125487 + if (node != bm_node)
125488 + return -EINVAL;
125489 + /* FBPR memory */
125490 + bm_set_memory(bm, fbpr_a, 0, fbpr_sz);
125491 + pr_info("bman-fbpr addr %pad size 0x%zx\n", &fbpr_a, fbpr_sz);
125492 +
125493 + ret = __bind_irq();
125494 + if (ret)
125495 + return ret;
125496 + return 0;
125497 +}
125498 +
125499 +u32 bm_pool_free_buffers(u32 bpid)
125500 +{
125501 + return bm_in(POOL_CONTENT(bpid));
125502 +}
125503 +
125504 +#ifdef CONFIG_SYSFS
125505 +
125506 +#define DRV_NAME "fsl-bman"
125507 +#define SBEC_MAX_ID 1
125508 +#define SBEC_MIN_ID 0
125509 +
125510 +static ssize_t show_fbpr_fpc(struct device *dev,
125511 + struct device_attribute *dev_attr, char *buf)
125512 +{
125513 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(FBPR_FPC));
125514 +};
125515 +
125516 +static ssize_t show_pool_count(struct device *dev,
125517 + struct device_attribute *dev_attr, char *buf)
125518 +{
125519 + u32 data;
125520 + int i;
125521 +
125522 + if (!sscanf(dev_attr->attr.name, "%d", &i) || (i >= bman_pool_max))
125523 + return -EINVAL;
125524 + data = bm_in(POOL_CONTENT(i));
125525 + return snprintf(buf, PAGE_SIZE, "%d\n", data);
125526 +};
125527 +
125528 +static ssize_t show_err_isr(struct device *dev,
125529 + struct device_attribute *dev_attr, char *buf)
125530 +{
125531 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", bm_in(ERR_ISR));
125532 +};
125533 +
125534 +static ssize_t show_sbec(struct device *dev,
125535 + struct device_attribute *dev_attr, char *buf)
125536 +{
125537 + int i;
125538 +
125539 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
125540 + return -EINVAL;
125541 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
125542 + return -EINVAL;
125543 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(SBEC(i)));
125544 +};
125545 +
125546 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
125547 +static DEVICE_ATTR(fbpr_fpc, S_IRUSR, show_fbpr_fpc, NULL);
125548 +
125549 +/* Didn't use DEVICE_ATTR as 64 of this would be required.
125550 + * Initialize them when needed. */
125551 +static char *name_attrs_pool_count; /* "xx" + null-terminator */
125552 +static struct device_attribute *dev_attr_buffer_pool_count;
125553 +
125554 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
125555 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
125556 +
125557 +static struct attribute *bman_dev_attributes[] = {
125558 + &dev_attr_fbpr_fpc.attr,
125559 + &dev_attr_err_isr.attr,
125560 + NULL
125561 +};
125562 +
125563 +static struct attribute *bman_dev_ecr_attributes[] = {
125564 + &dev_attr_sbec_0.attr,
125565 + &dev_attr_sbec_1.attr,
125566 + NULL
125567 +};
125568 +
125569 +static struct attribute **bman_dev_pool_count_attributes;
125570 +
125571 +
125572 +/* root level */
125573 +static const struct attribute_group bman_dev_attr_grp = {
125574 + .name = NULL,
125575 + .attrs = bman_dev_attributes
125576 +};
125577 +static const struct attribute_group bman_dev_ecr_grp = {
125578 + .name = "error_capture",
125579 + .attrs = bman_dev_ecr_attributes
125580 +};
125581 +static struct attribute_group bman_dev_pool_countent_grp = {
125582 + .name = "pool_count",
125583 +};
125584 +
125585 +static int of_fsl_bman_remove(struct platform_device *ofdev)
125586 +{
125587 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125588 + return 0;
125589 +};
125590 +
125591 +static int of_fsl_bman_probe(struct platform_device *ofdev)
125592 +{
125593 + int ret, i;
125594 +
125595 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125596 + if (ret)
125597 + goto done;
125598 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
125599 + if (ret)
125600 + goto del_group_0;
125601 +
125602 + name_attrs_pool_count = kmalloc(sizeof(char) * bman_pool_max * 3,
125603 + GFP_KERNEL);
125604 + if (!name_attrs_pool_count) {
125605 + pr_err("Can't alloc name_attrs_pool_count\n");
125606 + goto del_group_1;
125607 + }
125608 +
125609 + dev_attr_buffer_pool_count = kmalloc(sizeof(struct device_attribute) *
125610 + bman_pool_max, GFP_KERNEL);
125611 + if (!dev_attr_buffer_pool_count) {
125612 + pr_err("Can't alloc dev_attr-buffer_pool_count\n");
125613 + goto del_group_2;
125614 + }
125615 +
125616 + bman_dev_pool_count_attributes = kmalloc(sizeof(struct attribute *) *
125617 + (bman_pool_max + 1), GFP_KERNEL);
125618 + if (!bman_dev_pool_count_attributes) {
125619 + pr_err("can't alloc bman_dev_pool_count_attributes\n");
125620 + goto del_group_3;
125621 + }
125622 +
125623 + for (i = 0; i < bman_pool_max; i++) {
125624 + ret = scnprintf((name_attrs_pool_count + i * 3), 3, "%d", i);
125625 + if (!ret)
125626 + goto del_group_4;
125627 + dev_attr_buffer_pool_count[i].attr.name =
125628 + (name_attrs_pool_count + i * 3);
125629 + dev_attr_buffer_pool_count[i].attr.mode = S_IRUSR;
125630 + dev_attr_buffer_pool_count[i].show = show_pool_count;
125631 + bman_dev_pool_count_attributes[i] =
125632 + &dev_attr_buffer_pool_count[i].attr;
125633 + sysfs_attr_init(bman_dev_pool_count_attributes[i]);
125634 + }
125635 + bman_dev_pool_count_attributes[bman_pool_max] = NULL;
125636 +
125637 + bman_dev_pool_countent_grp.attrs = bman_dev_pool_count_attributes;
125638 +
125639 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_pool_countent_grp);
125640 + if (ret)
125641 + goto del_group_4;
125642 +
125643 + goto done;
125644 +
125645 +del_group_4:
125646 + kfree(bman_dev_pool_count_attributes);
125647 +del_group_3:
125648 + kfree(dev_attr_buffer_pool_count);
125649 +del_group_2:
125650 + kfree(name_attrs_pool_count);
125651 +del_group_1:
125652 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
125653 +del_group_0:
125654 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125655 +done:
125656 + if (ret)
125657 + dev_err(&ofdev->dev,
125658 + "Cannot create dev attributes ret=%d\n", ret);
125659 + return ret;
125660 +};
125661 +
125662 +static struct of_device_id of_fsl_bman_ids[] = {
125663 + {
125664 + .compatible = "fsl,bman",
125665 + },
125666 + {}
125667 +};
125668 +MODULE_DEVICE_TABLE(of, of_fsl_bman_ids);
125669 +
125670 +#ifdef CONFIG_SUSPEND
125671 +static u32 saved_isdr;
125672 +
125673 +static int bman_pm_suspend_noirq(struct device *dev)
125674 +{
125675 + uint32_t idle_state;
125676 +
125677 + suspend_unused_bportal();
125678 + /* save isdr, disable all, clear isr */
125679 + saved_isdr = bm_err_isr_disable_read(bm);
125680 + bm_err_isr_disable_write(bm, 0xffffffff);
125681 + bm_err_isr_status_clear(bm, 0xffffffff);
125682 +
125683 + if (bman_ip_rev < BMAN_REV21) {
125684 +#ifdef CONFIG_PM_DEBUG
125685 + pr_info("Bman version doesn't have STATE_IDLE\n");
125686 +#endif
125687 + return 0;
125688 + }
125689 + idle_state = bm_in(STATE_IDLE);
125690 + if (!(idle_state & 0x1)) {
125691 + pr_err("Bman not idle 0x%x aborting\n", idle_state);
125692 + bm_err_isr_disable_write(bm, saved_isdr);
125693 + resume_unused_bportal();
125694 + return -EBUSY;
125695 + }
125696 +#ifdef CONFIG_PM_DEBUG
125697 + pr_info("Bman suspend code, IDLE_STAT = 0x%x\n", idle_state);
125698 +#endif
125699 + return 0;
125700 +}
125701 +
125702 +static int bman_pm_resume_noirq(struct device *dev)
125703 +{
125704 + /* restore isdr */
125705 + bm_err_isr_disable_write(bm, saved_isdr);
125706 + resume_unused_bportal();
125707 + return 0;
125708 +}
125709 +#else
125710 +#define bman_pm_suspend_noirq NULL
125711 +#define bman_pm_resume_noirq NULL
125712 +#endif
125713 +
125714 +static const struct dev_pm_ops bman_pm_ops = {
125715 + .suspend_noirq = bman_pm_suspend_noirq,
125716 + .resume_noirq = bman_pm_resume_noirq,
125717 +};
125718 +
125719 +static struct platform_driver of_fsl_bman_driver = {
125720 + .driver = {
125721 + .owner = THIS_MODULE,
125722 + .name = DRV_NAME,
125723 + .of_match_table = of_fsl_bman_ids,
125724 + .pm = &bman_pm_ops,
125725 + },
125726 + .probe = of_fsl_bman_probe,
125727 + .remove = of_fsl_bman_remove,
125728 +};
125729 +
125730 +static int bman_ctrl_init(void)
125731 +{
125732 + return platform_driver_register(&of_fsl_bman_driver);
125733 +}
125734 +
125735 +static void bman_ctrl_exit(void)
125736 +{
125737 + platform_driver_unregister(&of_fsl_bman_driver);
125738 +}
125739 +
125740 +module_init(bman_ctrl_init);
125741 +module_exit(bman_ctrl_exit);
125742 +
125743 +#endif /* CONFIG_SYSFS */
125744 diff --git a/drivers/staging/fsl_qbman/bman_debugfs.c b/drivers/staging/fsl_qbman/bman_debugfs.c
125745 new file mode 100644
125746 index 00000000..96909348
125747 --- /dev/null
125748 +++ b/drivers/staging/fsl_qbman/bman_debugfs.c
125749 @@ -0,0 +1,119 @@
125750 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
125751 + *
125752 + * Redistribution and use in source and binary forms, with or without
125753 + * modification, are permitted provided that the following conditions are met:
125754 + * * Redistributions of source code must retain the above copyright
125755 + * notice, this list of conditions and the following disclaimer.
125756 + * * Redistributions in binary form must reproduce the above copyright
125757 + * notice, this list of conditions and the following disclaimer in the
125758 + * documentation and/or other materials provided with the distribution.
125759 + * * Neither the name of Freescale Semiconductor nor the
125760 + * names of its contributors may be used to endorse or promote products
125761 + * derived from this software without specific prior written permission.
125762 + *
125763 + *
125764 + * ALTERNATIVELY, this software may be distributed under the terms of the
125765 + * GNU General Public License ("GPL") as published by the Free Software
125766 + * Foundation, either version 2 of that License or (at your option) any
125767 + * later version.
125768 + *
125769 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125770 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125771 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125772 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125773 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125774 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125775 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125776 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125777 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125778 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125779 + */
125780 +#include <linux/module.h>
125781 +#include <linux/fsl_bman.h>
125782 +#include <linux/debugfs.h>
125783 +#include <linux/seq_file.h>
125784 +#include <linux/uaccess.h>
125785 +
125786 +static struct dentry *dfs_root; /* debugfs root directory */
125787 +
125788 +/*******************************************************************************
125789 + * Query Buffer Pool State
125790 + ******************************************************************************/
125791 +static int query_bp_state_show(struct seq_file *file, void *offset)
125792 +{
125793 + int ret;
125794 + struct bm_pool_state state;
125795 + int i, j;
125796 + u32 mask;
125797 +
125798 + memset(&state, 0, sizeof(struct bm_pool_state));
125799 + ret = bman_query_pools(&state);
125800 + if (ret) {
125801 + seq_printf(file, "Error %d\n", ret);
125802 + return 0;
125803 + }
125804 + seq_puts(file, "bp_id free_buffers_avail bp_depleted\n");
125805 + for (i = 0; i < 2; i++) {
125806 + mask = 0x80000000;
125807 + for (j = 0; j < 32; j++) {
125808 + seq_printf(file,
125809 + " %-2u %-3s %-3s\n",
125810 + (i*32)+j,
125811 + (state.as.state.__state[i] & mask) ? "no" : "yes",
125812 + (state.ds.state.__state[i] & mask) ? "yes" : "no");
125813 + mask >>= 1;
125814 + }
125815 + }
125816 + return 0;
125817 +}
125818 +
125819 +static int query_bp_state_open(struct inode *inode, struct file *file)
125820 +{
125821 + return single_open(file, query_bp_state_show, NULL);
125822 +}
125823 +
125824 +static const struct file_operations query_bp_state_fops = {
125825 + .owner = THIS_MODULE,
125826 + .open = query_bp_state_open,
125827 + .read = seq_read,
125828 + .release = single_release,
125829 +};
125830 +
125831 +static int __init bman_debugfs_module_init(void)
125832 +{
125833 + int ret = 0;
125834 + struct dentry *d;
125835 +
125836 + dfs_root = debugfs_create_dir("bman", NULL);
125837 +
125838 + if (dfs_root == NULL) {
125839 + ret = -ENOMEM;
125840 + pr_err("Cannot create bman debugfs dir\n");
125841 + goto _return;
125842 + }
125843 + d = debugfs_create_file("query_bp_state",
125844 + S_IRUGO,
125845 + dfs_root,
125846 + NULL,
125847 + &query_bp_state_fops);
125848 + if (d == NULL) {
125849 + ret = -ENOMEM;
125850 + pr_err("Cannot create query_bp_state\n");
125851 + goto _return;
125852 + }
125853 + return 0;
125854 +
125855 +_return:
125856 + debugfs_remove_recursive(dfs_root);
125857 + return ret;
125858 +}
125859 +
125860 +static void __exit bman_debugfs_module_exit(void)
125861 +{
125862 + debugfs_remove_recursive(dfs_root);
125863 +}
125864 +
125865 +
125866 +module_init(bman_debugfs_module_init);
125867 +module_exit(bman_debugfs_module_exit);
125868 +MODULE_LICENSE("Dual BSD/GPL");
125869 diff --git a/drivers/staging/fsl_qbman/bman_driver.c b/drivers/staging/fsl_qbman/bman_driver.c
125870 new file mode 100644
125871 index 00000000..86fabef6
125872 --- /dev/null
125873 +++ b/drivers/staging/fsl_qbman/bman_driver.c
125874 @@ -0,0 +1,575 @@
125875 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
125876 + *
125877 + * Redistribution and use in source and binary forms, with or without
125878 + * modification, are permitted provided that the following conditions are met:
125879 + * * Redistributions of source code must retain the above copyright
125880 + * notice, this list of conditions and the following disclaimer.
125881 + * * Redistributions in binary form must reproduce the above copyright
125882 + * notice, this list of conditions and the following disclaimer in the
125883 + * documentation and/or other materials provided with the distribution.
125884 + * * Neither the name of Freescale Semiconductor nor the
125885 + * names of its contributors may be used to endorse or promote products
125886 + * derived from this software without specific prior written permission.
125887 + *
125888 + *
125889 + * ALTERNATIVELY, this software may be distributed under the terms of the
125890 + * GNU General Public License ("GPL") as published by the Free Software
125891 + * Foundation, either version 2 of that License or (at your option) any
125892 + * later version.
125893 + *
125894 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125895 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125896 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125897 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125898 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125899 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125900 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125901 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125902 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125903 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125904 + */
125905 +#include "bman_low.h"
125906 +#ifdef CONFIG_HOTPLUG_CPU
125907 +#include <linux/cpu.h>
125908 +#endif
125909 +/*
125910 + * Global variables of the max portal/pool number this bman version supported
125911 + */
125912 +u16 bman_ip_rev;
125913 +EXPORT_SYMBOL(bman_ip_rev);
125914 +u16 bman_pool_max;
125915 +EXPORT_SYMBOL(bman_pool_max);
125916 +static u16 bman_portal_max;
125917 +
125918 +/* After initialising cpus that own shared portal configs, we cache the
125919 + * resulting portals (ie. not just the configs) in this array. Then we
125920 + * initialise slave cpus that don't have their own portals, redirecting them to
125921 + * portals from this cache in a round-robin assignment. */
125922 +static struct bman_portal *shared_portals[NR_CPUS];
125923 +static int num_shared_portals;
125924 +static int shared_portals_idx;
125925 +static LIST_HEAD(unused_pcfgs);
125926 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
125927 +static void *affine_bportals[NR_CPUS];
125928 +
125929 +static int __init fsl_bpool_init(struct device_node *node)
125930 +{
125931 + int ret;
125932 + u32 *thresh, *bpid = (u32 *)of_get_property(node, "fsl,bpid", &ret);
125933 + if (!bpid || (ret != 4)) {
125934 + pr_err("Can't get %s property 'fsl,bpid'\n", node->full_name);
125935 + return -ENODEV;
125936 + }
125937 + thresh = (u32 *)of_get_property(node, "fsl,bpool-thresholds", &ret);
125938 + if (thresh) {
125939 + if (ret != 16) {
125940 + pr_err("Invalid %s property '%s'\n",
125941 + node->full_name, "fsl,bpool-thresholds");
125942 + return -ENODEV;
125943 + }
125944 + }
125945 + if (thresh) {
125946 +#ifdef CONFIG_FSL_BMAN_CONFIG
125947 + ret = bm_pool_set(be32_to_cpu(*bpid), thresh);
125948 + if (ret)
125949 + pr_err("No CCSR node for %s property '%s'\n",
125950 + node->full_name, "fsl,bpool-thresholds");
125951 + return ret;
125952 +#else
125953 + pr_err("Ignoring %s property '%s', no CCSR support\n",
125954 + node->full_name, "fsl,bpool-thresholds");
125955 +#endif
125956 + }
125957 + return 0;
125958 +}
125959 +
125960 +static int __init fsl_bpid_range_init(struct device_node *node)
125961 +{
125962 + int ret;
125963 + u32 *range = (u32 *)of_get_property(node, "fsl,bpid-range", &ret);
125964 + if (!range) {
125965 + pr_err("No 'fsl,bpid-range' property in node %s\n",
125966 + node->full_name);
125967 + return -EINVAL;
125968 + }
125969 + if (ret != 8) {
125970 + pr_err("'fsl,bpid-range' is not a 2-cell range in node %s\n",
125971 + node->full_name);
125972 + return -EINVAL;
125973 + }
125974 + bman_seed_bpid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125975 + pr_info("Bman: BPID allocator includes range %d:%d\n",
125976 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125977 + return 0;
125978 +}
125979 +
125980 +static struct bm_portal_config * __init parse_pcfg(struct device_node *node)
125981 +{
125982 + struct bm_portal_config *pcfg;
125983 + const u32 *index;
125984 + int irq, ret;
125985 + resource_size_t len;
125986 +
125987 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
125988 + if (!pcfg) {
125989 + pr_err("can't allocate portal config");
125990 + return NULL;
125991 + }
125992 +
125993 + if (of_device_is_compatible(node, "fsl,bman-portal-1.0") ||
125994 + of_device_is_compatible(node, "fsl,bman-portal-1.0.0")) {
125995 + bman_ip_rev = BMAN_REV10;
125996 + bman_pool_max = 64;
125997 + bman_portal_max = 10;
125998 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.0") ||
125999 + of_device_is_compatible(node, "fsl,bman-portal-2.0.8")) {
126000 + bman_ip_rev = BMAN_REV20;
126001 + bman_pool_max = 8;
126002 + bman_portal_max = 3;
126003 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.0")) {
126004 + bman_ip_rev = BMAN_REV21;
126005 + bman_pool_max = 64;
126006 + bman_portal_max = 50;
126007 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.1")) {
126008 + bman_ip_rev = BMAN_REV21;
126009 + bman_pool_max = 64;
126010 + bman_portal_max = 25;
126011 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.2")) {
126012 + bman_ip_rev = BMAN_REV21;
126013 + bman_pool_max = 64;
126014 + bman_portal_max = 18;
126015 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.3")) {
126016 + bman_ip_rev = BMAN_REV21;
126017 + bman_pool_max = 64;
126018 + bman_portal_max = 10;
126019 + } else {
126020 + pr_warn("unknown BMan version in portal node,"
126021 + "default to rev1.0\n");
126022 + bman_ip_rev = BMAN_REV10;
126023 + bman_pool_max = 64;
126024 + bman_portal_max = 10;
126025 + }
126026 +
126027 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
126028 + &pcfg->addr_phys[DPA_PORTAL_CE]);
126029 + if (ret) {
126030 + pr_err("Can't get %s property 'reg::CE'\n", node->full_name);
126031 + goto err;
126032 + }
126033 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
126034 + &pcfg->addr_phys[DPA_PORTAL_CI]);
126035 + if (ret) {
126036 + pr_err("Can't get %s property 'reg::CI'\n", node->full_name);
126037 + goto err;
126038 + }
126039 +
126040 + index = of_get_property(node, "cell-index", &ret);
126041 + if (!index || (ret != 4)) {
126042 + pr_err("Can't get %s property '%s'\n", node->full_name,
126043 + "cell-index");
126044 + goto err;
126045 + }
126046 + if (be32_to_cpu(*index) >= bman_portal_max) {
126047 + pr_err("BMan portal cell index %d out of range, max %d\n",
126048 + be32_to_cpu(*index), bman_portal_max);
126049 + goto err;
126050 + }
126051 +
126052 + pcfg->public_cfg.cpu = -1;
126053 +
126054 + irq = irq_of_parse_and_map(node, 0);
126055 + if (irq == 0) {
126056 + pr_err("Can't get %s property 'interrupts'\n", node->full_name);
126057 + goto err;
126058 + }
126059 + pcfg->public_cfg.irq = irq;
126060 + pcfg->public_cfg.index = be32_to_cpu(*index);
126061 + bman_depletion_fill(&pcfg->public_cfg.mask);
126062 +
126063 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
126064 + if (len != (unsigned long)len)
126065 + goto err;
126066 +
126067 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
126068 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
126069 + pcfg->addr_phys[DPA_PORTAL_CE].start,
126070 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
126071 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
126072 + pcfg->addr_phys[DPA_PORTAL_CI].start,
126073 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
126074 +
126075 +#else
126076 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
126077 + pcfg->addr_phys[DPA_PORTAL_CE].start,
126078 + (unsigned long)len,
126079 + 0);
126080 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
126081 + pcfg->addr_phys[DPA_PORTAL_CI].start,
126082 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
126083 + _PAGE_GUARDED | _PAGE_NO_CACHE);
126084 +#endif
126085 + /* disable bp depletion */
126086 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(0));
126087 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(1));
126088 + return pcfg;
126089 +err:
126090 + kfree(pcfg);
126091 + return NULL;
126092 +}
126093 +
126094 +static struct bm_portal_config *get_pcfg(struct list_head *list)
126095 +{
126096 + struct bm_portal_config *pcfg;
126097 + if (list_empty(list))
126098 + return NULL;
126099 + pcfg = list_entry(list->prev, struct bm_portal_config, list);
126100 + list_del(&pcfg->list);
126101 + return pcfg;
126102 +}
126103 +
126104 +static struct bm_portal_config *get_pcfg_idx(struct list_head *list,
126105 + uint32_t idx)
126106 +{
126107 + struct bm_portal_config *pcfg;
126108 + if (list_empty(list))
126109 + return NULL;
126110 + list_for_each_entry(pcfg, list, list) {
126111 + if (pcfg->public_cfg.index == idx) {
126112 + list_del(&pcfg->list);
126113 + return pcfg;
126114 + }
126115 + }
126116 + return NULL;
126117 +}
126118 +
126119 +struct bm_portal_config *bm_get_unused_portal(void)
126120 +{
126121 + return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
126122 +}
126123 +
126124 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx)
126125 +{
126126 + struct bm_portal_config *ret;
126127 + spin_lock(&unused_pcfgs_lock);
126128 + if (idx == QBMAN_ANY_PORTAL_IDX)
126129 + ret = get_pcfg(&unused_pcfgs);
126130 + else
126131 + ret = get_pcfg_idx(&unused_pcfgs, idx);
126132 + spin_unlock(&unused_pcfgs_lock);
126133 + return ret;
126134 +}
126135 +
126136 +void bm_put_unused_portal(struct bm_portal_config *pcfg)
126137 +{
126138 + spin_lock(&unused_pcfgs_lock);
126139 + list_add(&pcfg->list, &unused_pcfgs);
126140 + spin_unlock(&unused_pcfgs_lock);
126141 +}
126142 +
126143 +static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg)
126144 +{
126145 + struct bman_portal *p;
126146 + p = bman_create_affine_portal(pcfg);
126147 + if (p) {
126148 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
126149 + bman_p_irqsource_add(p, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
126150 +#endif
126151 + pr_info("Bman portal %sinitialised, cpu %d\n",
126152 + pcfg->public_cfg.is_shared ? "(shared) " : "",
126153 + pcfg->public_cfg.cpu);
126154 + affine_bportals[pcfg->public_cfg.cpu] = p;
126155 + } else
126156 + pr_crit("Bman portal failure on cpu %d\n",
126157 + pcfg->public_cfg.cpu);
126158 + return p;
126159 +}
126160 +
126161 +static void init_slave(int cpu)
126162 +{
126163 + struct bman_portal *p;
126164 + p = bman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
126165 + if (!p)
126166 + pr_err("Bman slave portal failure on cpu %d\n", cpu);
126167 + else
126168 + pr_info("Bman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
126169 + if (shared_portals_idx >= num_shared_portals)
126170 + shared_portals_idx = 0;
126171 + affine_bportals[cpu] = p;
126172 +}
126173 +
126174 +/* Bootarg "bportals=[...]" has the same syntax as "qportals=", and so the
126175 + * parsing is in dpa_sys.h. The syntax is a comma-separated list of indexes
126176 + * and/or ranges of indexes, with each being optionally prefixed by "s" to
126177 + * explicitly mark it or them for sharing.
126178 + * Eg;
126179 + * bportals=s0,1-3,s4
126180 + * means that cpus 1,2,3 get "unshared" portals, cpus 0 and 4 get "shared"
126181 + * portals, and any remaining cpus share the portals that are assigned to cpus 0
126182 + * or 4, selected in a round-robin fashion. (In this example, cpu 5 would share
126183 + * cpu 0's portal, cpu 6 would share cpu4's portal, and cpu 7 would share cpu
126184 + * 0's portal.) */
126185 +static struct cpumask want_unshared __initdata; /* cpus requested without "s" */
126186 +static struct cpumask want_shared __initdata; /* cpus requested with "s" */
126187 +
126188 +static int __init parse_bportals(char *str)
126189 +{
126190 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
126191 + "bportals");
126192 +}
126193 +__setup("bportals=", parse_bportals);
126194 +
126195 +static int bman_offline_cpu(unsigned int cpu)
126196 +{
126197 + struct bman_portal *p;
126198 + const struct bm_portal_config *pcfg;
126199 + p = (struct bman_portal *)affine_bportals[cpu];
126200 + if (p) {
126201 + pcfg = bman_get_bm_portal_config(p);
126202 + if (pcfg)
126203 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
126204 + }
126205 + return 0;
126206 +}
126207 +
126208 +#ifdef CONFIG_HOTPLUG_CPU
126209 +static int bman_online_cpu(unsigned int cpu)
126210 +{
126211 + struct bman_portal *p;
126212 + const struct bm_portal_config *pcfg;
126213 + p = (struct bman_portal *)affine_bportals[cpu];
126214 + if (p) {
126215 + pcfg = bman_get_bm_portal_config(p);
126216 + if (pcfg)
126217 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
126218 + }
126219 + return 0;
126220 +}
126221 +static int bman_hotplug_cpu_callback(struct notifier_block *nfb,
126222 + unsigned long action, void *hcpu)
126223 +{
126224 + unsigned int cpu = (unsigned long)hcpu;
126225 +
126226 + switch (action) {
126227 + case CPU_ONLINE:
126228 + case CPU_ONLINE_FROZEN:
126229 + bman_online_cpu(cpu);
126230 + break;
126231 + case CPU_DOWN_PREPARE:
126232 + case CPU_DOWN_PREPARE_FROZEN:
126233 + bman_offline_cpu(cpu);
126234 + default:
126235 + break;
126236 + }
126237 + return NOTIFY_OK;
126238 +}
126239 +
126240 +static struct notifier_block bman_hotplug_cpu_notifier = {
126241 + .notifier_call = bman_hotplug_cpu_callback,
126242 +};
126243 +#endif /* CONFIG_HOTPLUG_CPU */
126244 +
126245 +/* Initialise the Bman driver. The meat of this function deals with portals. The
126246 + * following describes the flow of portal-handling, the code "steps" refer to
126247 + * this description;
126248 + * 1. Portal configs are parsed from the device-tree into 'unused_pcfgs', with
126249 + * ::cpu==-1. Regions and interrupts are mapped (but interrupts are not
126250 + * bound).
126251 + * 2. The "want_shared" and "want_unshared" lists (as filled by the
126252 + * "bportals=[...]" bootarg) are processed, allocating portals and assigning
126253 + * them to cpus, placing them in the relevant list and setting ::cpu as
126254 + * appropriate. If no "bportals" bootarg was present, the defaut is to try to
126255 + * assign portals to all online cpus at the time of driver initialisation.
126256 + * Any failure to allocate portals (when parsing the "want" lists or when
126257 + * using default behaviour) will be silently tolerated (the "fixup" logic in
126258 + * step 3 will determine what happens in this case).
126259 + * 3. Do fixups relative to cpu_online_mask(). If no portals are marked for
126260 + * sharing and sharing is required (because not all cpus have been assigned
126261 + * portals), then one portal will marked for sharing. Conversely if no
126262 + * sharing is required, any portals marked for sharing will not be shared. It
126263 + * may be that sharing occurs when it wasn't expected, if portal allocation
126264 + * failed to honour all the requested assignments (including the default
126265 + * assignments if no bootarg is present).
126266 + * 4. Unshared portals are initialised on their respective cpus.
126267 + * 5. Shared portals are initialised on their respective cpus.
126268 + * 6. Each remaining cpu is initialised to slave to one of the shared portals,
126269 + * which are selected in a round-robin fashion.
126270 + * Any portal configs left unused are available for USDPAA allocation.
126271 + */
126272 +__init int bman_init(void)
126273 +{
126274 + struct cpumask slave_cpus;
126275 + struct cpumask unshared_cpus = *cpu_none_mask;
126276 + struct cpumask shared_cpus = *cpu_none_mask;
126277 + LIST_HEAD(unshared_pcfgs);
126278 + LIST_HEAD(shared_pcfgs);
126279 + struct device_node *dn;
126280 + struct bm_portal_config *pcfg;
126281 + struct bman_portal *p;
126282 + int cpu, ret;
126283 + struct cpumask offline_cpus;
126284 +
126285 + /* Initialise the Bman (CCSR) device */
126286 + for_each_compatible_node(dn, NULL, "fsl,bman") {
126287 + if (!bman_init_ccsr(dn))
126288 + pr_info("Bman err interrupt handler present\n");
126289 + else
126290 + pr_err("Bman CCSR setup failed\n");
126291 + }
126292 + /* Initialise any declared buffer pools */
126293 + for_each_compatible_node(dn, NULL, "fsl,bpool") {
126294 + ret = fsl_bpool_init(dn);
126295 + if (ret)
126296 + return ret;
126297 + }
126298 + /* Step 1. See comments at the beginning of the file. */
126299 + for_each_compatible_node(dn, NULL, "fsl,bman-portal") {
126300 + if (!of_device_is_available(dn))
126301 + continue;
126302 + pcfg = parse_pcfg(dn);
126303 + if (pcfg)
126304 + list_add_tail(&pcfg->list, &unused_pcfgs);
126305 + }
126306 + /* Step 2. */
126307 + for_each_possible_cpu(cpu) {
126308 + if (cpumask_test_cpu(cpu, &want_shared)) {
126309 + pcfg = get_pcfg(&unused_pcfgs);
126310 + if (!pcfg)
126311 + break;
126312 + pcfg->public_cfg.cpu = cpu;
126313 + list_add_tail(&pcfg->list, &shared_pcfgs);
126314 + cpumask_set_cpu(cpu, &shared_cpus);
126315 + }
126316 + if (cpumask_test_cpu(cpu, &want_unshared)) {
126317 + if (cpumask_test_cpu(cpu, &shared_cpus))
126318 + continue;
126319 + pcfg = get_pcfg(&unused_pcfgs);
126320 + if (!pcfg)
126321 + break;
126322 + pcfg->public_cfg.cpu = cpu;
126323 + list_add_tail(&pcfg->list, &unshared_pcfgs);
126324 + cpumask_set_cpu(cpu, &unshared_cpus);
126325 + }
126326 + }
126327 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
126328 + /* Default, give an unshared portal to each online cpu */
126329 + for_each_online_cpu(cpu) {
126330 + pcfg = get_pcfg(&unused_pcfgs);
126331 + if (!pcfg)
126332 + break;
126333 + pcfg->public_cfg.cpu = cpu;
126334 + list_add_tail(&pcfg->list, &unshared_pcfgs);
126335 + cpumask_set_cpu(cpu, &unshared_cpus);
126336 + }
126337 + }
126338 + /* Step 3. */
126339 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
126340 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
126341 + if (cpumask_empty(&slave_cpus)) {
126342 + /* No sharing required */
126343 + if (!list_empty(&shared_pcfgs)) {
126344 + /* Migrate "shared" to "unshared" */
126345 + cpumask_or(&unshared_cpus, &unshared_cpus,
126346 + &shared_cpus);
126347 + cpumask_clear(&shared_cpus);
126348 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
126349 + INIT_LIST_HEAD(&shared_pcfgs);
126350 + }
126351 + } else {
126352 + /* Sharing required */
126353 + if (list_empty(&shared_pcfgs)) {
126354 + /* Migrate one "unshared" to "shared" */
126355 + pcfg = get_pcfg(&unshared_pcfgs);
126356 + if (!pcfg) {
126357 + pr_crit("No BMan portals available!\n");
126358 + return 0;
126359 + }
126360 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
126361 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
126362 + list_add_tail(&pcfg->list, &shared_pcfgs);
126363 + }
126364 + }
126365 + /* Step 4. */
126366 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
126367 + pcfg->public_cfg.is_shared = 0;
126368 + p = init_pcfg(pcfg);
126369 + if (!p) {
126370 + pr_crit("Unable to initialize bman portal\n");
126371 + return 0;
126372 + }
126373 + }
126374 + /* Step 5. */
126375 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
126376 + pcfg->public_cfg.is_shared = 1;
126377 + p = init_pcfg(pcfg);
126378 + if (p)
126379 + shared_portals[num_shared_portals++] = p;
126380 + }
126381 + /* Step 6. */
126382 + if (!cpumask_empty(&slave_cpus))
126383 + for_each_cpu(cpu, &slave_cpus)
126384 + init_slave(cpu);
126385 + pr_info("Bman portals initialised\n");
126386 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
126387 + for_each_cpu(cpu, &offline_cpus)
126388 + bman_offline_cpu(cpu);
126389 +#ifdef CONFIG_HOTPLUG_CPU
126390 + register_hotcpu_notifier(&bman_hotplug_cpu_notifier);
126391 +#endif
126392 + return 0;
126393 +}
126394 +
126395 +__init int bman_resource_init(void)
126396 +{
126397 + struct device_node *dn;
126398 + int ret;
126399 +
126400 + /* Initialise BPID allocation ranges */
126401 + for_each_compatible_node(dn, NULL, "fsl,bpid-range") {
126402 + ret = fsl_bpid_range_init(dn);
126403 + if (ret)
126404 + return ret;
126405 + }
126406 + return 0;
126407 +}
126408 +
126409 +#ifdef CONFIG_SUSPEND
126410 +void suspend_unused_bportal(void)
126411 +{
126412 + struct bm_portal_config *pcfg;
126413 +
126414 + if (list_empty(&unused_pcfgs))
126415 + return;
126416 +
126417 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
126418 +#ifdef CONFIG_PM_DEBUG
126419 + pr_info("Need to save bportal %d\n", pcfg->public_cfg.index);
126420 +#endif
126421 + /* save isdr, disable all via isdr, clear isr */
126422 + pcfg->saved_isdr =
126423 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
126424 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
126425 + 0xe08);
126426 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
126427 + 0xe00);
126428 + }
126429 + return;
126430 +}
126431 +
126432 +void resume_unused_bportal(void)
126433 +{
126434 + struct bm_portal_config *pcfg;
126435 +
126436 + if (list_empty(&unused_pcfgs))
126437 + return;
126438 +
126439 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
126440 +#ifdef CONFIG_PM_DEBUG
126441 + pr_info("Need to resume bportal %d\n", pcfg->public_cfg.index);
126442 +#endif
126443 + /* restore isdr */
126444 + __raw_writel(pcfg->saved_isdr,
126445 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
126446 + }
126447 + return;
126448 +}
126449 +#endif
126450 diff --git a/drivers/staging/fsl_qbman/bman_high.c b/drivers/staging/fsl_qbman/bman_high.c
126451 new file mode 100644
126452 index 00000000..c066602d
126453 --- /dev/null
126454 +++ b/drivers/staging/fsl_qbman/bman_high.c
126455 @@ -0,0 +1,1145 @@
126456 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
126457 + *
126458 + * Redistribution and use in source and binary forms, with or without
126459 + * modification, are permitted provided that the following conditions are met:
126460 + * * Redistributions of source code must retain the above copyright
126461 + * notice, this list of conditions and the following disclaimer.
126462 + * * Redistributions in binary form must reproduce the above copyright
126463 + * notice, this list of conditions and the following disclaimer in the
126464 + * documentation and/or other materials provided with the distribution.
126465 + * * Neither the name of Freescale Semiconductor nor the
126466 + * names of its contributors may be used to endorse or promote products
126467 + * derived from this software without specific prior written permission.
126468 + *
126469 + *
126470 + * ALTERNATIVELY, this software may be distributed under the terms of the
126471 + * GNU General Public License ("GPL") as published by the Free Software
126472 + * Foundation, either version 2 of that License or (at your option) any
126473 + * later version.
126474 + *
126475 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
126476 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
126477 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
126478 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
126479 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
126480 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
126481 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
126482 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
126483 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
126484 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126485 + */
126486 +
126487 +#include "bman_low.h"
126488 +
126489 +/* Compilation constants */
126490 +#define RCR_THRESH 2 /* reread h/w CI when running out of space */
126491 +#define IRQNAME "BMan portal %d"
126492 +#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */
126493 +
126494 +struct bman_portal {
126495 + struct bm_portal p;
126496 + /* 2-element array. pools[0] is mask, pools[1] is snapshot. */
126497 + struct bman_depletion *pools;
126498 + int thresh_set;
126499 + unsigned long irq_sources;
126500 + u32 slowpoll; /* only used when interrupts are off */
126501 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126502 + struct bman_pool *rcri_owned; /* only 1 release WAIT_SYNC at a time */
126503 +#endif
126504 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126505 + raw_spinlock_t sharing_lock; /* only used if is_shared */
126506 + int is_shared;
126507 + struct bman_portal *sharing_redirect;
126508 +#endif
126509 + /* When the cpu-affine portal is activated, this is non-NULL */
126510 + const struct bm_portal_config *config;
126511 + /* This is needed for power management */
126512 + struct platform_device *pdev;
126513 + /* 64-entry hash-table of pool objects that are tracking depletion
126514 + * entry/exit (ie. BMAN_POOL_FLAG_DEPLETION). This isn't fast-path, so
126515 + * we're not fussy about cache-misses and so forth - whereas the above
126516 + * members should all fit in one cacheline.
126517 + * BTW, with 64 entries in the hash table and 64 buffer pools to track,
126518 + * you'll never guess the hash-function ... */
126519 + struct bman_pool *cb[64];
126520 + char irqname[MAX_IRQNAME];
126521 + /* Track if the portal was alloced by the driver */
126522 + u8 alloced;
126523 + /* power management data */
126524 + u32 save_isdr;
126525 +};
126526 +
126527 +/* For an explanation of the locking, redirection, or affine-portal logic,
126528 + * please consult the Qman driver for details. This is the same, only simpler
126529 + * (no fiddly Qman-specific bits.) */
126530 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126531 +#define PORTAL_IRQ_LOCK(p, irqflags) \
126532 + do { \
126533 + if ((p)->is_shared) \
126534 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
126535 + else \
126536 + local_irq_save(irqflags); \
126537 + } while (0)
126538 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
126539 + do { \
126540 + if ((p)->is_shared) \
126541 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
126542 + irqflags); \
126543 + else \
126544 + local_irq_restore(irqflags); \
126545 + } while (0)
126546 +#else
126547 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
126548 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
126549 +#endif
126550 +
126551 +static cpumask_t affine_mask;
126552 +static DEFINE_SPINLOCK(affine_mask_lock);
126553 +static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal);
126554 +static inline struct bman_portal *get_raw_affine_portal(void)
126555 +{
126556 + return &get_cpu_var(bman_affine_portal);
126557 +}
126558 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126559 +static inline struct bman_portal *get_affine_portal(void)
126560 +{
126561 + struct bman_portal *p = get_raw_affine_portal();
126562 + if (p->sharing_redirect)
126563 + return p->sharing_redirect;
126564 + return p;
126565 +}
126566 +#else
126567 +#define get_affine_portal() get_raw_affine_portal()
126568 +#endif
126569 +static inline void put_affine_portal(void)
126570 +{
126571 + put_cpu_var(bman_affine_portal);
126572 +}
126573 +static inline struct bman_portal *get_poll_portal(void)
126574 +{
126575 + return &get_cpu_var(bman_affine_portal);
126576 +}
126577 +#define put_poll_portal()
126578 +
126579 +/* GOTCHA: this object type refers to a pool, it isn't *the* pool. There may be
126580 + * more than one such object per Bman buffer pool, eg. if different users of the
126581 + * pool are operating via different portals. */
126582 +struct bman_pool {
126583 + struct bman_pool_params params;
126584 + /* Used for hash-table admin when using depletion notifications. */
126585 + struct bman_portal *portal;
126586 + struct bman_pool *next;
126587 + /* stockpile state - NULL unless BMAN_POOL_FLAG_STOCKPILE is set */
126588 + struct bm_buffer *sp;
126589 + unsigned int sp_fill;
126590 +#ifdef CONFIG_FSL_DPA_CHECKING
126591 + atomic_t in_use;
126592 +#endif
126593 +};
126594 +
126595 +/* (De)Registration of depletion notification callbacks */
126596 +static void depletion_link(struct bman_portal *portal, struct bman_pool *pool)
126597 +{
126598 + __maybe_unused unsigned long irqflags;
126599 + pool->portal = portal;
126600 + PORTAL_IRQ_LOCK(portal, irqflags);
126601 + pool->next = portal->cb[pool->params.bpid];
126602 + portal->cb[pool->params.bpid] = pool;
126603 + if (!pool->next)
126604 + /* First object for that bpid on this portal, enable the BSCN
126605 + * mask bit. */
126606 + bm_isr_bscn_mask(&portal->p, pool->params.bpid, 1);
126607 + PORTAL_IRQ_UNLOCK(portal, irqflags);
126608 +}
126609 +static void depletion_unlink(struct bman_pool *pool)
126610 +{
126611 + struct bman_pool *it, *last = NULL;
126612 + struct bman_pool **base = &pool->portal->cb[pool->params.bpid];
126613 + __maybe_unused unsigned long irqflags;
126614 + PORTAL_IRQ_LOCK(pool->portal, irqflags);
126615 + it = *base; /* <-- gotcha, don't do this prior to the irq_save */
126616 + while (it != pool) {
126617 + last = it;
126618 + it = it->next;
126619 + }
126620 + if (!last)
126621 + *base = pool->next;
126622 + else
126623 + last->next = pool->next;
126624 + if (!last && !pool->next) {
126625 + /* Last object for that bpid on this portal, disable the BSCN
126626 + * mask bit. */
126627 + bm_isr_bscn_mask(&pool->portal->p, pool->params.bpid, 0);
126628 + /* And "forget" that we last saw this pool as depleted */
126629 + bman_depletion_unset(&pool->portal->pools[1],
126630 + pool->params.bpid);
126631 + }
126632 + PORTAL_IRQ_UNLOCK(pool->portal, irqflags);
126633 +}
126634 +
126635 +/* In the case that the application's core loop calls qman_poll() and
126636 + * bman_poll(), we ought to balance how often we incur the overheads of the
126637 + * slow-path poll. We'll use two decrementer sources. The idle decrementer
126638 + * constant is used when the last slow-poll detected no work to do, and the busy
126639 + * decrementer constant when the last slow-poll had work to do. */
126640 +#define SLOW_POLL_IDLE 1000
126641 +#define SLOW_POLL_BUSY 10
126642 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is);
126643 +
126644 +/* Portal interrupt handler */
126645 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
126646 +{
126647 + struct bman_portal *p = ptr;
126648 + u32 clear = p->irq_sources;
126649 + u32 is = bm_isr_status_read(&p->p) & p->irq_sources;
126650 + clear |= __poll_portal_slow(p, is);
126651 + bm_isr_status_clear(&p->p, clear);
126652 + return IRQ_HANDLED;
126653 +}
126654 +
126655 +#ifdef CONFIG_SUSPEND
126656 +static int _bman_portal_suspend_noirq(struct device *dev)
126657 +{
126658 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
126659 +#ifdef CONFIG_PM_DEBUG
126660 + struct platform_device *pdev = to_platform_device(dev);
126661 +#endif
126662 + p->save_isdr = bm_isr_disable_read(&p->p);
126663 + bm_isr_disable_write(&p->p, 0xffffffff);
126664 + bm_isr_status_clear(&p->p, 0xffffffff);
126665 +#ifdef CONFIG_PM_DEBUG
126666 + pr_info("Suspend for %s\n", pdev->name);
126667 +#endif
126668 + return 0;
126669 +}
126670 +
126671 +static int _bman_portal_resume_noirq(struct device *dev)
126672 +{
126673 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
126674 +
126675 + /* restore isdr */
126676 + bm_isr_disable_write(&p->p, p->save_isdr);
126677 + return 0;
126678 +}
126679 +#else
126680 +#define _bman_portal_suspend_noirq NULL
126681 +#define _bman_portal_resume_noirq NULL
126682 +#endif
126683 +
126684 +struct dev_pm_domain bman_portal_device_pm_domain = {
126685 + .ops = {
126686 + USE_PLATFORM_PM_SLEEP_OPS
126687 + .suspend_noirq = _bman_portal_suspend_noirq,
126688 + .resume_noirq = _bman_portal_resume_noirq,
126689 + }
126690 +};
126691 +
126692 +struct bman_portal *bman_create_portal(
126693 + struct bman_portal *portal,
126694 + const struct bm_portal_config *config)
126695 +{
126696 + struct bm_portal *__p;
126697 + const struct bman_depletion *pools = &config->public_cfg.mask;
126698 + int ret;
126699 + u8 bpid = 0;
126700 + char buf[16];
126701 +
126702 + if (!portal) {
126703 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
126704 + if (!portal)
126705 + return portal;
126706 + portal->alloced = 1;
126707 + } else
126708 + portal->alloced = 0;
126709 +
126710 + __p = &portal->p;
126711 +
126712 + /* prep the low-level portal struct with the mapped addresses from the
126713 + * config, everything that follows depends on it and "config" is more
126714 + * for (de)reference... */
126715 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
126716 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
126717 + if (bm_rcr_init(__p, bm_rcr_pvb, bm_rcr_cce)) {
126718 + pr_err("Bman RCR initialisation failed\n");
126719 + goto fail_rcr;
126720 + }
126721 + if (bm_mc_init(__p)) {
126722 + pr_err("Bman MC initialisation failed\n");
126723 + goto fail_mc;
126724 + }
126725 + if (bm_isr_init(__p)) {
126726 + pr_err("Bman ISR initialisation failed\n");
126727 + goto fail_isr;
126728 + }
126729 + portal->pools = kmalloc(2 * sizeof(*pools), GFP_KERNEL);
126730 + if (!portal->pools)
126731 + goto fail_pools;
126732 + portal->pools[0] = *pools;
126733 + bman_depletion_init(portal->pools + 1);
126734 + while (bpid < bman_pool_max) {
126735 + /* Default to all BPIDs disabled, we enable as required at
126736 + * run-time. */
126737 + bm_isr_bscn_mask(__p, bpid, 0);
126738 + bpid++;
126739 + }
126740 + portal->slowpoll = 0;
126741 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126742 + portal->rcri_owned = NULL;
126743 +#endif
126744 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126745 + raw_spin_lock_init(&portal->sharing_lock);
126746 + portal->is_shared = config->public_cfg.is_shared;
126747 + portal->sharing_redirect = NULL;
126748 +#endif
126749 + sprintf(buf, "bportal-%u", config->public_cfg.index);
126750 + portal->pdev = platform_device_alloc(buf, -1);
126751 + if (!portal->pdev)
126752 + goto fail_devalloc;
126753 + portal->pdev->dev.pm_domain = &bman_portal_device_pm_domain;
126754 + portal->pdev->dev.platform_data = portal;
126755 + ret = platform_device_add(portal->pdev);
126756 + if (ret)
126757 + goto fail_devadd;
126758 + memset(&portal->cb, 0, sizeof(portal->cb));
126759 + /* Write-to-clear any stale interrupt status bits */
126760 + bm_isr_disable_write(__p, 0xffffffff);
126761 + portal->irq_sources = 0;
126762 + bm_isr_enable_write(__p, portal->irq_sources);
126763 + bm_isr_status_clear(__p, 0xffffffff);
126764 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
126765 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
126766 + portal)) {
126767 + pr_err("request_irq() failed\n");
126768 + goto fail_irq;
126769 + }
126770 + if ((config->public_cfg.cpu != -1) &&
126771 + irq_can_set_affinity(config->public_cfg.irq) &&
126772 + irq_set_affinity(config->public_cfg.irq,
126773 + cpumask_of(config->public_cfg.cpu))) {
126774 + pr_err("irq_set_affinity() failed %s\n", portal->irqname);
126775 + goto fail_affinity;
126776 + }
126777 +
126778 + /* Need RCR to be empty before continuing */
126779 + ret = bm_rcr_get_fill(__p);
126780 + if (ret) {
126781 + pr_err("Bman RCR unclean\n");
126782 + goto fail_rcr_empty;
126783 + }
126784 + /* Success */
126785 + portal->config = config;
126786 +
126787 + bm_isr_disable_write(__p, 0);
126788 + bm_isr_uninhibit(__p);
126789 + return portal;
126790 +fail_rcr_empty:
126791 +fail_affinity:
126792 + free_irq(config->public_cfg.irq, portal);
126793 +fail_irq:
126794 + platform_device_del(portal->pdev);
126795 +fail_devadd:
126796 + platform_device_put(portal->pdev);
126797 +fail_devalloc:
126798 + kfree(portal->pools);
126799 +fail_pools:
126800 + bm_isr_finish(__p);
126801 +fail_isr:
126802 + bm_mc_finish(__p);
126803 +fail_mc:
126804 + bm_rcr_finish(__p);
126805 +fail_rcr:
126806 + if (portal->alloced)
126807 + kfree(portal);
126808 + return NULL;
126809 +}
126810 +
126811 +struct bman_portal *bman_create_affine_portal(
126812 + const struct bm_portal_config *config)
126813 +{
126814 + struct bman_portal *portal;
126815 +
126816 + portal = &per_cpu(bman_affine_portal, config->public_cfg.cpu);
126817 + portal = bman_create_portal(portal, config);
126818 + if (portal) {
126819 + spin_lock(&affine_mask_lock);
126820 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
126821 + spin_unlock(&affine_mask_lock);
126822 + }
126823 + return portal;
126824 +}
126825 +
126826 +
126827 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
126828 + int cpu)
126829 +{
126830 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126831 + struct bman_portal *p;
126832 + p = &per_cpu(bman_affine_portal, cpu);
126833 + BUG_ON(p->config);
126834 + BUG_ON(p->is_shared);
126835 + BUG_ON(!redirect->config->public_cfg.is_shared);
126836 + p->irq_sources = 0;
126837 + p->sharing_redirect = redirect;
126838 + return p;
126839 +#else
126840 + BUG();
126841 + return NULL;
126842 +#endif
126843 +}
126844 +
126845 +void bman_destroy_portal(struct bman_portal *bm)
126846 +{
126847 + const struct bm_portal_config *pcfg;
126848 + pcfg = bm->config;
126849 + bm_rcr_cce_update(&bm->p);
126850 + bm_rcr_cce_update(&bm->p);
126851 +
126852 + free_irq(pcfg->public_cfg.irq, bm);
126853 +
126854 + kfree(bm->pools);
126855 + bm_isr_finish(&bm->p);
126856 + bm_mc_finish(&bm->p);
126857 + bm_rcr_finish(&bm->p);
126858 + bm->config = NULL;
126859 + if (bm->alloced)
126860 + kfree(bm);
126861 +}
126862 +
126863 +const struct bm_portal_config *bman_destroy_affine_portal(void)
126864 +{
126865 + struct bman_portal *bm = get_raw_affine_portal();
126866 + const struct bm_portal_config *pcfg;
126867 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126868 + if (bm->sharing_redirect) {
126869 + bm->sharing_redirect = NULL;
126870 + put_affine_portal();
126871 + return NULL;
126872 + }
126873 + bm->is_shared = 0;
126874 +#endif
126875 + pcfg = bm->config;
126876 + bman_destroy_portal(bm);
126877 + spin_lock(&affine_mask_lock);
126878 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &affine_mask);
126879 + spin_unlock(&affine_mask_lock);
126880 + put_affine_portal();
126881 + return pcfg;
126882 +}
126883 +
126884 +/* When release logic waits on available RCR space, we need a global waitqueue
126885 + * in the case of "affine" use (as the waits wake on different cpus which means
126886 + * different portals - so we can't wait on any per-portal waitqueue). */
126887 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
126888 +
126889 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is)
126890 +{
126891 + struct bman_depletion tmp;
126892 + u32 ret = is;
126893 +
126894 + /* There is a gotcha to be aware of. If we do the query before clearing
126895 + * the status register, we may miss state changes that occur between the
126896 + * two. If we write to clear the status register before the query, the
126897 + * cache-enabled query command may overtake the status register write
126898 + * unless we use a heavyweight sync (which we don't want). Instead, we
126899 + * write-to-clear the status register then *read it back* before doing
126900 + * the query, hence the odd while loop with the 'is' accumulation. */
126901 + if (is & BM_PIRQ_BSCN) {
126902 + struct bm_mc_result *mcr;
126903 + __maybe_unused unsigned long irqflags;
126904 + unsigned int i, j;
126905 + u32 __is;
126906 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126907 + while ((__is = bm_isr_status_read(&p->p)) & BM_PIRQ_BSCN) {
126908 + is |= __is;
126909 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126910 + }
126911 + is &= ~BM_PIRQ_BSCN;
126912 + PORTAL_IRQ_LOCK(p, irqflags);
126913 + bm_mc_start(&p->p);
126914 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
126915 + while (!(mcr = bm_mc_result(&p->p)))
126916 + cpu_relax();
126917 + tmp = mcr->query.ds.state;
126918 + tmp.__state[0] = be32_to_cpu(tmp.__state[0]);
126919 + tmp.__state[1] = be32_to_cpu(tmp.__state[1]);
126920 + PORTAL_IRQ_UNLOCK(p, irqflags);
126921 + for (i = 0; i < 2; i++) {
126922 + int idx = i * 32;
126923 + /* tmp is a mask of currently-depleted pools.
126924 + * pools[0] is mask of those we care about.
126925 + * pools[1] is our previous view (we only want to
126926 + * be told about changes). */
126927 + tmp.__state[i] &= p->pools[0].__state[i];
126928 + if (tmp.__state[i] == p->pools[1].__state[i])
126929 + /* fast-path, nothing to see, move along */
126930 + continue;
126931 + for (j = 0; j <= 31; j++, idx++) {
126932 + struct bman_pool *pool = p->cb[idx];
126933 + int b4 = bman_depletion_get(&p->pools[1], idx);
126934 + int af = bman_depletion_get(&tmp, idx);
126935 + if (b4 == af)
126936 + continue;
126937 + while (pool) {
126938 + pool->params.cb(p, pool,
126939 + pool->params.cb_ctx, af);
126940 + pool = pool->next;
126941 + }
126942 + }
126943 + }
126944 + p->pools[1] = tmp;
126945 + }
126946 +
126947 + if (is & BM_PIRQ_RCRI) {
126948 + __maybe_unused unsigned long irqflags;
126949 + PORTAL_IRQ_LOCK(p, irqflags);
126950 + bm_rcr_cce_update(&p->p);
126951 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126952 + /* If waiting for sync, we only cancel the interrupt threshold
126953 + * when the ring utilisation hits zero. */
126954 + if (p->rcri_owned) {
126955 + if (!bm_rcr_get_fill(&p->p)) {
126956 + p->rcri_owned = NULL;
126957 + bm_rcr_set_ithresh(&p->p, 0);
126958 + }
126959 + } else
126960 +#endif
126961 + bm_rcr_set_ithresh(&p->p, 0);
126962 + PORTAL_IRQ_UNLOCK(p, irqflags);
126963 + wake_up(&affine_queue);
126964 + bm_isr_status_clear(&p->p, BM_PIRQ_RCRI);
126965 + is &= ~BM_PIRQ_RCRI;
126966 + }
126967 +
126968 + /* There should be no status register bits left undefined */
126969 + DPA_ASSERT(!is);
126970 + return ret;
126971 +}
126972 +
126973 +const struct bman_portal_config *bman_get_portal_config(void)
126974 +{
126975 + struct bman_portal *p = get_affine_portal();
126976 + const struct bman_portal_config *ret = &p->config->public_cfg;
126977 + put_affine_portal();
126978 + return ret;
126979 +}
126980 +EXPORT_SYMBOL(bman_get_portal_config);
126981 +
126982 +u32 bman_irqsource_get(void)
126983 +{
126984 + struct bman_portal *p = get_raw_affine_portal();
126985 + u32 ret = p->irq_sources & BM_PIRQ_VISIBLE;
126986 + put_affine_portal();
126987 + return ret;
126988 +}
126989 +EXPORT_SYMBOL(bman_irqsource_get);
126990 +
126991 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits)
126992 +{
126993 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126994 + if (p->sharing_redirect)
126995 + return -EINVAL;
126996 + else
126997 +#endif
126998 + {
126999 + __maybe_unused unsigned long irqflags;
127000 + PORTAL_IRQ_LOCK(p, irqflags);
127001 + set_bits(bits & BM_PIRQ_VISIBLE, &p->irq_sources);
127002 + bm_isr_enable_write(&p->p, p->irq_sources);
127003 + PORTAL_IRQ_UNLOCK(p, irqflags);
127004 + }
127005 + return 0;
127006 +}
127007 +EXPORT_SYMBOL(bman_p_irqsource_add);
127008 +
127009 +int bman_irqsource_add(__maybe_unused u32 bits)
127010 +{
127011 + struct bman_portal *p = get_raw_affine_portal();
127012 + int ret = 0;
127013 + ret = bman_p_irqsource_add(p, bits);
127014 + put_affine_portal();
127015 + return ret;
127016 +}
127017 +EXPORT_SYMBOL(bman_irqsource_add);
127018 +
127019 +int bman_irqsource_remove(u32 bits)
127020 +{
127021 + struct bman_portal *p = get_raw_affine_portal();
127022 + __maybe_unused unsigned long irqflags;
127023 + u32 ier;
127024 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127025 + if (p->sharing_redirect) {
127026 + put_affine_portal();
127027 + return -EINVAL;
127028 + }
127029 +#endif
127030 + /* Our interrupt handler only processes+clears status register bits that
127031 + * are in p->irq_sources. As we're trimming that mask, if one of them
127032 + * were to assert in the status register just before we remove it from
127033 + * the enable register, there would be an interrupt-storm when we
127034 + * release the IRQ lock. So we wait for the enable register update to
127035 + * take effect in h/w (by reading it back) and then clear all other bits
127036 + * in the status register. Ie. we clear them from ISR once it's certain
127037 + * IER won't allow them to reassert. */
127038 + PORTAL_IRQ_LOCK(p, irqflags);
127039 + bits &= BM_PIRQ_VISIBLE;
127040 + clear_bits(bits, &p->irq_sources);
127041 + bm_isr_enable_write(&p->p, p->irq_sources);
127042 + ier = bm_isr_enable_read(&p->p);
127043 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
127044 + * data-dependency, ie. to protect against re-ordering. */
127045 + bm_isr_status_clear(&p->p, ~ier);
127046 + PORTAL_IRQ_UNLOCK(p, irqflags);
127047 + put_affine_portal();
127048 + return 0;
127049 +}
127050 +EXPORT_SYMBOL(bman_irqsource_remove);
127051 +
127052 +const cpumask_t *bman_affine_cpus(void)
127053 +{
127054 + return &affine_mask;
127055 +}
127056 +EXPORT_SYMBOL(bman_affine_cpus);
127057 +
127058 +u32 bman_poll_slow(void)
127059 +{
127060 + struct bman_portal *p = get_poll_portal();
127061 + u32 ret;
127062 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127063 + if (unlikely(p->sharing_redirect))
127064 + ret = (u32)-1;
127065 + else
127066 +#endif
127067 + {
127068 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
127069 + ret = __poll_portal_slow(p, is);
127070 + bm_isr_status_clear(&p->p, ret);
127071 + }
127072 + put_poll_portal();
127073 + return ret;
127074 +}
127075 +EXPORT_SYMBOL(bman_poll_slow);
127076 +
127077 +/* Legacy wrapper */
127078 +void bman_poll(void)
127079 +{
127080 + struct bman_portal *p = get_poll_portal();
127081 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127082 + if (unlikely(p->sharing_redirect))
127083 + goto done;
127084 +#endif
127085 + if (!(p->slowpoll--)) {
127086 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
127087 + u32 active = __poll_portal_slow(p, is);
127088 + if (active)
127089 + p->slowpoll = SLOW_POLL_BUSY;
127090 + else
127091 + p->slowpoll = SLOW_POLL_IDLE;
127092 + }
127093 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127094 +done:
127095 +#endif
127096 + put_poll_portal();
127097 +}
127098 +EXPORT_SYMBOL(bman_poll);
127099 +
127100 +static const u32 zero_thresholds[4] = {0, 0, 0, 0};
127101 +
127102 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params)
127103 +{
127104 + struct bman_pool *pool = NULL;
127105 + u32 bpid;
127106 +
127107 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) {
127108 + int ret = bman_alloc_bpid(&bpid);
127109 + if (ret)
127110 + return NULL;
127111 + } else {
127112 + if (params->bpid >= bman_pool_max)
127113 + return NULL;
127114 + bpid = params->bpid;
127115 + }
127116 +#ifdef CONFIG_FSL_BMAN_CONFIG
127117 + if (params->flags & BMAN_POOL_FLAG_THRESH) {
127118 + int ret = bm_pool_set(bpid, params->thresholds);
127119 + if (ret)
127120 + goto err;
127121 + }
127122 +#else
127123 + if (params->flags & BMAN_POOL_FLAG_THRESH)
127124 + goto err;
127125 +#endif
127126 + pool = kmalloc(sizeof(*pool), GFP_KERNEL);
127127 + if (!pool)
127128 + goto err;
127129 + pool->sp = NULL;
127130 + pool->sp_fill = 0;
127131 + pool->params = *params;
127132 +#ifdef CONFIG_FSL_DPA_CHECKING
127133 + atomic_set(&pool->in_use, 1);
127134 +#endif
127135 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
127136 + pool->params.bpid = bpid;
127137 + if (params->flags & BMAN_POOL_FLAG_STOCKPILE) {
127138 + pool->sp = kmalloc(sizeof(struct bm_buffer) * BMAN_STOCKPILE_SZ,
127139 + GFP_KERNEL);
127140 + if (!pool->sp)
127141 + goto err;
127142 + }
127143 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION) {
127144 + struct bman_portal *p = get_affine_portal();
127145 + if (!p->pools || !bman_depletion_get(&p->pools[0], bpid)) {
127146 + pr_err("Depletion events disabled for bpid %d\n", bpid);
127147 + goto err;
127148 + }
127149 + depletion_link(p, pool);
127150 + put_affine_portal();
127151 + }
127152 + return pool;
127153 +err:
127154 +#ifdef CONFIG_FSL_BMAN_CONFIG
127155 + if (params->flags & BMAN_POOL_FLAG_THRESH)
127156 + bm_pool_set(bpid, zero_thresholds);
127157 +#endif
127158 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
127159 + bman_release_bpid(bpid);
127160 + if (pool) {
127161 + kfree(pool->sp);
127162 + kfree(pool);
127163 + }
127164 + return NULL;
127165 +}
127166 +EXPORT_SYMBOL(bman_new_pool);
127167 +
127168 +void bman_free_pool(struct bman_pool *pool)
127169 +{
127170 +#ifdef CONFIG_FSL_BMAN_CONFIG
127171 + if (pool->params.flags & BMAN_POOL_FLAG_THRESH)
127172 + bm_pool_set(pool->params.bpid, zero_thresholds);
127173 +#endif
127174 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION)
127175 + depletion_unlink(pool);
127176 + if (pool->params.flags & BMAN_POOL_FLAG_STOCKPILE) {
127177 + if (pool->sp_fill)
127178 + pr_err("Stockpile not flushed, has %u in bpid %u.\n",
127179 + pool->sp_fill, pool->params.bpid);
127180 + kfree(pool->sp);
127181 + pool->sp = NULL;
127182 + pool->params.flags ^= BMAN_POOL_FLAG_STOCKPILE;
127183 + }
127184 + if (pool->params.flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
127185 + bman_release_bpid(pool->params.bpid);
127186 + kfree(pool);
127187 +}
127188 +EXPORT_SYMBOL(bman_free_pool);
127189 +
127190 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
127191 +{
127192 + return &pool->params;
127193 +}
127194 +EXPORT_SYMBOL(bman_get_params);
127195 +
127196 +static noinline void update_rcr_ci(struct bman_portal *p, u8 avail)
127197 +{
127198 + if (avail)
127199 + bm_rcr_cce_prefetch(&p->p);
127200 + else
127201 + bm_rcr_cce_update(&p->p);
127202 +}
127203 +
127204 +int bman_rcr_is_empty(void)
127205 +{
127206 + __maybe_unused unsigned long irqflags;
127207 + struct bman_portal *p = get_affine_portal();
127208 + u8 avail;
127209 +
127210 + PORTAL_IRQ_LOCK(p, irqflags);
127211 + update_rcr_ci(p, 0);
127212 + avail = bm_rcr_get_fill(&p->p);
127213 + PORTAL_IRQ_UNLOCK(p, irqflags);
127214 + put_affine_portal();
127215 + return avail == 0;
127216 +}
127217 +EXPORT_SYMBOL(bman_rcr_is_empty);
127218 +
127219 +static inline struct bm_rcr_entry *try_rel_start(struct bman_portal **p,
127220 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
127221 + __maybe_unused struct bman_pool *pool,
127222 +#endif
127223 + __maybe_unused unsigned long *irqflags,
127224 + __maybe_unused u32 flags)
127225 +{
127226 + struct bm_rcr_entry *r;
127227 + u8 avail;
127228 +
127229 + *p = get_affine_portal();
127230 + PORTAL_IRQ_LOCK(*p, (*irqflags));
127231 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127232 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
127233 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
127234 + if ((*p)->rcri_owned) {
127235 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
127236 + put_affine_portal();
127237 + return NULL;
127238 + }
127239 + (*p)->rcri_owned = pool;
127240 + }
127241 +#endif
127242 + avail = bm_rcr_get_avail(&(*p)->p);
127243 + if (avail < 2)
127244 + update_rcr_ci(*p, avail);
127245 + r = bm_rcr_start(&(*p)->p);
127246 + if (unlikely(!r)) {
127247 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127248 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
127249 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC)))
127250 + (*p)->rcri_owned = NULL;
127251 +#endif
127252 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
127253 + put_affine_portal();
127254 + }
127255 + return r;
127256 +}
127257 +
127258 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
127259 +static noinline struct bm_rcr_entry *__wait_rel_start(struct bman_portal **p,
127260 + struct bman_pool *pool,
127261 + __maybe_unused unsigned long *irqflags,
127262 + u32 flags)
127263 +{
127264 + struct bm_rcr_entry *rcr = try_rel_start(p, pool, irqflags, flags);
127265 + if (!rcr)
127266 + bm_rcr_set_ithresh(&(*p)->p, 1);
127267 + return rcr;
127268 +}
127269 +
127270 +static noinline struct bm_rcr_entry *wait_rel_start(struct bman_portal **p,
127271 + struct bman_pool *pool,
127272 + __maybe_unused unsigned long *irqflags,
127273 + u32 flags)
127274 +{
127275 + struct bm_rcr_entry *rcr;
127276 +#ifndef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127277 + pool = NULL;
127278 +#endif
127279 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
127280 + /* NB: return NULL if signal occurs before completion. Signal
127281 + * can occur during return. Caller must check for signal */
127282 + wait_event_interruptible(affine_queue,
127283 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
127284 + else
127285 + wait_event(affine_queue,
127286 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
127287 + return rcr;
127288 +}
127289 +#endif
127290 +
127291 +static inline int __bman_release(struct bman_pool *pool,
127292 + const struct bm_buffer *bufs, u8 num, u32 flags)
127293 +{
127294 + struct bman_portal *p;
127295 + struct bm_rcr_entry *r;
127296 + __maybe_unused unsigned long irqflags;
127297 + u32 i = num - 1;
127298 +
127299 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
127300 + if (flags & BMAN_RELEASE_FLAG_WAIT)
127301 + r = wait_rel_start(&p, pool, &irqflags, flags);
127302 + else
127303 + r = try_rel_start(&p, pool, &irqflags, flags);
127304 +#else
127305 + r = try_rel_start(&p, &irqflags, flags);
127306 +#endif
127307 + if (!r)
127308 + return -EBUSY;
127309 + /* We can copy all but the first entry, as this can trigger badness
127310 + * with the valid-bit. Use the overlay to mask the verb byte. */
127311 + r->bufs[0].opaque =
127312 + ((cpu_to_be64((bufs[0].opaque |
127313 + ((u64)pool->params.bpid<<48))
127314 + & 0x00ffffffffffffff)));
127315 + if (i) {
127316 + for (i = 1; i < num; i++)
127317 + r->bufs[i].opaque =
127318 + cpu_to_be64(bufs[i].opaque);
127319 + }
127320 +
127321 + bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
127322 + (num & BM_RCR_VERB_BUFCOUNT_MASK));
127323 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127324 + /* if we wish to sync we need to set the threshold after h/w sees the
127325 + * new ring entry. As we're mixing cache-enabled and cache-inhibited
127326 + * accesses, this requires a heavy-weight sync. */
127327 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
127328 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
127329 + hwsync();
127330 + bm_rcr_set_ithresh(&p->p, 1);
127331 + }
127332 +#endif
127333 + PORTAL_IRQ_UNLOCK(p, irqflags);
127334 + put_affine_portal();
127335 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127336 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
127337 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
127338 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
127339 + /* NB: return success even if signal occurs before
127340 + * condition is true. pvb_commit guarantees success */
127341 + wait_event_interruptible(affine_queue,
127342 + (p->rcri_owned != pool));
127343 + else
127344 + wait_event(affine_queue, (p->rcri_owned != pool));
127345 + }
127346 +#endif
127347 + return 0;
127348 +}
127349 +
127350 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
127351 + u32 flags)
127352 +{
127353 + int ret;
127354 +#ifdef CONFIG_FSL_DPA_CHECKING
127355 + if (!num || (num > 8))
127356 + return -EINVAL;
127357 + if (pool->params.flags & BMAN_POOL_FLAG_NO_RELEASE)
127358 + return -EINVAL;
127359 +#endif
127360 + /* Without stockpile, this API is a pass-through to the h/w operation */
127361 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
127362 + return __bman_release(pool, bufs, num, flags);
127363 +#ifdef CONFIG_FSL_DPA_CHECKING
127364 + if (!atomic_dec_and_test(&pool->in_use)) {
127365 + pr_crit("Parallel attempts to enter bman_released() detected.");
127366 + panic("only one instance of bman_released/acquired allowed");
127367 + }
127368 +#endif
127369 + /* Two movements of buffers are possible, and can occur in either order.
127370 + * A: moving buffers from the caller to the stockpile.
127371 + * B: moving buffers from the stockpile to hardware.
127372 + * Order 1: if there is already enough space in the stockpile for A
127373 + * then we want to do A first, and only do B if we trigger the
127374 + * stockpile-high threshold.
127375 + * Order 2: if there is not enough space in the stockpile for A, then
127376 + * we want to do B first, then do A if B had succeeded. However in this
127377 + * case B is dependent on how many buffers the user needs to release,
127378 + * not the stockpile-high threshold.
127379 + * Due to the different handling of B between the two cases, putting A
127380 + * and B in a while() loop would require quite obscure logic, so handle
127381 + * the different sequences explicitly. */
127382 + if ((pool->sp_fill + num) <= BMAN_STOCKPILE_SZ) {
127383 + /* Order 1: do A */
127384 + copy_words(pool->sp + pool->sp_fill, bufs,
127385 + sizeof(struct bm_buffer) * num);
127386 + pool->sp_fill += num;
127387 + /* do B relative to STOCKPILE_HIGH */
127388 + while (pool->sp_fill >= BMAN_STOCKPILE_HIGH) {
127389 + ret = __bman_release(pool,
127390 + pool->sp + (pool->sp_fill - 8), 8,
127391 + flags);
127392 + if (ret >= 0)
127393 + pool->sp_fill -= 8;
127394 + }
127395 + } else {
127396 + /* Order 2: do B relative to 'num' */
127397 + do {
127398 + ret = __bman_release(pool,
127399 + pool->sp + (pool->sp_fill - 8), 8,
127400 + flags);
127401 + if (ret < 0)
127402 + /* failure */
127403 + goto release_done;
127404 + pool->sp_fill -= 8;
127405 + } while ((pool->sp_fill + num) > BMAN_STOCKPILE_SZ);
127406 + /* do A */
127407 + copy_words(pool->sp + pool->sp_fill, bufs,
127408 + sizeof(struct bm_buffer) * num);
127409 + pool->sp_fill += num;
127410 + }
127411 + /* success */
127412 + ret = 0;
127413 +release_done:
127414 +#ifdef CONFIG_FSL_DPA_CHECKING
127415 + atomic_inc(&pool->in_use);
127416 +#endif
127417 + return ret;
127418 +}
127419 +EXPORT_SYMBOL(bman_release);
127420 +
127421 +static inline int __bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs,
127422 + u8 num)
127423 +{
127424 + struct bman_portal *p = get_affine_portal();
127425 + struct bm_mc_command *mcc;
127426 + struct bm_mc_result *mcr;
127427 + __maybe_unused unsigned long irqflags;
127428 + int ret, i;
127429 +
127430 + PORTAL_IRQ_LOCK(p, irqflags);
127431 + mcc = bm_mc_start(&p->p);
127432 + mcc->acquire.bpid = pool->params.bpid;
127433 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
127434 + (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
127435 + while (!(mcr = bm_mc_result(&p->p)))
127436 + cpu_relax();
127437 + ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
127438 + if (bufs) {
127439 + for (i = 0; i < num; i++)
127440 + bufs[i].opaque =
127441 + be64_to_cpu(mcr->acquire.bufs[i].opaque);
127442 + }
127443 + PORTAL_IRQ_UNLOCK(p, irqflags);
127444 + put_affine_portal();
127445 + if (ret != num)
127446 + ret = -ENOMEM;
127447 + return ret;
127448 +}
127449 +
127450 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
127451 + u32 flags)
127452 +{
127453 + int ret;
127454 +#ifdef CONFIG_FSL_DPA_CHECKING
127455 + if (!num || (num > 8))
127456 + return -EINVAL;
127457 + if (pool->params.flags & BMAN_POOL_FLAG_ONLY_RELEASE)
127458 + return -EINVAL;
127459 +#endif
127460 + /* Without stockpile, this API is a pass-through to the h/w operation */
127461 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
127462 + return __bman_acquire(pool, bufs, num);
127463 +#ifdef CONFIG_FSL_DPA_CHECKING
127464 + if (!atomic_dec_and_test(&pool->in_use)) {
127465 + pr_crit("Parallel attempts to enter bman_acquire() detected.");
127466 + panic("only one instance of bman_released/acquired allowed");
127467 + }
127468 +#endif
127469 + /* Two movements of buffers are possible, and can occur in either order.
127470 + * A: moving buffers from stockpile to the caller.
127471 + * B: moving buffers from hardware to the stockpile.
127472 + * Order 1: if there are already enough buffers in the stockpile for A
127473 + * then we want to do A first, and only do B if we trigger the
127474 + * stockpile-low threshold.
127475 + * Order 2: if there are not enough buffers in the stockpile for A,
127476 + * then we want to do B first, then do A if B had succeeded. However in
127477 + * this case B is dependent on how many buffers the user needs, not the
127478 + * stockpile-low threshold.
127479 + * Due to the different handling of B between the two cases, putting A
127480 + * and B in a while() loop would require quite obscure logic, so handle
127481 + * the different sequences explicitly. */
127482 + if (num <= pool->sp_fill) {
127483 + /* Order 1: do A */
127484 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
127485 + sizeof(struct bm_buffer) * num);
127486 + pool->sp_fill -= num;
127487 + /* do B relative to STOCKPILE_LOW */
127488 + while (pool->sp_fill <= BMAN_STOCKPILE_LOW) {
127489 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
127490 + if (ret < 0)
127491 + ret = __bman_acquire(pool,
127492 + pool->sp + pool->sp_fill, 1);
127493 + if (ret < 0)
127494 + break;
127495 + pool->sp_fill += ret;
127496 + }
127497 + } else {
127498 + /* Order 2: do B relative to 'num' */
127499 + do {
127500 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
127501 + if (ret < 0)
127502 + ret = __bman_acquire(pool,
127503 + pool->sp + pool->sp_fill, 1);
127504 + if (ret < 0)
127505 + /* failure */
127506 + goto acquire_done;
127507 + pool->sp_fill += ret;
127508 + } while (pool->sp_fill < num);
127509 + /* do A */
127510 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
127511 + sizeof(struct bm_buffer) * num);
127512 + pool->sp_fill -= num;
127513 + }
127514 + /* success */
127515 + ret = num;
127516 +acquire_done:
127517 +#ifdef CONFIG_FSL_DPA_CHECKING
127518 + atomic_inc(&pool->in_use);
127519 +#endif
127520 + return ret;
127521 +}
127522 +EXPORT_SYMBOL(bman_acquire);
127523 +
127524 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags)
127525 +{
127526 + u8 num;
127527 + int ret;
127528 +
127529 + while (pool->sp_fill) {
127530 + num = ((pool->sp_fill > 8) ? 8 : pool->sp_fill);
127531 + ret = __bman_release(pool, pool->sp + (pool->sp_fill - num),
127532 + num, flags);
127533 + if (ret)
127534 + return ret;
127535 + pool->sp_fill -= num;
127536 + }
127537 + return 0;
127538 +}
127539 +EXPORT_SYMBOL(bman_flush_stockpile);
127540 +
127541 +int bman_query_pools(struct bm_pool_state *state)
127542 +{
127543 + struct bman_portal *p = get_affine_portal();
127544 + struct bm_mc_result *mcr;
127545 + __maybe_unused unsigned long irqflags;
127546 +
127547 + PORTAL_IRQ_LOCK(p, irqflags);
127548 + bm_mc_start(&p->p);
127549 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
127550 + while (!(mcr = bm_mc_result(&p->p)))
127551 + cpu_relax();
127552 + DPA_ASSERT((mcr->verb & BM_MCR_VERB_CMD_MASK) == BM_MCR_VERB_CMD_QUERY);
127553 + *state = mcr->query;
127554 + state->as.state.__state[0] = be32_to_cpu(state->as.state.__state[0]);
127555 + state->as.state.__state[1] = be32_to_cpu(state->as.state.__state[1]);
127556 + state->ds.state.__state[0] = be32_to_cpu(state->ds.state.__state[0]);
127557 + state->ds.state.__state[1] = be32_to_cpu(state->ds.state.__state[1]);
127558 + PORTAL_IRQ_UNLOCK(p, irqflags);
127559 + put_affine_portal();
127560 + return 0;
127561 +}
127562 +EXPORT_SYMBOL(bman_query_pools);
127563 +
127564 +#ifdef CONFIG_FSL_BMAN_CONFIG
127565 +u32 bman_query_free_buffers(struct bman_pool *pool)
127566 +{
127567 + return bm_pool_free_buffers(pool->params.bpid);
127568 +}
127569 +EXPORT_SYMBOL(bman_query_free_buffers);
127570 +
127571 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds)
127572 +{
127573 + u32 bpid;
127574 +
127575 + bpid = bman_get_params(pool)->bpid;
127576 +
127577 + return bm_pool_set(bpid, thresholds);
127578 +}
127579 +EXPORT_SYMBOL(bman_update_pool_thresholds);
127580 +#endif
127581 +
127582 +int bman_shutdown_pool(u32 bpid)
127583 +{
127584 + struct bman_portal *p = get_affine_portal();
127585 + __maybe_unused unsigned long irqflags;
127586 + int ret;
127587 +
127588 + PORTAL_IRQ_LOCK(p, irqflags);
127589 + ret = bm_shutdown_pool(&p->p, bpid);
127590 + PORTAL_IRQ_UNLOCK(p, irqflags);
127591 + put_affine_portal();
127592 + return ret;
127593 +}
127594 +EXPORT_SYMBOL(bman_shutdown_pool);
127595 +
127596 +const struct bm_portal_config *bman_get_bm_portal_config(
127597 + struct bman_portal *portal)
127598 +{
127599 + return portal->sharing_redirect ? NULL : portal->config;
127600 +}
127601 diff --git a/drivers/staging/fsl_qbman/bman_low.h b/drivers/staging/fsl_qbman/bman_low.h
127602 new file mode 100644
127603 index 00000000..3da70571
127604 --- /dev/null
127605 +++ b/drivers/staging/fsl_qbman/bman_low.h
127606 @@ -0,0 +1,565 @@
127607 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127608 + *
127609 + * Redistribution and use in source and binary forms, with or without
127610 + * modification, are permitted provided that the following conditions are met:
127611 + * * Redistributions of source code must retain the above copyright
127612 + * notice, this list of conditions and the following disclaimer.
127613 + * * Redistributions in binary form must reproduce the above copyright
127614 + * notice, this list of conditions and the following disclaimer in the
127615 + * documentation and/or other materials provided with the distribution.
127616 + * * Neither the name of Freescale Semiconductor nor the
127617 + * names of its contributors may be used to endorse or promote products
127618 + * derived from this software without specific prior written permission.
127619 + *
127620 + *
127621 + * ALTERNATIVELY, this software may be distributed under the terms of the
127622 + * GNU General Public License ("GPL") as published by the Free Software
127623 + * Foundation, either version 2 of that License or (at your option) any
127624 + * later version.
127625 + *
127626 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127627 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127628 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127629 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127630 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127631 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127632 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127633 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127634 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127635 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127636 + */
127637 +
127638 +#include "bman_private.h"
127639 +
127640 +/***************************/
127641 +/* Portal register assists */
127642 +/***************************/
127643 +
127644 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127645 +
127646 +/* Cache-inhibited register offsets */
127647 +#define BM_REG_RCR_PI_CINH 0x0000
127648 +#define BM_REG_RCR_CI_CINH 0x0004
127649 +#define BM_REG_RCR_ITR 0x0008
127650 +#define BM_REG_CFG 0x0100
127651 +#define BM_REG_SCN(n) (0x0200 + ((n) << 2))
127652 +#define BM_REG_ISR 0x0e00
127653 +#define BM_REG_IIR 0x0e0c
127654 +
127655 +/* Cache-enabled register offsets */
127656 +#define BM_CL_CR 0x0000
127657 +#define BM_CL_RR0 0x0100
127658 +#define BM_CL_RR1 0x0140
127659 +#define BM_CL_RCR 0x1000
127660 +#define BM_CL_RCR_PI_CENA 0x3000
127661 +#define BM_CL_RCR_CI_CENA 0x3100
127662 +
127663 +#endif
127664 +
127665 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127666 +
127667 +/* Cache-inhibited register offsets */
127668 +#define BM_REG_RCR_PI_CINH 0x3000
127669 +#define BM_REG_RCR_CI_CINH 0x3100
127670 +#define BM_REG_RCR_ITR 0x3200
127671 +#define BM_REG_CFG 0x3300
127672 +#define BM_REG_SCN(n) (0x3400 + ((n) << 6))
127673 +#define BM_REG_ISR 0x3e00
127674 +#define BM_REG_IIR 0x3ec0
127675 +
127676 +/* Cache-enabled register offsets */
127677 +#define BM_CL_CR 0x0000
127678 +#define BM_CL_RR0 0x0100
127679 +#define BM_CL_RR1 0x0140
127680 +#define BM_CL_RCR 0x1000
127681 +#define BM_CL_RCR_PI_CENA 0x3000
127682 +#define BM_CL_RCR_CI_CENA 0x3100
127683 +
127684 +#endif
127685 +
127686 +/* BTW, the drivers (and h/w programming model) already obtain the required
127687 + * synchronisation for portal accesses via lwsync(), hwsync(), and
127688 + * data-dependencies. Use of barrier()s or other order-preserving primitives
127689 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
127690 + * simply ensure that the compiler treats the portal registers as volatile (ie.
127691 + * non-coherent). */
127692 +
127693 +/* Cache-inhibited register access. */
127694 +#define __bm_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ci + (o)))
127695 +#define __bm_out(bm, o, val) __raw_writel(cpu_to_be32(val), \
127696 + (bm)->addr_ci + (o));
127697 +#define bm_in(reg) __bm_in(&portal->addr, BM_REG_##reg)
127698 +#define bm_out(reg, val) __bm_out(&portal->addr, BM_REG_##reg, val)
127699 +
127700 +/* Cache-enabled (index) register access */
127701 +#define __bm_cl_touch_ro(bm, o) dcbt_ro((bm)->addr_ce + (o))
127702 +#define __bm_cl_touch_rw(bm, o) dcbt_rw((bm)->addr_ce + (o))
127703 +#define __bm_cl_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ce + (o)))
127704 +#define __bm_cl_out(bm, o, val) \
127705 + do { \
127706 + u32 *__tmpclout = (bm)->addr_ce + (o); \
127707 + __raw_writel(cpu_to_be32(val), __tmpclout); \
127708 + dcbf(__tmpclout); \
127709 + } while (0)
127710 +#define __bm_cl_invalidate(bm, o) dcbi((bm)->addr_ce + (o))
127711 +#define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, BM_CL_##reg##_CENA)
127712 +#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, BM_CL_##reg##_CENA)
127713 +#define bm_cl_in(reg) __bm_cl_in(&portal->addr, BM_CL_##reg##_CENA)
127714 +#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, BM_CL_##reg##_CENA, val)
127715 +#define bm_cl_invalidate(reg)\
127716 + __bm_cl_invalidate(&portal->addr, BM_CL_##reg##_CENA)
127717 +
127718 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
127719 + * analysis, look at using the "extra" bit in the ring index registers to avoid
127720 + * cyclic issues. */
127721 +static inline u8 bm_cyc_diff(u8 ringsize, u8 first, u8 last)
127722 +{
127723 + /* 'first' is included, 'last' is excluded */
127724 + if (first <= last)
127725 + return last - first;
127726 + return ringsize + last - first;
127727 +}
127728 +
127729 +/* Portal modes.
127730 + * Enum types;
127731 + * pmode == production mode
127732 + * cmode == consumption mode,
127733 + * Enum values use 3 letter codes. First letter matches the portal mode,
127734 + * remaining two letters indicate;
127735 + * ci == cache-inhibited portal register
127736 + * ce == cache-enabled portal register
127737 + * vb == in-band valid-bit (cache-enabled)
127738 + */
127739 +enum bm_rcr_pmode { /* matches BCSP_CFG::RPM */
127740 + bm_rcr_pci = 0, /* PI index, cache-inhibited */
127741 + bm_rcr_pce = 1, /* PI index, cache-enabled */
127742 + bm_rcr_pvb = 2 /* valid-bit */
127743 +};
127744 +enum bm_rcr_cmode { /* s/w-only */
127745 + bm_rcr_cci, /* CI index, cache-inhibited */
127746 + bm_rcr_cce /* CI index, cache-enabled */
127747 +};
127748 +
127749 +
127750 +/* ------------------------- */
127751 +/* --- Portal structures --- */
127752 +
127753 +#define BM_RCR_SIZE 8
127754 +
127755 +struct bm_rcr {
127756 + struct bm_rcr_entry *ring, *cursor;
127757 + u8 ci, available, ithresh, vbit;
127758 +#ifdef CONFIG_FSL_DPA_CHECKING
127759 + u32 busy;
127760 + enum bm_rcr_pmode pmode;
127761 + enum bm_rcr_cmode cmode;
127762 +#endif
127763 +};
127764 +
127765 +struct bm_mc {
127766 + struct bm_mc_command *cr;
127767 + struct bm_mc_result *rr;
127768 + u8 rridx, vbit;
127769 +#ifdef CONFIG_FSL_DPA_CHECKING
127770 + enum {
127771 + /* Can only be _mc_start()ed */
127772 + mc_idle,
127773 + /* Can only be _mc_commit()ed or _mc_abort()ed */
127774 + mc_user,
127775 + /* Can only be _mc_retry()ed */
127776 + mc_hw
127777 + } state;
127778 +#endif
127779 +};
127780 +
127781 +struct bm_addr {
127782 + void __iomem *addr_ce; /* cache-enabled */
127783 + void __iomem *addr_ci; /* cache-inhibited */
127784 +};
127785 +
127786 +struct bm_portal {
127787 + struct bm_addr addr;
127788 + struct bm_rcr rcr;
127789 + struct bm_mc mc;
127790 + struct bm_portal_config config;
127791 +} ____cacheline_aligned;
127792 +
127793 +
127794 +/* --------------- */
127795 +/* --- RCR API --- */
127796 +
127797 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
127798 +#define RCR_CARRYCLEAR(p) \
127799 + (void *)((unsigned long)(p) & (~(unsigned long)(BM_RCR_SIZE << 6)))
127800 +
127801 +/* Bit-wise logic to convert a ring pointer to a ring index */
127802 +static inline u8 RCR_PTR2IDX(struct bm_rcr_entry *e)
127803 +{
127804 + return ((uintptr_t)e >> 6) & (BM_RCR_SIZE - 1);
127805 +}
127806 +
127807 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
127808 +static inline void RCR_INC(struct bm_rcr *rcr)
127809 +{
127810 + /* NB: this is odd-looking, but experiments show that it generates
127811 + * fast code with essentially no branching overheads. We increment to
127812 + * the next RCR pointer and handle overflow and 'vbit'. */
127813 + struct bm_rcr_entry *partial = rcr->cursor + 1;
127814 + rcr->cursor = RCR_CARRYCLEAR(partial);
127815 + if (partial != rcr->cursor)
127816 + rcr->vbit ^= BM_RCR_VERB_VBIT;
127817 +}
127818 +
127819 +static inline int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
127820 + __maybe_unused enum bm_rcr_cmode cmode)
127821 +{
127822 + /* This use of 'register', as well as all other occurrences, is because
127823 + * it has been observed to generate much faster code with gcc than is
127824 + * otherwise the case. */
127825 + register struct bm_rcr *rcr = &portal->rcr;
127826 + u32 cfg;
127827 + u8 pi;
127828 +
127829 + rcr->ring = portal->addr.addr_ce + BM_CL_RCR;
127830 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127831 +
127832 + pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
127833 + rcr->cursor = rcr->ring + pi;
127834 + rcr->vbit = (bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0;
127835 + rcr->available = BM_RCR_SIZE - 1
127836 + - bm_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
127837 + rcr->ithresh = bm_in(RCR_ITR);
127838 +#ifdef CONFIG_FSL_DPA_CHECKING
127839 + rcr->busy = 0;
127840 + rcr->pmode = pmode;
127841 + rcr->cmode = cmode;
127842 +#endif
127843 + cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */
127844 + bm_out(CFG, cfg);
127845 + return 0;
127846 +}
127847 +
127848 +static inline void bm_rcr_finish(struct bm_portal *portal)
127849 +{
127850 + register struct bm_rcr *rcr = &portal->rcr;
127851 + u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
127852 + u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127853 + DPA_ASSERT(!rcr->busy);
127854 + if (pi != RCR_PTR2IDX(rcr->cursor))
127855 + pr_crit("losing uncommited RCR entries\n");
127856 + if (ci != rcr->ci)
127857 + pr_crit("missing existing RCR completions\n");
127858 + if (rcr->ci != RCR_PTR2IDX(rcr->cursor))
127859 + pr_crit("RCR destroyed unquiesced\n");
127860 +}
127861 +
127862 +static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
127863 +{
127864 + register struct bm_rcr *rcr = &portal->rcr;
127865 + DPA_ASSERT(!rcr->busy);
127866 + if (!rcr->available)
127867 + return NULL;
127868 +#ifdef CONFIG_FSL_DPA_CHECKING
127869 + rcr->busy = 1;
127870 +#endif
127871 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127872 + dcbz_64(rcr->cursor);
127873 +#endif
127874 + return rcr->cursor;
127875 +}
127876 +
127877 +static inline void bm_rcr_abort(struct bm_portal *portal)
127878 +{
127879 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127880 + DPA_ASSERT(rcr->busy);
127881 +#ifdef CONFIG_FSL_DPA_CHECKING
127882 + rcr->busy = 0;
127883 +#endif
127884 +}
127885 +
127886 +static inline struct bm_rcr_entry *bm_rcr_pend_and_next(
127887 + struct bm_portal *portal, u8 myverb)
127888 +{
127889 + register struct bm_rcr *rcr = &portal->rcr;
127890 + DPA_ASSERT(rcr->busy);
127891 + DPA_ASSERT(rcr->pmode != bm_rcr_pvb);
127892 + if (rcr->available == 1)
127893 + return NULL;
127894 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127895 + dcbf_64(rcr->cursor);
127896 + RCR_INC(rcr);
127897 + rcr->available--;
127898 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127899 + dcbz_64(rcr->cursor);
127900 +#endif
127901 + return rcr->cursor;
127902 +}
127903 +
127904 +static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb)
127905 +{
127906 + register struct bm_rcr *rcr = &portal->rcr;
127907 + DPA_ASSERT(rcr->busy);
127908 + DPA_ASSERT(rcr->pmode == bm_rcr_pci);
127909 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127910 + RCR_INC(rcr);
127911 + rcr->available--;
127912 + hwsync();
127913 + bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor));
127914 +#ifdef CONFIG_FSL_DPA_CHECKING
127915 + rcr->busy = 0;
127916 +#endif
127917 +}
127918 +
127919 +static inline void bm_rcr_pce_prefetch(struct bm_portal *portal)
127920 +{
127921 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127922 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127923 + bm_cl_invalidate(RCR_PI);
127924 + bm_cl_touch_rw(RCR_PI);
127925 +}
127926 +
127927 +static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb)
127928 +{
127929 + register struct bm_rcr *rcr = &portal->rcr;
127930 + DPA_ASSERT(rcr->busy);
127931 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127932 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127933 + RCR_INC(rcr);
127934 + rcr->available--;
127935 + lwsync();
127936 + bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor));
127937 +#ifdef CONFIG_FSL_DPA_CHECKING
127938 + rcr->busy = 0;
127939 +#endif
127940 +}
127941 +
127942 +static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
127943 +{
127944 + register struct bm_rcr *rcr = &portal->rcr;
127945 + struct bm_rcr_entry *rcursor;
127946 + DPA_ASSERT(rcr->busy);
127947 + DPA_ASSERT(rcr->pmode == bm_rcr_pvb);
127948 + lwsync();
127949 + rcursor = rcr->cursor;
127950 + rcursor->__dont_write_directly__verb = myverb | rcr->vbit;
127951 + dcbf_64(rcursor);
127952 + RCR_INC(rcr);
127953 + rcr->available--;
127954 +#ifdef CONFIG_FSL_DPA_CHECKING
127955 + rcr->busy = 0;
127956 +#endif
127957 +}
127958 +
127959 +static inline u8 bm_rcr_cci_update(struct bm_portal *portal)
127960 +{
127961 + register struct bm_rcr *rcr = &portal->rcr;
127962 + u8 diff, old_ci = rcr->ci;
127963 + DPA_ASSERT(rcr->cmode == bm_rcr_cci);
127964 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127965 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127966 + rcr->available += diff;
127967 + return diff;
127968 +}
127969 +
127970 +static inline void bm_rcr_cce_prefetch(struct bm_portal *portal)
127971 +{
127972 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127973 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127974 + bm_cl_touch_ro(RCR_CI);
127975 +}
127976 +
127977 +static inline u8 bm_rcr_cce_update(struct bm_portal *portal)
127978 +{
127979 + register struct bm_rcr *rcr = &portal->rcr;
127980 + u8 diff, old_ci = rcr->ci;
127981 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127982 + rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1);
127983 + bm_cl_invalidate(RCR_CI);
127984 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127985 + rcr->available += diff;
127986 + return diff;
127987 +}
127988 +
127989 +static inline u8 bm_rcr_get_ithresh(struct bm_portal *portal)
127990 +{
127991 + register struct bm_rcr *rcr = &portal->rcr;
127992 + return rcr->ithresh;
127993 +}
127994 +
127995 +static inline void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
127996 +{
127997 + register struct bm_rcr *rcr = &portal->rcr;
127998 + rcr->ithresh = ithresh;
127999 + bm_out(RCR_ITR, ithresh);
128000 +}
128001 +
128002 +static inline u8 bm_rcr_get_avail(struct bm_portal *portal)
128003 +{
128004 + register struct bm_rcr *rcr = &portal->rcr;
128005 + return rcr->available;
128006 +}
128007 +
128008 +static inline u8 bm_rcr_get_fill(struct bm_portal *portal)
128009 +{
128010 + register struct bm_rcr *rcr = &portal->rcr;
128011 + return BM_RCR_SIZE - 1 - rcr->available;
128012 +}
128013 +
128014 +
128015 +/* ------------------------------ */
128016 +/* --- Management command API --- */
128017 +
128018 +static inline int bm_mc_init(struct bm_portal *portal)
128019 +{
128020 + register struct bm_mc *mc = &portal->mc;
128021 + mc->cr = portal->addr.addr_ce + BM_CL_CR;
128022 + mc->rr = portal->addr.addr_ce + BM_CL_RR0;
128023 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
128024 + BM_MCC_VERB_VBIT) ? 0 : 1;
128025 + mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
128026 +#ifdef CONFIG_FSL_DPA_CHECKING
128027 + mc->state = mc_idle;
128028 +#endif
128029 + return 0;
128030 +}
128031 +
128032 +static inline void bm_mc_finish(struct bm_portal *portal)
128033 +{
128034 + __maybe_unused register struct bm_mc *mc = &portal->mc;
128035 + DPA_ASSERT(mc->state == mc_idle);
128036 +#ifdef CONFIG_FSL_DPA_CHECKING
128037 + if (mc->state != mc_idle)
128038 + pr_crit("Losing incomplete MC command\n");
128039 +#endif
128040 +}
128041 +
128042 +static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
128043 +{
128044 + register struct bm_mc *mc = &portal->mc;
128045 + DPA_ASSERT(mc->state == mc_idle);
128046 +#ifdef CONFIG_FSL_DPA_CHECKING
128047 + mc->state = mc_user;
128048 +#endif
128049 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
128050 + dcbz_64(mc->cr);
128051 +#endif
128052 + return mc->cr;
128053 +}
128054 +
128055 +static inline void bm_mc_abort(struct bm_portal *portal)
128056 +{
128057 + __maybe_unused register struct bm_mc *mc = &portal->mc;
128058 + DPA_ASSERT(mc->state == mc_user);
128059 +#ifdef CONFIG_FSL_DPA_CHECKING
128060 + mc->state = mc_idle;
128061 +#endif
128062 +}
128063 +
128064 +static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
128065 +{
128066 + register struct bm_mc *mc = &portal->mc;
128067 + struct bm_mc_result *rr = mc->rr + mc->rridx;
128068 + DPA_ASSERT(mc->state == mc_user);
128069 + lwsync();
128070 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
128071 + dcbf(mc->cr);
128072 + dcbit_ro(rr);
128073 +#ifdef CONFIG_FSL_DPA_CHECKING
128074 + mc->state = mc_hw;
128075 +#endif
128076 +}
128077 +
128078 +static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
128079 +{
128080 + register struct bm_mc *mc = &portal->mc;
128081 + struct bm_mc_result *rr = mc->rr + mc->rridx;
128082 + DPA_ASSERT(mc->state == mc_hw);
128083 + /* The inactive response register's verb byte always returns zero until
128084 + * its command is submitted and completed. This includes the valid-bit,
128085 + * in case you were wondering... */
128086 + if (!__raw_readb(&rr->verb)) {
128087 + dcbit_ro(rr);
128088 + return NULL;
128089 + }
128090 + mc->rridx ^= 1;
128091 + mc->vbit ^= BM_MCC_VERB_VBIT;
128092 +#ifdef CONFIG_FSL_DPA_CHECKING
128093 + mc->state = mc_idle;
128094 +#endif
128095 + return rr;
128096 +}
128097 +
128098 +
128099 +/* ------------------------------------- */
128100 +/* --- Portal interrupt register API --- */
128101 +
128102 +static inline int bm_isr_init(__always_unused struct bm_portal *portal)
128103 +{
128104 + return 0;
128105 +}
128106 +
128107 +static inline void bm_isr_finish(__always_unused struct bm_portal *portal)
128108 +{
128109 +}
128110 +
128111 +#define SCN_REG(bpid) BM_REG_SCN((bpid) / 32)
128112 +#define SCN_BIT(bpid) (0x80000000 >> (bpid & 31))
128113 +static inline void bm_isr_bscn_mask(struct bm_portal *portal, u8 bpid,
128114 + int enable)
128115 +{
128116 + u32 val;
128117 + DPA_ASSERT(bpid < bman_pool_max);
128118 + /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */
128119 + val = __bm_in(&portal->addr, SCN_REG(bpid));
128120 + if (enable)
128121 + val |= SCN_BIT(bpid);
128122 + else
128123 + val &= ~SCN_BIT(bpid);
128124 + __bm_out(&portal->addr, SCN_REG(bpid), val);
128125 +}
128126 +
128127 +static inline u32 __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n)
128128 +{
128129 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
128130 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 6));
128131 +#else
128132 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 2));
128133 +#endif
128134 +}
128135 +
128136 +static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n,
128137 + u32 val)
128138 +{
128139 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
128140 + __bm_out(&portal->addr, BM_REG_ISR + (n << 6), val);
128141 +#else
128142 + __bm_out(&portal->addr, BM_REG_ISR + (n << 2), val);
128143 +#endif
128144 +}
128145 +
128146 +/* Buffer Pool Cleanup */
128147 +static inline int bm_shutdown_pool(struct bm_portal *p, u32 bpid)
128148 +{
128149 + struct bm_mc_command *bm_cmd;
128150 + struct bm_mc_result *bm_res;
128151 +
128152 + int aq_count = 0;
128153 + bool stop = false;
128154 + while (!stop) {
128155 + /* Acquire buffers until empty */
128156 + bm_cmd = bm_mc_start(p);
128157 + bm_cmd->acquire.bpid = bpid;
128158 + bm_mc_commit(p, BM_MCC_VERB_CMD_ACQUIRE | 1);
128159 + while (!(bm_res = bm_mc_result(p)))
128160 + cpu_relax();
128161 + if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
128162 + /* Pool is empty */
128163 + /* TBD : Should we do a few extra iterations in
128164 + case some other some blocks keep buffers 'on deck',
128165 + which may also be problematic */
128166 + stop = true;
128167 + } else
128168 + ++aq_count;
128169 + }
128170 + return 0;
128171 +}
128172 diff --git a/drivers/staging/fsl_qbman/bman_private.h b/drivers/staging/fsl_qbman/bman_private.h
128173 new file mode 100644
128174 index 00000000..64eefe7d
128175 --- /dev/null
128176 +++ b/drivers/staging/fsl_qbman/bman_private.h
128177 @@ -0,0 +1,166 @@
128178 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
128179 + *
128180 + * Redistribution and use in source and binary forms, with or without
128181 + * modification, are permitted provided that the following conditions are met:
128182 + * * Redistributions of source code must retain the above copyright
128183 + * notice, this list of conditions and the following disclaimer.
128184 + * * Redistributions in binary form must reproduce the above copyright
128185 + * notice, this list of conditions and the following disclaimer in the
128186 + * documentation and/or other materials provided with the distribution.
128187 + * * Neither the name of Freescale Semiconductor nor the
128188 + * names of its contributors may be used to endorse or promote products
128189 + * derived from this software without specific prior written permission.
128190 + *
128191 + *
128192 + * ALTERNATIVELY, this software may be distributed under the terms of the
128193 + * GNU General Public License ("GPL") as published by the Free Software
128194 + * Foundation, either version 2 of that License or (at your option) any
128195 + * later version.
128196 + *
128197 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128198 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128199 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128200 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128201 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128202 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128203 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128204 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128205 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128206 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128207 + */
128208 +
128209 +#include "dpa_sys.h"
128210 +#include <linux/fsl_bman.h>
128211 +
128212 +/* Revision info (for errata and feature handling) */
128213 +#define BMAN_REV10 0x0100
128214 +#define BMAN_REV20 0x0200
128215 +#define BMAN_REV21 0x0201
128216 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
128217 +extern u16 bman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
128218 +
128219 +/*
128220 + * Global variables of the max portal/pool number this bman version supported
128221 + */
128222 +extern u16 bman_pool_max;
128223 +
128224 +/* used by CCSR and portal interrupt code */
128225 +enum bm_isr_reg {
128226 + bm_isr_status = 0,
128227 + bm_isr_enable = 1,
128228 + bm_isr_disable = 2,
128229 + bm_isr_inhibit = 3
128230 +};
128231 +
128232 +struct bm_portal_config {
128233 + /* Corenet portal addresses;
128234 + * [0]==cache-enabled, [1]==cache-inhibited. */
128235 + __iomem void *addr_virt[2];
128236 + struct resource addr_phys[2];
128237 + /* Allow these to be joined in lists */
128238 + struct list_head list;
128239 + /* User-visible portal configuration settings */
128240 + struct bman_portal_config public_cfg;
128241 + /* power management saved data */
128242 + u32 saved_isdr;
128243 +};
128244 +
128245 +#ifdef CONFIG_FSL_BMAN_CONFIG
128246 +/* Hooks from bman_driver.c to bman_config.c */
128247 +int bman_init_ccsr(struct device_node *node);
128248 +#endif
128249 +
128250 +/* Hooks from bman_driver.c in to bman_high.c */
128251 +struct bman_portal *bman_create_portal(
128252 + struct bman_portal *portal,
128253 + const struct bm_portal_config *config);
128254 +struct bman_portal *bman_create_affine_portal(
128255 + const struct bm_portal_config *config);
128256 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
128257 + int cpu);
128258 +void bman_destroy_portal(struct bman_portal *bm);
128259 +
128260 +const struct bm_portal_config *bman_destroy_affine_portal(void);
128261 +
128262 +/* Hooks from fsl_usdpaa.c to bman_driver.c */
128263 +struct bm_portal_config *bm_get_unused_portal(void);
128264 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx);
128265 +void bm_put_unused_portal(struct bm_portal_config *pcfg);
128266 +void bm_set_liodns(struct bm_portal_config *pcfg);
128267 +
128268 +/* Pool logic in the portal driver, during initialisation, needs to know if
128269 + * there's access to CCSR or not (if not, it'll cripple the pool allocator). */
128270 +#ifdef CONFIG_FSL_BMAN_CONFIG
128271 +int bman_have_ccsr(void);
128272 +#else
128273 +#define bman_have_ccsr() 0
128274 +#endif
128275 +
128276 +/* Stockpile build constants. The _LOW value: when bman_acquire() is called and
128277 + * the stockpile fill-level is <= _LOW, an acquire is attempted from h/w but it
128278 + * might fail (if the buffer pool is depleted). So this value provides some
128279 + * "stagger" in that the bman_acquire() function will only fail if lots of bufs
128280 + * are requested at once or if h/w has been tested a couple of times without
128281 + * luck. The _HIGH value: when bman_release() is called and the stockpile
128282 + * fill-level is >= _HIGH, a release is attempted to h/w but it might fail (if
128283 + * the release ring is full). So this value provides some "stagger" so that
128284 + * ring-access is retried a couple of times prior to the API returning a
128285 + * failure. The following *must* be true;
128286 + * BMAN_STOCKPILE_HIGH-BMAN_STOCKPILE_LOW > 8
128287 + * (to avoid thrashing)
128288 + * BMAN_STOCKPILE_SZ >= 16
128289 + * (as the release logic expects to either send 8 buffers to hw prior to
128290 + * adding the given buffers to the stockpile or add the buffers to the
128291 + * stockpile before sending 8 to hw, as the API must be an all-or-nothing
128292 + * success/fail.)
128293 + */
128294 +#define BMAN_STOCKPILE_SZ 16u /* number of bufs in per-pool cache */
128295 +#define BMAN_STOCKPILE_LOW 2u /* when fill is <= this, acquire from hw */
128296 +#define BMAN_STOCKPILE_HIGH 14u /* when fill is >= this, release to hw */
128297 +
128298 +/*************************************************/
128299 +/* BMan s/w corenet portal, low-level i/face */
128300 +/*************************************************/
128301 +
128302 +/* Used by all portal interrupt registers except 'inhibit'
128303 + * This mask contains all the "irqsource" bits visible to API users
128304 + */
128305 +#define BM_PIRQ_VISIBLE (BM_PIRQ_RCRI | BM_PIRQ_BSCN)
128306 +
128307 +/* These are bm_<reg>_<verb>(). So for example, bm_disable_write() means "write
128308 + * the disable register" rather than "disable the ability to write". */
128309 +#define bm_isr_status_read(bm) __bm_isr_read(bm, bm_isr_status)
128310 +#define bm_isr_status_clear(bm, m) __bm_isr_write(bm, bm_isr_status, m)
128311 +#define bm_isr_enable_read(bm) __bm_isr_read(bm, bm_isr_enable)
128312 +#define bm_isr_enable_write(bm, v) __bm_isr_write(bm, bm_isr_enable, v)
128313 +#define bm_isr_disable_read(bm) __bm_isr_read(bm, bm_isr_disable)
128314 +#define bm_isr_disable_write(bm, v) __bm_isr_write(bm, bm_isr_disable, v)
128315 +#define bm_isr_inhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 1)
128316 +#define bm_isr_uninhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 0)
128317 +
128318 +#ifdef CONFIG_FSL_BMAN_CONFIG
128319 +/* Set depletion thresholds associated with a buffer pool. Requires that the
128320 + * operating system have access to Bman CCSR (ie. compiled in support and
128321 + * run-time access courtesy of the device-tree). */
128322 +int bm_pool_set(u32 bpid, const u32 *thresholds);
128323 +#define BM_POOL_THRESH_SW_ENTER 0
128324 +#define BM_POOL_THRESH_SW_EXIT 1
128325 +#define BM_POOL_THRESH_HW_ENTER 2
128326 +#define BM_POOL_THRESH_HW_EXIT 3
128327 +
128328 +/* Read the free buffer count for a given buffer */
128329 +u32 bm_pool_free_buffers(u32 bpid);
128330 +
128331 +__init int bman_init(void);
128332 +__init int bman_resource_init(void);
128333 +
128334 +const struct bm_portal_config *bman_get_bm_portal_config(
128335 + struct bman_portal *portal);
128336 +
128337 +/* power management */
128338 +#ifdef CONFIG_SUSPEND
128339 +void suspend_unused_bportal(void);
128340 +void resume_unused_bportal(void);
128341 +#endif
128342 +
128343 +#endif /* CONFIG_FSL_BMAN_CONFIG */
128344 diff --git a/drivers/staging/fsl_qbman/bman_test.c b/drivers/staging/fsl_qbman/bman_test.c
128345 new file mode 100644
128346 index 00000000..db5b7fd3
128347 --- /dev/null
128348 +++ b/drivers/staging/fsl_qbman/bman_test.c
128349 @@ -0,0 +1,56 @@
128350 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
128351 + *
128352 + * Redistribution and use in source and binary forms, with or without
128353 + * modification, are permitted provided that the following conditions are met:
128354 + * * Redistributions of source code must retain the above copyright
128355 + * notice, this list of conditions and the following disclaimer.
128356 + * * Redistributions in binary form must reproduce the above copyright
128357 + * notice, this list of conditions and the following disclaimer in the
128358 + * documentation and/or other materials provided with the distribution.
128359 + * * Neither the name of Freescale Semiconductor nor the
128360 + * names of its contributors may be used to endorse or promote products
128361 + * derived from this software without specific prior written permission.
128362 + *
128363 + *
128364 + * ALTERNATIVELY, this software may be distributed under the terms of the
128365 + * GNU General Public License ("GPL") as published by the Free Software
128366 + * Foundation, either version 2 of that License or (at your option) any
128367 + * later version.
128368 + *
128369 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128370 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128371 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128372 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128373 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128374 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128375 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128376 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128377 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128378 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128379 + */
128380 +
128381 +#include "bman_test.h"
128382 +
128383 +MODULE_AUTHOR("Geoff Thorpe");
128384 +MODULE_LICENSE("Dual BSD/GPL");
128385 +MODULE_DESCRIPTION("Bman testing");
128386 +
128387 +static int test_init(void)
128388 +{
128389 +#ifdef CONFIG_FSL_BMAN_TEST_HIGH
128390 + int loop = 1;
128391 + while (loop--)
128392 + bman_test_high();
128393 +#endif
128394 +#ifdef CONFIG_FSL_BMAN_TEST_THRESH
128395 + bman_test_thresh();
128396 +#endif
128397 + return 0;
128398 +}
128399 +
128400 +static void test_exit(void)
128401 +{
128402 +}
128403 +
128404 +module_init(test_init);
128405 +module_exit(test_exit);
128406 diff --git a/drivers/staging/fsl_qbman/bman_test.h b/drivers/staging/fsl_qbman/bman_test.h
128407 new file mode 100644
128408 index 00000000..fcd65056
128409 --- /dev/null
128410 +++ b/drivers/staging/fsl_qbman/bman_test.h
128411 @@ -0,0 +1,44 @@
128412 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
128413 + *
128414 + * Redistribution and use in source and binary forms, with or without
128415 + * modification, are permitted provided that the following conditions are met:
128416 + * * Redistributions of source code must retain the above copyright
128417 + * notice, this list of conditions and the following disclaimer.
128418 + * * Redistributions in binary form must reproduce the above copyright
128419 + * notice, this list of conditions and the following disclaimer in the
128420 + * documentation and/or other materials provided with the distribution.
128421 + * * Neither the name of Freescale Semiconductor nor the
128422 + * names of its contributors may be used to endorse or promote products
128423 + * derived from this software without specific prior written permission.
128424 + *
128425 + *
128426 + * ALTERNATIVELY, this software may be distributed under the terms of the
128427 + * GNU General Public License ("GPL") as published by the Free Software
128428 + * Foundation, either version 2 of that License or (at your option) any
128429 + * later version.
128430 + *
128431 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128432 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128433 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128434 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128435 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128436 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128437 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128438 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128439 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128440 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128441 + */
128442 +
128443 +#include <linux/kernel.h>
128444 +#include <linux/errno.h>
128445 +#include <linux/io.h>
128446 +#include <linux/slab.h>
128447 +#include <linux/module.h>
128448 +#include <linux/interrupt.h>
128449 +#include <linux/delay.h>
128450 +#include <linux/kthread.h>
128451 +
128452 +#include <linux/fsl_bman.h>
128453 +
128454 +void bman_test_high(void);
128455 +void bman_test_thresh(void);
128456 diff --git a/drivers/staging/fsl_qbman/bman_test_high.c b/drivers/staging/fsl_qbman/bman_test_high.c
128457 new file mode 100644
128458 index 00000000..1617a531
128459 --- /dev/null
128460 +++ b/drivers/staging/fsl_qbman/bman_test_high.c
128461 @@ -0,0 +1,183 @@
128462 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
128463 + *
128464 + * Redistribution and use in source and binary forms, with or without
128465 + * modification, are permitted provided that the following conditions are met:
128466 + * * Redistributions of source code must retain the above copyright
128467 + * notice, this list of conditions and the following disclaimer.
128468 + * * Redistributions in binary form must reproduce the above copyright
128469 + * notice, this list of conditions and the following disclaimer in the
128470 + * documentation and/or other materials provided with the distribution.
128471 + * * Neither the name of Freescale Semiconductor nor the
128472 + * names of its contributors may be used to endorse or promote products
128473 + * derived from this software without specific prior written permission.
128474 + *
128475 + *
128476 + * ALTERNATIVELY, this software may be distributed under the terms of the
128477 + * GNU General Public License ("GPL") as published by the Free Software
128478 + * Foundation, either version 2 of that License or (at your option) any
128479 + * later version.
128480 + *
128481 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128482 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128483 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128484 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128485 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128486 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128487 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128488 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128489 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128490 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128491 + */
128492 +
128493 +#include "bman_test.h"
128494 +#include "bman_private.h"
128495 +
128496 +/*************/
128497 +/* constants */
128498 +/*************/
128499 +
128500 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
128501 +#define POOL_OPAQUE ((void *)0xdeadabba)
128502 +#define NUM_BUFS 93
128503 +#define LOOPS 3
128504 +#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
128505 +
128506 +/***************/
128507 +/* global vars */
128508 +/***************/
128509 +
128510 +static struct bman_pool *pool;
128511 +static int depleted;
128512 +static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
128513 +static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
128514 +static int bufs_received;
128515 +
128516 +/* Predeclare the callback so we can instantiate pool parameters */
128517 +static void depletion_cb(struct bman_portal *, struct bman_pool *, void *, int);
128518 +
128519 +/**********************/
128520 +/* internal functions */
128521 +/**********************/
128522 +
128523 +static void bufs_init(void)
128524 +{
128525 + int i;
128526 + for (i = 0; i < NUM_BUFS; i++)
128527 + bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
128528 + bufs_received = 0;
128529 +}
128530 +
128531 +static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
128532 +{
128533 + if ((bman_ip_rev == BMAN_REV20) || (bman_ip_rev == BMAN_REV21)) {
128534 +
128535 + /* On SoCs with Bman revison 2.0, Bman only respects the 40
128536 + * LS-bits of buffer addresses, masking off the upper 8-bits on
128537 + * release commands. The API provides for 48-bit addresses
128538 + * because some SoCs support all 48-bits. When generating
128539 + * garbage addresses for testing, we either need to zero the
128540 + * upper 8-bits when releasing to Bman (otherwise we'll be
128541 + * disappointed when the buffers we acquire back from Bman
128542 + * don't match), or we need to mask the upper 8-bits off when
128543 + * comparing. We do the latter.
128544 + */
128545 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
128546 + < (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
128547 + return -1;
128548 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
128549 + > (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
128550 + return 1;
128551 + } else {
128552 + if (bm_buffer_get64(a) < bm_buffer_get64(b))
128553 + return -1;
128554 + if (bm_buffer_get64(a) > bm_buffer_get64(b))
128555 + return 1;
128556 + }
128557 +
128558 + return 0;
128559 +}
128560 +
128561 +static void bufs_confirm(void)
128562 +{
128563 + int i, j;
128564 + for (i = 0; i < NUM_BUFS; i++) {
128565 + int matches = 0;
128566 + for (j = 0; j < NUM_BUFS; j++)
128567 + if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
128568 + matches++;
128569 + BUG_ON(matches != 1);
128570 + }
128571 +}
128572 +
128573 +/********/
128574 +/* test */
128575 +/********/
128576 +
128577 +static void depletion_cb(struct bman_portal *__portal, struct bman_pool *__pool,
128578 + void *pool_ctx, int __depleted)
128579 +{
128580 + BUG_ON(__pool != pool);
128581 + BUG_ON(pool_ctx != POOL_OPAQUE);
128582 + depleted = __depleted;
128583 +}
128584 +
128585 +void bman_test_high(void)
128586 +{
128587 + struct bman_pool_params pparams = {
128588 + .flags = BMAN_POOL_FLAG_DEPLETION | BMAN_POOL_FLAG_DYNAMIC_BPID,
128589 + .cb = depletion_cb,
128590 + .cb_ctx = POOL_OPAQUE,
128591 + };
128592 + int i, loops = LOOPS;
128593 + struct bm_buffer tmp_buf;
128594 +
128595 + bufs_init();
128596 +
128597 + pr_info("BMAN: --- starting high-level test ---\n");
128598 +
128599 + pool = bman_new_pool(&pparams);
128600 + BUG_ON(!pool);
128601 +
128602 + /*******************/
128603 + /* Release buffers */
128604 + /*******************/
128605 +do_loop:
128606 + i = 0;
128607 + while (i < NUM_BUFS) {
128608 + u32 flags = BMAN_RELEASE_FLAG_WAIT;
128609 + int num = 8;
128610 + if ((i + num) > NUM_BUFS)
128611 + num = NUM_BUFS - i;
128612 + if ((i + num) == NUM_BUFS)
128613 + flags |= BMAN_RELEASE_FLAG_WAIT_SYNC;
128614 + if (bman_release(pool, bufs_in + i, num, flags))
128615 + panic("bman_release() failed\n");
128616 + i += num;
128617 + }
128618 +
128619 + /*******************/
128620 + /* Acquire buffers */
128621 + /*******************/
128622 + while (i > 0) {
128623 + int tmp, num = 8;
128624 + if (num > i)
128625 + num = i;
128626 + tmp = bman_acquire(pool, bufs_out + i - num, num, 0);
128627 + BUG_ON(tmp != num);
128628 + i -= num;
128629 + }
128630 +
128631 + i = bman_acquire(pool, &tmp_buf, 1, 0);
128632 + BUG_ON(i > 0);
128633 +
128634 + bufs_confirm();
128635 +
128636 + if (--loops)
128637 + goto do_loop;
128638 +
128639 + /************/
128640 + /* Clean up */
128641 + /************/
128642 + bman_free_pool(pool);
128643 + pr_info("BMAN: --- finished high-level test ---\n");
128644 +}
128645 diff --git a/drivers/staging/fsl_qbman/bman_test_thresh.c b/drivers/staging/fsl_qbman/bman_test_thresh.c
128646 new file mode 100644
128647 index 00000000..67093693
128648 --- /dev/null
128649 +++ b/drivers/staging/fsl_qbman/bman_test_thresh.c
128650 @@ -0,0 +1,196 @@
128651 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
128652 + *
128653 + * Redistribution and use in source and binary forms, with or without
128654 + * modification, are permitted provided that the following conditions are met:
128655 + * * Redistributions of source code must retain the above copyright
128656 + * notice, this list of conditions and the following disclaimer.
128657 + * * Redistributions in binary form must reproduce the above copyright
128658 + * notice, this list of conditions and the following disclaimer in the
128659 + * documentation and/or other materials provided with the distribution.
128660 + * * Neither the name of Freescale Semiconductor nor the
128661 + * names of its contributors may be used to endorse or promote products
128662 + * derived from this software without specific prior written permission.
128663 + *
128664 + *
128665 + * ALTERNATIVELY, this software may be distributed under the terms of the
128666 + * GNU General Public License ("GPL") as published by the Free Software
128667 + * Foundation, either version 2 of that License or (at your option) any
128668 + * later version.
128669 + *
128670 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128671 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128672 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128673 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128674 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128675 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128676 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128677 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128678 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128679 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128680 + */
128681 +
128682 +#include "bman_test.h"
128683 +
128684 +/* Test constants */
128685 +#define TEST_NUMBUFS 129728
128686 +#define TEST_EXIT 129536
128687 +#define TEST_ENTRY 129024
128688 +
128689 +struct affine_test_data {
128690 + struct task_struct *t;
128691 + int cpu;
128692 + int expect_affinity;
128693 + int drain;
128694 + int num_enter;
128695 + int num_exit;
128696 + struct list_head node;
128697 + struct completion wakethread;
128698 + struct completion wakeparent;
128699 +};
128700 +
128701 +static void cb_depletion(struct bman_portal *portal,
128702 + struct bman_pool *pool,
128703 + void *opaque,
128704 + int depleted)
128705 +{
128706 + struct affine_test_data *data = opaque;
128707 + int c = smp_processor_id();
128708 + pr_info("cb_depletion: bpid=%d, depleted=%d, cpu=%d, original=%d\n",
128709 + bman_get_params(pool)->bpid, !!depleted, c, data->cpu);
128710 + /* We should be executing on the CPU of the thread that owns the pool if
128711 + * and that CPU has an affine portal (ie. it isn't slaved). */
128712 + BUG_ON((c != data->cpu) && data->expect_affinity);
128713 + BUG_ON((c == data->cpu) && !data->expect_affinity);
128714 + if (depleted)
128715 + data->num_enter++;
128716 + else
128717 + data->num_exit++;
128718 +}
128719 +
128720 +/* Params used to set up a pool, this also dynamically allocates a BPID */
128721 +static const struct bman_pool_params params_nocb = {
128722 + .flags = BMAN_POOL_FLAG_DYNAMIC_BPID | BMAN_POOL_FLAG_THRESH,
128723 + .thresholds = { TEST_ENTRY, TEST_EXIT, 0, 0 }
128724 +};
128725 +
128726 +/* Params used to set up each cpu's pool with callbacks enabled */
128727 +static struct bman_pool_params params_cb = {
128728 + .bpid = 0, /* will be replaced to match pool_nocb */
128729 + .flags = BMAN_POOL_FLAG_DEPLETION,
128730 + .cb = cb_depletion
128731 +};
128732 +
128733 +static struct bman_pool *pool_nocb;
128734 +static LIST_HEAD(threads);
128735 +
128736 +static int affine_test(void *__data)
128737 +{
128738 + struct bman_pool *pool;
128739 + struct affine_test_data *data = __data;
128740 + struct bman_pool_params my_params = params_cb;
128741 +
128742 + pr_info("thread %d: starting\n", data->cpu);
128743 + /* create the pool */
128744 + my_params.cb_ctx = data;
128745 + pool = bman_new_pool(&my_params);
128746 + BUG_ON(!pool);
128747 + complete(&data->wakeparent);
128748 + wait_for_completion(&data->wakethread);
128749 + init_completion(&data->wakethread);
128750 +
128751 + /* if we're the drainer, we get signalled for that */
128752 + if (data->drain) {
128753 + struct bm_buffer buf;
128754 + int ret;
128755 + pr_info("thread %d: draining...\n", data->cpu);
128756 + do {
128757 + ret = bman_acquire(pool, &buf, 1, 0);
128758 + } while (ret > 0);
128759 + pr_info("thread %d: draining done.\n", data->cpu);
128760 + complete(&data->wakeparent);
128761 + wait_for_completion(&data->wakethread);
128762 + init_completion(&data->wakethread);
128763 + }
128764 +
128765 + /* cleanup */
128766 + bman_free_pool(pool);
128767 + while (!kthread_should_stop())
128768 + cpu_relax();
128769 + pr_info("thread %d: exiting\n", data->cpu);
128770 + return 0;
128771 +}
128772 +
128773 +static struct affine_test_data *start_affine_test(int cpu, int drain)
128774 +{
128775 + struct affine_test_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
128776 +
128777 + if (!data)
128778 + return NULL;
128779 + data->cpu = cpu;
128780 + data->expect_affinity = cpumask_test_cpu(cpu, bman_affine_cpus());
128781 + data->drain = drain;
128782 + data->num_enter = 0;
128783 + data->num_exit = 0;
128784 + init_completion(&data->wakethread);
128785 + init_completion(&data->wakeparent);
128786 + list_add_tail(&data->node, &threads);
128787 + data->t = kthread_create(affine_test, data, "threshtest%d", cpu);
128788 + BUG_ON(IS_ERR(data->t));
128789 + kthread_bind(data->t, cpu);
128790 + wake_up_process(data->t);
128791 + return data;
128792 +}
128793 +
128794 +void bman_test_thresh(void)
128795 +{
128796 + int loop = TEST_NUMBUFS;
128797 + int ret, num_cpus = 0;
128798 + struct affine_test_data *data, *drainer = NULL;
128799 +
128800 + pr_info("bman_test_thresh: start\n");
128801 +
128802 + /* allocate a BPID and seed it */
128803 + pool_nocb = bman_new_pool(&params_nocb);
128804 + BUG_ON(!pool_nocb);
128805 + while (loop--) {
128806 + struct bm_buffer buf;
128807 + bm_buffer_set64(&buf, 0x0badbeef + loop);
128808 + ret = bman_release(pool_nocb, &buf, 1,
128809 + BMAN_RELEASE_FLAG_WAIT);
128810 + BUG_ON(ret);
128811 + }
128812 + while (!bman_rcr_is_empty())
128813 + cpu_relax();
128814 + pr_info("bman_test_thresh: buffers are in\n");
128815 +
128816 + /* create threads and wait for them to create pools */
128817 + params_cb.bpid = bman_get_params(pool_nocb)->bpid;
128818 + for_each_cpu(loop, cpu_online_mask) {
128819 + data = start_affine_test(loop, drainer ? 0 : 1);
128820 + BUG_ON(!data);
128821 + if (!drainer)
128822 + drainer = data;
128823 + num_cpus++;
128824 + wait_for_completion(&data->wakeparent);
128825 + }
128826 +
128827 + /* signal the drainer to start draining */
128828 + complete(&drainer->wakethread);
128829 + wait_for_completion(&drainer->wakeparent);
128830 + init_completion(&drainer->wakeparent);
128831 +
128832 + /* tear down */
128833 + list_for_each_entry_safe(data, drainer, &threads, node) {
128834 + complete(&data->wakethread);
128835 + ret = kthread_stop(data->t);
128836 + BUG_ON(ret);
128837 + list_del(&data->node);
128838 + /* check that we get the expected callbacks (and no others) */
128839 + BUG_ON(data->num_enter != 1);
128840 + BUG_ON(data->num_exit != 0);
128841 + kfree(data);
128842 + }
128843 + bman_free_pool(pool_nocb);
128844 +
128845 + pr_info("bman_test_thresh: done\n");
128846 +}
128847 diff --git a/drivers/staging/fsl_qbman/dpa_alloc.c b/drivers/staging/fsl_qbman/dpa_alloc.c
128848 new file mode 100644
128849 index 00000000..44db3e1e
128850 --- /dev/null
128851 +++ b/drivers/staging/fsl_qbman/dpa_alloc.c
128852 @@ -0,0 +1,706 @@
128853 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
128854 + *
128855 + * Redistribution and use in source and binary forms, with or without
128856 + * modification, are permitted provided that the following conditions are met:
128857 + * * Redistributions of source code must retain the above copyright
128858 + * notice, this list of conditions and the following disclaimer.
128859 + * * Redistributions in binary form must reproduce the above copyright
128860 + * notice, this list of conditions and the following disclaimer in the
128861 + * documentation and/or other materials provided with the distribution.
128862 + * * Neither the name of Freescale Semiconductor nor the
128863 + * names of its contributors may be used to endorse or promote products
128864 + * derived from this software without specific prior written permission.
128865 + *
128866 + *
128867 + * ALTERNATIVELY, this software may be distributed under the terms of the
128868 + * GNU General Public License ("GPL") as published by the Free Software
128869 + * Foundation, either version 2 of that License or (at your option) any
128870 + * later version.
128871 + *
128872 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128873 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128874 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128875 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128876 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128877 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128878 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128879 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128880 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128881 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128882 + */
128883 +
128884 +#include "dpa_sys.h"
128885 +#include <linux/fsl_qman.h>
128886 +#include <linux/fsl_bman.h>
128887 +
128888 +/* Qman and Bman APIs are front-ends to the common code; */
128889 +
128890 +static DECLARE_DPA_ALLOC(bpalloc); /* BPID allocator */
128891 +static DECLARE_DPA_ALLOC(fqalloc); /* FQID allocator */
128892 +static DECLARE_DPA_ALLOC(qpalloc); /* pool-channel allocator */
128893 +static DECLARE_DPA_ALLOC(cgralloc); /* CGR ID allocator */
128894 +static DECLARE_DPA_ALLOC(ceetm0_challoc); /* CEETM Channel ID allocator */
128895 +static DECLARE_DPA_ALLOC(ceetm0_lfqidalloc); /* CEETM LFQID allocator */
128896 +static DECLARE_DPA_ALLOC(ceetm1_challoc); /* CEETM Channel ID allocator */
128897 +static DECLARE_DPA_ALLOC(ceetm1_lfqidalloc); /* CEETM LFQID allocator */
128898 +
128899 +/* This is a sort-of-conditional dpa_alloc_free() routine. Eg. when releasing
128900 + * FQIDs (probably from user-space), it can filter out those that aren't in the
128901 + * OOS state (better to leak a h/w resource than to crash). This function
128902 + * returns the number of invalid IDs that were not released. */
128903 +static u32 release_id_range(struct dpa_alloc *alloc, u32 id, u32 count,
128904 + int (*is_valid)(u32 id))
128905 +{
128906 + int valid_mode = 0;
128907 + u32 loop = id, total_invalid = 0;
128908 + while (loop < (id + count)) {
128909 + int isvalid = is_valid ? is_valid(loop) : 1;
128910 + if (!valid_mode) {
128911 + /* We're looking for a valid ID to terminate an invalid
128912 + * range */
128913 + if (isvalid) {
128914 + /* We finished a range of invalid IDs, a valid
128915 + * range is now underway */
128916 + valid_mode = 1;
128917 + count -= (loop - id);
128918 + id = loop;
128919 + } else
128920 + total_invalid++;
128921 + } else {
128922 + /* We're looking for an invalid ID to terminate a
128923 + * valid range */
128924 + if (!isvalid) {
128925 + /* Release the range of valid IDs, an unvalid
128926 + * range is now underway */
128927 + if (loop > id)
128928 + dpa_alloc_free(alloc, id, loop - id);
128929 + valid_mode = 0;
128930 + }
128931 + }
128932 + loop++;
128933 + }
128934 + /* Release any unterminated range of valid IDs */
128935 + if (valid_mode && count)
128936 + dpa_alloc_free(alloc, id, count);
128937 + return total_invalid;
128938 +}
128939 +
128940 +/* BPID allocator front-end */
128941 +
128942 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial)
128943 +{
128944 + return dpa_alloc_new(&bpalloc, result, count, align, partial);
128945 +}
128946 +EXPORT_SYMBOL(bman_alloc_bpid_range);
128947 +
128948 +static int bp_cleanup(u32 bpid)
128949 +{
128950 + return bman_shutdown_pool(bpid) == 0;
128951 +}
128952 +void bman_release_bpid_range(u32 bpid, u32 count)
128953 +{
128954 + u32 total_invalid = release_id_range(&bpalloc, bpid, count, bp_cleanup);
128955 + if (total_invalid)
128956 + pr_err("BPID range [%d..%d] (%d) had %d leaks\n",
128957 + bpid, bpid + count - 1, count, total_invalid);
128958 +}
128959 +EXPORT_SYMBOL(bman_release_bpid_range);
128960 +
128961 +void bman_seed_bpid_range(u32 bpid, u32 count)
128962 +{
128963 + dpa_alloc_seed(&bpalloc, bpid, count);
128964 +}
128965 +EXPORT_SYMBOL(bman_seed_bpid_range);
128966 +
128967 +int bman_reserve_bpid_range(u32 bpid, u32 count)
128968 +{
128969 + return dpa_alloc_reserve(&bpalloc, bpid, count);
128970 +}
128971 +EXPORT_SYMBOL(bman_reserve_bpid_range);
128972 +
128973 +
128974 +/* FQID allocator front-end */
128975 +
128976 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial)
128977 +{
128978 + return dpa_alloc_new(&fqalloc, result, count, align, partial);
128979 +}
128980 +EXPORT_SYMBOL(qman_alloc_fqid_range);
128981 +
128982 +static int fq_cleanup(u32 fqid)
128983 +{
128984 + return qman_shutdown_fq(fqid) == 0;
128985 +}
128986 +void qman_release_fqid_range(u32 fqid, u32 count)
128987 +{
128988 + u32 total_invalid = release_id_range(&fqalloc, fqid, count, fq_cleanup);
128989 + if (total_invalid)
128990 + pr_err("FQID range [%d..%d] (%d) had %d leaks\n",
128991 + fqid, fqid + count - 1, count, total_invalid);
128992 +}
128993 +EXPORT_SYMBOL(qman_release_fqid_range);
128994 +
128995 +int qman_reserve_fqid_range(u32 fqid, u32 count)
128996 +{
128997 + return dpa_alloc_reserve(&fqalloc, fqid, count);
128998 +}
128999 +EXPORT_SYMBOL(qman_reserve_fqid_range);
129000 +
129001 +void qman_seed_fqid_range(u32 fqid, u32 count)
129002 +{
129003 + dpa_alloc_seed(&fqalloc, fqid, count);
129004 +}
129005 +EXPORT_SYMBOL(qman_seed_fqid_range);
129006 +
129007 +/* Pool-channel allocator front-end */
129008 +
129009 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial)
129010 +{
129011 + return dpa_alloc_new(&qpalloc, result, count, align, partial);
129012 +}
129013 +EXPORT_SYMBOL(qman_alloc_pool_range);
129014 +
129015 +static int qpool_cleanup(u32 qp)
129016 +{
129017 + /* We query all FQDs starting from
129018 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
129019 + * whose destination channel is the pool-channel being released.
129020 + * When a non-OOS FQD is found we attempt to clean it up */
129021 + struct qman_fq fq = {
129022 + .fqid = 1
129023 + };
129024 + int err;
129025 + do {
129026 + struct qm_mcr_queryfq_np np;
129027 + err = qman_query_fq_np(&fq, &np);
129028 + if (err)
129029 + /* FQID range exceeded, found no problems */
129030 + return 1;
129031 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
129032 + struct qm_fqd fqd;
129033 + err = qman_query_fq(&fq, &fqd);
129034 + BUG_ON(err);
129035 + if (fqd.dest.channel == qp) {
129036 + /* The channel is the FQ's target, clean it */
129037 + if (qman_shutdown_fq(fq.fqid) != 0)
129038 + /* Couldn't shut down the FQ
129039 + so the pool must be leaked */
129040 + return 0;
129041 + }
129042 + }
129043 + /* Move to the next FQID */
129044 + fq.fqid++;
129045 + } while (1);
129046 +}
129047 +void qman_release_pool_range(u32 qp, u32 count)
129048 +{
129049 + u32 total_invalid = release_id_range(&qpalloc, qp,
129050 + count, qpool_cleanup);
129051 + if (total_invalid) {
129052 + /* Pool channels are almost always used individually */
129053 + if (count == 1)
129054 + pr_err("Pool channel 0x%x had %d leaks\n",
129055 + qp, total_invalid);
129056 + else
129057 + pr_err("Pool channels [%d..%d] (%d) had %d leaks\n",
129058 + qp, qp + count - 1, count, total_invalid);
129059 + }
129060 +}
129061 +EXPORT_SYMBOL(qman_release_pool_range);
129062 +
129063 +
129064 +void qman_seed_pool_range(u32 poolid, u32 count)
129065 +{
129066 + dpa_alloc_seed(&qpalloc, poolid, count);
129067 +
129068 +}
129069 +EXPORT_SYMBOL(qman_seed_pool_range);
129070 +
129071 +int qman_reserve_pool_range(u32 poolid, u32 count)
129072 +{
129073 + return dpa_alloc_reserve(&qpalloc, poolid, count);
129074 +}
129075 +EXPORT_SYMBOL(qman_reserve_pool_range);
129076 +
129077 +
129078 +/* CGR ID allocator front-end */
129079 +
129080 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial)
129081 +{
129082 + return dpa_alloc_new(&cgralloc, result, count, align, partial);
129083 +}
129084 +EXPORT_SYMBOL(qman_alloc_cgrid_range);
129085 +
129086 +static int cqr_cleanup(u32 cgrid)
129087 +{
129088 + /* We query all FQDs starting from
129089 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
129090 + * whose CGR is the CGR being released.
129091 + */
129092 + struct qman_fq fq = {
129093 + .fqid = 1
129094 + };
129095 + int err;
129096 + do {
129097 + struct qm_mcr_queryfq_np np;
129098 + err = qman_query_fq_np(&fq, &np);
129099 + if (err)
129100 + /* FQID range exceeded, found no problems */
129101 + return 1;
129102 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
129103 + struct qm_fqd fqd;
129104 + err = qman_query_fq(&fq, &fqd);
129105 + BUG_ON(err);
129106 + if ((fqd.fq_ctrl & QM_FQCTRL_CGE) &&
129107 + (fqd.cgid == cgrid)) {
129108 + pr_err("CRGID 0x%x is being used by FQID 0x%x,"
129109 + " CGR will be leaked\n",
129110 + cgrid, fq.fqid);
129111 + return 1;
129112 + }
129113 + }
129114 + /* Move to the next FQID */
129115 + fq.fqid++;
129116 + } while (1);
129117 +}
129118 +
129119 +void qman_release_cgrid_range(u32 cgrid, u32 count)
129120 +{
129121 + u32 total_invalid = release_id_range(&cgralloc, cgrid,
129122 + count, cqr_cleanup);
129123 + if (total_invalid)
129124 + pr_err("CGRID range [%d..%d] (%d) had %d leaks\n",
129125 + cgrid, cgrid + count - 1, count, total_invalid);
129126 +}
129127 +EXPORT_SYMBOL(qman_release_cgrid_range);
129128 +
129129 +void qman_seed_cgrid_range(u32 cgrid, u32 count)
129130 +{
129131 + dpa_alloc_seed(&cgralloc, cgrid, count);
129132 +
129133 +}
129134 +EXPORT_SYMBOL(qman_seed_cgrid_range);
129135 +
129136 +/* CEETM CHANNEL ID allocator front-end */
129137 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
129138 + int partial)
129139 +{
129140 + return dpa_alloc_new(&ceetm0_challoc, result, count, align, partial);
129141 +}
129142 +EXPORT_SYMBOL(qman_alloc_ceetm0_channel_range);
129143 +
129144 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
129145 + int partial)
129146 +{
129147 + return dpa_alloc_new(&ceetm1_challoc, result, count, align, partial);
129148 +}
129149 +EXPORT_SYMBOL(qman_alloc_ceetm1_channel_range);
129150 +
129151 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count)
129152 +{
129153 + u32 total_invalid;
129154 +
129155 + total_invalid = release_id_range(&ceetm0_challoc, channelid, count,
129156 + NULL);
129157 + if (total_invalid)
129158 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
129159 + channelid, channelid + count - 1, count, total_invalid);
129160 +}
129161 +EXPORT_SYMBOL(qman_release_ceetm0_channel_range);
129162 +
129163 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count)
129164 +{
129165 + dpa_alloc_seed(&ceetm0_challoc, channelid, count);
129166 +
129167 +}
129168 +EXPORT_SYMBOL(qman_seed_ceetm0_channel_range);
129169 +
129170 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count)
129171 +{
129172 + u32 total_invalid;
129173 + total_invalid = release_id_range(&ceetm1_challoc, channelid, count,
129174 + NULL);
129175 + if (total_invalid)
129176 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
129177 + channelid, channelid + count - 1, count, total_invalid);
129178 +}
129179 +EXPORT_SYMBOL(qman_release_ceetm1_channel_range);
129180 +
129181 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count)
129182 +{
129183 + dpa_alloc_seed(&ceetm1_challoc, channelid, count);
129184 +
129185 +}
129186 +EXPORT_SYMBOL(qman_seed_ceetm1_channel_range);
129187 +
129188 +/* CEETM LFQID allocator front-end */
129189 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
129190 + int partial)
129191 +{
129192 + return dpa_alloc_new(&ceetm0_lfqidalloc, result, count, align, partial);
129193 +}
129194 +EXPORT_SYMBOL(qman_alloc_ceetm0_lfqid_range);
129195 +
129196 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
129197 + int partial)
129198 +{
129199 + return dpa_alloc_new(&ceetm1_lfqidalloc, result, count, align, partial);
129200 +}
129201 +EXPORT_SYMBOL(qman_alloc_ceetm1_lfqid_range);
129202 +
129203 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count)
129204 +{
129205 + u32 total_invalid;
129206 +
129207 + total_invalid = release_id_range(&ceetm0_lfqidalloc, lfqid, count,
129208 + NULL);
129209 + if (total_invalid)
129210 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
129211 + lfqid, lfqid + count - 1, count, total_invalid);
129212 +}
129213 +EXPORT_SYMBOL(qman_release_ceetm0_lfqid_range);
129214 +
129215 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count)
129216 +{
129217 + dpa_alloc_seed(&ceetm0_lfqidalloc, lfqid, count);
129218 +
129219 +}
129220 +EXPORT_SYMBOL(qman_seed_ceetm0_lfqid_range);
129221 +
129222 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count)
129223 +{
129224 + u32 total_invalid;
129225 +
129226 + total_invalid = release_id_range(&ceetm1_lfqidalloc, lfqid, count,
129227 + NULL);
129228 + if (total_invalid)
129229 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
129230 + lfqid, lfqid + count - 1, count, total_invalid);
129231 +}
129232 +EXPORT_SYMBOL(qman_release_ceetm1_lfqid_range);
129233 +
129234 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count)
129235 +{
129236 + dpa_alloc_seed(&ceetm1_lfqidalloc, lfqid, count);
129237 +
129238 +}
129239 +EXPORT_SYMBOL(qman_seed_ceetm1_lfqid_range);
129240 +
129241 +
129242 +/* Everything else is the common backend to all the allocators */
129243 +
129244 +/* The allocator is a (possibly-empty) list of these; */
129245 +struct alloc_node {
129246 + struct list_head list;
129247 + u32 base;
129248 + u32 num;
129249 + /* refcount and is_alloced are only set
129250 + when the node is in the used list */
129251 + unsigned int refcount;
129252 + int is_alloced;
129253 +};
129254 +
129255 +/* #define DPA_ALLOC_DEBUG */
129256 +
129257 +#ifdef DPA_ALLOC_DEBUG
129258 +#define DPRINT pr_info
129259 +static void DUMP(struct dpa_alloc *alloc)
129260 +{
129261 + int off = 0;
129262 + char buf[256];
129263 + struct alloc_node *p;
129264 + pr_info("Free Nodes\n");
129265 + list_for_each_entry(p, &alloc->free, list) {
129266 + if (off < 255)
129267 + off += snprintf(buf + off, 255-off, "{%d,%d}",
129268 + p->base, p->base + p->num - 1);
129269 + }
129270 + pr_info("%s\n", buf);
129271 +
129272 + off = 0;
129273 + pr_info("Used Nodes\n");
129274 + list_for_each_entry(p, &alloc->used, list) {
129275 + if (off < 255)
129276 + off += snprintf(buf + off, 255-off, "{%d,%d}",
129277 + p->base, p->base + p->num - 1);
129278 + }
129279 + pr_info("%s\n", buf);
129280 +
129281 +
129282 +
129283 +}
129284 +#else
129285 +#define DPRINT(x...)
129286 +#define DUMP(a)
129287 +#endif
129288 +
129289 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
129290 + int partial)
129291 +{
129292 + struct alloc_node *i = NULL, *next_best = NULL, *used_node = NULL;
129293 + u32 base, next_best_base = 0, num = 0, next_best_num = 0;
129294 + struct alloc_node *margin_left, *margin_right;
129295 +
129296 + *result = (u32)-1;
129297 + DPRINT("alloc_range(%d,%d,%d)\n", count, align, partial);
129298 + DUMP(alloc);
129299 + /* If 'align' is 0, it should behave as though it was 1 */
129300 + if (!align)
129301 + align = 1;
129302 + margin_left = kmalloc(sizeof(*margin_left), GFP_KERNEL);
129303 + if (!margin_left)
129304 + goto err;
129305 + margin_right = kmalloc(sizeof(*margin_right), GFP_KERNEL);
129306 + if (!margin_right) {
129307 + kfree(margin_left);
129308 + goto err;
129309 + }
129310 + spin_lock_irq(&alloc->lock);
129311 + list_for_each_entry(i, &alloc->free, list) {
129312 + base = (i->base + align - 1) / align;
129313 + base *= align;
129314 + if ((base - i->base) >= i->num)
129315 + /* alignment is impossible, regardless of count */
129316 + continue;
129317 + num = i->num - (base - i->base);
129318 + if (num >= count) {
129319 + /* this one will do nicely */
129320 + num = count;
129321 + goto done;
129322 + }
129323 + if (num > next_best_num) {
129324 + next_best = i;
129325 + next_best_base = base;
129326 + next_best_num = num;
129327 + }
129328 + }
129329 + if (partial && next_best) {
129330 + i = next_best;
129331 + base = next_best_base;
129332 + num = next_best_num;
129333 + } else
129334 + i = NULL;
129335 +done:
129336 + if (i) {
129337 + if (base != i->base) {
129338 + margin_left->base = i->base;
129339 + margin_left->num = base - i->base;
129340 + list_add_tail(&margin_left->list, &i->list);
129341 + } else
129342 + kfree(margin_left);
129343 + if ((base + num) < (i->base + i->num)) {
129344 + margin_right->base = base + num;
129345 + margin_right->num = (i->base + i->num) -
129346 + (base + num);
129347 + list_add(&margin_right->list, &i->list);
129348 + } else
129349 + kfree(margin_right);
129350 + list_del(&i->list);
129351 + kfree(i);
129352 + *result = base;
129353 + } else {
129354 + spin_unlock_irq(&alloc->lock);
129355 + kfree(margin_left);
129356 + kfree(margin_right);
129357 + }
129358 +
129359 +err:
129360 + DPRINT("returning %d\n", i ? num : -ENOMEM);
129361 + DUMP(alloc);
129362 + if (!i)
129363 + return -ENOMEM;
129364 +
129365 + /* Add the allocation to the used list with a refcount of 1 */
129366 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
129367 + if (!used_node) {
129368 + spin_unlock_irq(&alloc->lock);
129369 + return -ENOMEM;
129370 + }
129371 + used_node->base = *result;
129372 + used_node->num = num;
129373 + used_node->refcount = 1;
129374 + used_node->is_alloced = 1;
129375 + list_add_tail(&used_node->list, &alloc->used);
129376 + spin_unlock_irq(&alloc->lock);
129377 + return (int)num;
129378 +}
129379 +
129380 +/* Allocate the list node using GFP_ATOMIC, because we *really* want to avoid
129381 + * forcing error-handling on to users in the deallocation path. */
129382 +static void _dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
129383 +{
129384 + struct alloc_node *i, *node = kmalloc(sizeof(*node), GFP_ATOMIC);
129385 + BUG_ON(!node);
129386 + DPRINT("release_range(%d,%d)\n", base_id, count);
129387 + DUMP(alloc);
129388 + BUG_ON(!count);
129389 + spin_lock_irq(&alloc->lock);
129390 +
129391 +
129392 + node->base = base_id;
129393 + node->num = count;
129394 + list_for_each_entry(i, &alloc->free, list) {
129395 + if (i->base >= node->base) {
129396 + /* BUG_ON(any overlapping) */
129397 + BUG_ON(i->base < (node->base + node->num));
129398 + list_add_tail(&node->list, &i->list);
129399 + goto done;
129400 + }
129401 + }
129402 + list_add_tail(&node->list, &alloc->free);
129403 +done:
129404 + /* Merge to the left */
129405 + i = list_entry(node->list.prev, struct alloc_node, list);
129406 + if (node->list.prev != &alloc->free) {
129407 + BUG_ON((i->base + i->num) > node->base);
129408 + if ((i->base + i->num) == node->base) {
129409 + node->base = i->base;
129410 + node->num += i->num;
129411 + list_del(&i->list);
129412 + kfree(i);
129413 + }
129414 + }
129415 + /* Merge to the right */
129416 + i = list_entry(node->list.next, struct alloc_node, list);
129417 + if (node->list.next != &alloc->free) {
129418 + BUG_ON((node->base + node->num) > i->base);
129419 + if ((node->base + node->num) == i->base) {
129420 + node->num += i->num;
129421 + list_del(&i->list);
129422 + kfree(i);
129423 + }
129424 + }
129425 + spin_unlock_irq(&alloc->lock);
129426 + DUMP(alloc);
129427 +}
129428 +
129429 +
129430 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
129431 +{
129432 + struct alloc_node *i = NULL;
129433 + spin_lock_irq(&alloc->lock);
129434 +
129435 + /* First find the node in the used list and decrement its ref count */
129436 + list_for_each_entry(i, &alloc->used, list) {
129437 + if (i->base == base_id && i->num == count) {
129438 + --i->refcount;
129439 + if (i->refcount == 0) {
129440 + list_del(&i->list);
129441 + spin_unlock_irq(&alloc->lock);
129442 + if (i->is_alloced)
129443 + _dpa_alloc_free(alloc, base_id, count);
129444 + kfree(i);
129445 + return;
129446 + }
129447 + spin_unlock_irq(&alloc->lock);
129448 + return;
129449 + }
129450 + }
129451 + /* Couldn't find the allocation */
129452 + pr_err("Attempt to free ID 0x%x COUNT %d that wasn't alloc'd or reserved\n",
129453 + base_id, count);
129454 + spin_unlock_irq(&alloc->lock);
129455 +}
129456 +
129457 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 base_id, u32 count)
129458 +{
129459 + /* Same as free but no previous allocation checking is needed */
129460 + _dpa_alloc_free(alloc, base_id, count);
129461 +}
129462 +
129463 +
129464 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base, u32 num)
129465 +{
129466 + struct alloc_node *i = NULL, *used_node;
129467 +
129468 + DPRINT("alloc_reserve(%d,%d)\n", base, num);
129469 + DUMP(alloc);
129470 +
129471 + spin_lock_irq(&alloc->lock);
129472 +
129473 + /* Check for the node in the used list.
129474 + If found, increase it's refcount */
129475 + list_for_each_entry(i, &alloc->used, list) {
129476 + if ((i->base == base) && (i->num == num)) {
129477 + ++i->refcount;
129478 + spin_unlock_irq(&alloc->lock);
129479 + return 0;
129480 + }
129481 + if ((base >= i->base) && (base < (i->base + i->num))) {
129482 + /* This is an attempt to reserve a region that was
129483 + already reserved or alloced with a different
129484 + base or num */
129485 + pr_err("Cannot reserve %d - %d, it overlaps with"
129486 + " existing reservation from %d - %d\n",
129487 + base, base + num - 1, i->base,
129488 + i->base + i->num - 1);
129489 + spin_unlock_irq(&alloc->lock);
129490 + return -1;
129491 + }
129492 + }
129493 + /* Check to make sure this ID isn't in the free list */
129494 + list_for_each_entry(i, &alloc->free, list) {
129495 + if ((base >= i->base) && (base < (i->base + i->num))) {
129496 + /* yep, the reservation is within this node */
129497 + pr_err("Cannot reserve %d - %d, it overlaps with"
129498 + " free range %d - %d and must be alloced\n",
129499 + base, base + num - 1,
129500 + i->base, i->base + i->num - 1);
129501 + spin_unlock_irq(&alloc->lock);
129502 + return -1;
129503 + }
129504 + }
129505 + /* Add the allocation to the used list with a refcount of 1 */
129506 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
129507 + if (!used_node) {
129508 + spin_unlock_irq(&alloc->lock);
129509 + return -ENOMEM;
129510 +
129511 + }
129512 + used_node->base = base;
129513 + used_node->num = num;
129514 + used_node->refcount = 1;
129515 + used_node->is_alloced = 0;
129516 + list_add_tail(&used_node->list, &alloc->used);
129517 + spin_unlock_irq(&alloc->lock);
129518 + return 0;
129519 +}
129520 +
129521 +
129522 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count)
129523 +{
129524 + struct alloc_node *i = NULL;
129525 + DPRINT("alloc_pop()\n");
129526 + DUMP(alloc);
129527 + spin_lock_irq(&alloc->lock);
129528 + if (!list_empty(&alloc->free)) {
129529 + i = list_entry(alloc->free.next, struct alloc_node, list);
129530 + list_del(&i->list);
129531 + }
129532 + spin_unlock_irq(&alloc->lock);
129533 + DPRINT("returning %d\n", i ? 0 : -ENOMEM);
129534 + DUMP(alloc);
129535 + if (!i)
129536 + return -ENOMEM;
129537 + *result = i->base;
129538 + *count = i->num;
129539 + kfree(i);
129540 + return 0;
129541 +}
129542 +
129543 +int dpa_alloc_check(struct dpa_alloc *list_head, u32 item)
129544 +{
129545 + struct alloc_node *i = NULL;
129546 + int res = 0;
129547 + DPRINT("alloc_check()\n");
129548 + spin_lock_irq(&list_head->lock);
129549 +
129550 + list_for_each_entry(i, &list_head->free, list) {
129551 + if ((item >= i->base) && (item < (i->base + i->num))) {
129552 + res = 1;
129553 + break;
129554 + }
129555 + }
129556 + spin_unlock_irq(&list_head->lock);
129557 + return res;
129558 +}
129559 diff --git a/drivers/staging/fsl_qbman/dpa_sys.h b/drivers/staging/fsl_qbman/dpa_sys.h
129560 new file mode 100644
129561 index 00000000..e144f5a4
129562 --- /dev/null
129563 +++ b/drivers/staging/fsl_qbman/dpa_sys.h
129564 @@ -0,0 +1,259 @@
129565 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
129566 + *
129567 + * Redistribution and use in source and binary forms, with or without
129568 + * modification, are permitted provided that the following conditions are met:
129569 + * * Redistributions of source code must retain the above copyright
129570 + * notice, this list of conditions and the following disclaimer.
129571 + * * Redistributions in binary form must reproduce the above copyright
129572 + * notice, this list of conditions and the following disclaimer in the
129573 + * documentation and/or other materials provided with the distribution.
129574 + * * Neither the name of Freescale Semiconductor nor the
129575 + * names of its contributors may be used to endorse or promote products
129576 + * derived from this software without specific prior written permission.
129577 + *
129578 + *
129579 + * ALTERNATIVELY, this software may be distributed under the terms of the
129580 + * GNU General Public License ("GPL") as published by the Free Software
129581 + * Foundation, either version 2 of that License or (at your option) any
129582 + * later version.
129583 + *
129584 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129585 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129586 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129587 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129588 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129589 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129590 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129591 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129592 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129593 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129594 + */
129595 +
129596 +#ifndef DPA_SYS_H
129597 +#define DPA_SYS_H
129598 +
129599 +#include <linux/kernel.h>
129600 +#include <linux/errno.h>
129601 +#include <linux/io.h>
129602 +#include <linux/dma-mapping.h>
129603 +#include <linux/bootmem.h>
129604 +#include <linux/slab.h>
129605 +#include <linux/module.h>
129606 +#include <linux/init.h>
129607 +#include <linux/interrupt.h>
129608 +#include <linux/delay.h>
129609 +#include <linux/of_platform.h>
129610 +#include <linux/of_address.h>
129611 +#include <linux/of_irq.h>
129612 +#include <linux/kthread.h>
129613 +#include <linux/memblock.h>
129614 +#include <linux/completion.h>
129615 +#include <linux/log2.h>
129616 +#include <linux/types.h>
129617 +#include <linux/ioctl.h>
129618 +#include <linux/miscdevice.h>
129619 +#include <linux/uaccess.h>
129620 +#include <linux/debugfs.h>
129621 +#include <linux/seq_file.h>
129622 +#include <linux/device.h>
129623 +#include <linux/uio_driver.h>
129624 +#include <linux/smp.h>
129625 +#include <linux/fsl_hypervisor.h>
129626 +#include <linux/vmalloc.h>
129627 +#include <linux/ctype.h>
129628 +#include <linux/math64.h>
129629 +#include <linux/bitops.h>
129630 +
129631 +#include <linux/fsl_usdpaa.h>
129632 +
129633 +/* When copying aligned words or shorts, try to avoid memcpy() */
129634 +#define CONFIG_TRY_BETTER_MEMCPY
129635 +
129636 +/* For 2-element tables related to cache-inhibited and cache-enabled mappings */
129637 +#define DPA_PORTAL_CE 0
129638 +#define DPA_PORTAL_CI 1
129639 +
129640 +/***********************/
129641 +/* Misc inline assists */
129642 +/***********************/
129643 +
129644 +#if defined CONFIG_PPC32
129645 +#include "dpa_sys_ppc32.h"
129646 +#elif defined CONFIG_PPC64
129647 +#include "dpa_sys_ppc64.h"
129648 +#elif defined CONFIG_ARM
129649 +#include "dpa_sys_arm.h"
129650 +#elif defined CONFIG_ARM64
129651 +#include "dpa_sys_arm64.h"
129652 +#endif
129653 +
129654 +
129655 +#ifdef CONFIG_FSL_DPA_CHECKING
129656 +#define DPA_ASSERT(x) \
129657 + do { \
129658 + if (!(x)) { \
129659 + pr_crit("ASSERT: (%s:%d) %s\n", __FILE__, __LINE__, \
129660 + __stringify_1(x)); \
129661 + dump_stack(); \
129662 + panic("assertion failure"); \
129663 + } \
129664 + } while (0)
129665 +#else
129666 +#define DPA_ASSERT(x)
129667 +#endif
129668 +
129669 +/* memcpy() stuff - when you know alignments in advance */
129670 +#ifdef CONFIG_TRY_BETTER_MEMCPY
129671 +static inline void copy_words(void *dest, const void *src, size_t sz)
129672 +{
129673 + u32 *__dest = dest;
129674 + const u32 *__src = src;
129675 + size_t __sz = sz >> 2;
129676 + BUG_ON((unsigned long)dest & 0x3);
129677 + BUG_ON((unsigned long)src & 0x3);
129678 + BUG_ON(sz & 0x3);
129679 + while (__sz--)
129680 + *(__dest++) = *(__src++);
129681 +}
129682 +static inline void copy_shorts(void *dest, const void *src, size_t sz)
129683 +{
129684 + u16 *__dest = dest;
129685 + const u16 *__src = src;
129686 + size_t __sz = sz >> 1;
129687 + BUG_ON((unsigned long)dest & 0x1);
129688 + BUG_ON((unsigned long)src & 0x1);
129689 + BUG_ON(sz & 0x1);
129690 + while (__sz--)
129691 + *(__dest++) = *(__src++);
129692 +}
129693 +static inline void copy_bytes(void *dest, const void *src, size_t sz)
129694 +{
129695 + u8 *__dest = dest;
129696 + const u8 *__src = src;
129697 + while (sz--)
129698 + *(__dest++) = *(__src++);
129699 +}
129700 +#else
129701 +#define copy_words memcpy
129702 +#define copy_shorts memcpy
129703 +#define copy_bytes memcpy
129704 +#endif
129705 +
129706 +/************/
129707 +/* RB-trees */
129708 +/************/
129709 +
129710 +/* We encapsulate RB-trees so that its easier to use non-linux forms in
129711 + * non-linux systems. This also encapsulates the extra plumbing that linux code
129712 + * usually provides when using RB-trees. This encapsulation assumes that the
129713 + * data type held by the tree is u32. */
129714 +
129715 +struct dpa_rbtree {
129716 + struct rb_root root;
129717 +};
129718 +#define DPA_RBTREE { .root = RB_ROOT }
129719 +
129720 +static inline void dpa_rbtree_init(struct dpa_rbtree *tree)
129721 +{
129722 + tree->root = RB_ROOT;
129723 +}
129724 +
129725 +#define IMPLEMENT_DPA_RBTREE(name, type, node_field, val_field) \
129726 +static inline int name##_push(struct dpa_rbtree *tree, type *obj) \
129727 +{ \
129728 + struct rb_node *parent = NULL, **p = &tree->root.rb_node; \
129729 + while (*p) { \
129730 + u32 item; \
129731 + parent = *p; \
129732 + item = rb_entry(parent, type, node_field)->val_field; \
129733 + if (obj->val_field < item) \
129734 + p = &parent->rb_left; \
129735 + else if (obj->val_field > item) \
129736 + p = &parent->rb_right; \
129737 + else \
129738 + return -EBUSY; \
129739 + } \
129740 + rb_link_node(&obj->node_field, parent, p); \
129741 + rb_insert_color(&obj->node_field, &tree->root); \
129742 + return 0; \
129743 +} \
129744 +static inline void name##_del(struct dpa_rbtree *tree, type *obj) \
129745 +{ \
129746 + rb_erase(&obj->node_field, &tree->root); \
129747 +} \
129748 +static inline type *name##_find(struct dpa_rbtree *tree, u32 val) \
129749 +{ \
129750 + type *ret; \
129751 + struct rb_node *p = tree->root.rb_node; \
129752 + while (p) { \
129753 + ret = rb_entry(p, type, node_field); \
129754 + if (val < ret->val_field) \
129755 + p = p->rb_left; \
129756 + else if (val > ret->val_field) \
129757 + p = p->rb_right; \
129758 + else \
129759 + return ret; \
129760 + } \
129761 + return NULL; \
129762 +}
129763 +
129764 +/************/
129765 +/* Bootargs */
129766 +/************/
129767 +
129768 +/* Qman has "qportals=" and Bman has "bportals=", they use the same syntax
129769 + * though; a comma-separated list of items, each item being a cpu index and/or a
129770 + * range of cpu indices, and each item optionally be prefixed by "s" to indicate
129771 + * that the portal associated with that cpu should be shared. See bman_driver.c
129772 + * for more specifics. */
129773 +static int __parse_portals_cpu(const char **s, unsigned int *cpu)
129774 +{
129775 + *cpu = 0;
129776 + if (!isdigit(**s))
129777 + return -EINVAL;
129778 + while (isdigit(**s))
129779 + *cpu = *cpu * 10 + (*((*s)++) - '0');
129780 + return 0;
129781 +}
129782 +static inline int parse_portals_bootarg(char *str, struct cpumask *want_shared,
129783 + struct cpumask *want_unshared,
129784 + const char *argname)
129785 +{
129786 + const char *s = str;
129787 + unsigned int shared, cpu1, cpu2, loop;
129788 +
129789 +keep_going:
129790 + if (*s == 's') {
129791 + shared = 1;
129792 + s++;
129793 + } else
129794 + shared = 0;
129795 + if (__parse_portals_cpu(&s, &cpu1))
129796 + goto err;
129797 + if (*s == '-') {
129798 + s++;
129799 + if (__parse_portals_cpu(&s, &cpu2))
129800 + goto err;
129801 + if (cpu2 < cpu1)
129802 + goto err;
129803 + } else
129804 + cpu2 = cpu1;
129805 + for (loop = cpu1; loop <= cpu2; loop++)
129806 + cpumask_set_cpu(loop, shared ? want_shared : want_unshared);
129807 + if (*s == ',') {
129808 + s++;
129809 + goto keep_going;
129810 + } else if ((*s == '\0') || isspace(*s))
129811 + return 0;
129812 +err:
129813 + pr_crit("Malformed %s argument: %s, offset: %lu\n", argname, str,
129814 + (unsigned long)s - (unsigned long)str);
129815 + return -EINVAL;
129816 +}
129817 +#ifdef CONFIG_FSL_USDPAA
129818 +/* Hooks from fsl_usdpaa_irq.c to fsl_usdpaa.c */
129819 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
129820 + enum usdpaa_portal_type ptype, unsigned int *irq,
129821 + void **iir_reg);
129822 +#endif
129823 +#endif /* DPA_SYS_H */
129824 diff --git a/drivers/staging/fsl_qbman/dpa_sys_arm.h b/drivers/staging/fsl_qbman/dpa_sys_arm.h
129825 new file mode 100644
129826 index 00000000..17c5500e
129827 --- /dev/null
129828 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm.h
129829 @@ -0,0 +1,95 @@
129830 +/* Copyright 2016 Freescale Semiconductor, Inc.
129831 + *
129832 + * Redistribution and use in source and binary forms, with or without
129833 + * modification, are permitted provided that the following conditions are met:
129834 + * * Redistributions of source code must retain the above copyright
129835 + * notice, this list of conditions and the following disclaimer.
129836 + * * Redistributions in binary form must reproduce the above copyright
129837 + * notice, this list of conditions and the following disclaimer in the
129838 + * documentation and/or other materials provided with the distribution.
129839 + * * Neither the name of Freescale Semiconductor nor the
129840 + * names of its contributors may be used to endorse or promote products
129841 + * derived from this software without specific prior written permission.
129842 + *
129843 + *
129844 + * ALTERNATIVELY, this software may be distributed under the terms of the
129845 + * GNU General Public License ("GPL") as published by the Free Software
129846 + * Foundation, either version 2 of that License or (at your option) any
129847 + * later version.
129848 + *
129849 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129850 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129851 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129852 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129853 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129854 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129855 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129856 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129857 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129858 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129859 + */
129860 +
129861 +#ifndef DPA_SYS_ARM_H
129862 +#define DPA_SYS_ARM_H
129863 +
129864 +#include <asm/cacheflush.h>
129865 +#include <asm/barrier.h>
129866 +
129867 +/* Implementation of ARM specific routines */
129868 +
129869 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129870 + * barriers and that dcb*() won't fall victim to compiler or execution
129871 + * reordering with respect to other code/instructions that manipulate the same
129872 + * cacheline. */
129873 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129874 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129875 +#define dcbf(p) { asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r" (p) : "memory"); }
129876 +#define dcbt_ro(p) { asm volatile("pld [%0, #64];": : "r" (p)); }
129877 +#define dcbt_rw(p) { asm volatile("pldw [%0, #64];": : "r" (p)); }
129878 +#define dcbi(p) { asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (p) : "memory"); }
129879 +
129880 +#define dcbz_64(p) { memset(p, 0, sizeof(*p)); }
129881 +
129882 +#define dcbf_64(p) \
129883 + do { \
129884 + dcbf((u32)p); \
129885 + } while (0)
129886 +/* Commonly used combo */
129887 +#define dcbit_ro(p) \
129888 + do { \
129889 + dcbi((u32)p); \
129890 + dcbt_ro((u32)p); \
129891 + } while (0)
129892 +
129893 +static inline u64 mfatb(void)
129894 +{
129895 + return get_cycles();
129896 +}
129897 +
129898 +static inline u32 in_be32(volatile void *addr)
129899 +{
129900 + return be32_to_cpu(*((volatile u32 *) addr));
129901 +}
129902 +
129903 +static inline void out_be32(void *addr, u32 val)
129904 +{
129905 + *((u32 *) addr) = cpu_to_be32(val);
129906 +}
129907 +
129908 +
129909 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129910 +{
129911 + *p |= mask;
129912 +}
129913 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129914 +{
129915 + *p &= ~mask;
129916 +}
129917 +
129918 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129919 +{
129920 + __cpuc_flush_dcache_area((void *) start, stop - start);
129921 +}
129922 +
129923 +#define hard_smp_processor_id() raw_smp_processor_id()
129924 +#endif
129925 diff --git a/drivers/staging/fsl_qbman/dpa_sys_arm64.h b/drivers/staging/fsl_qbman/dpa_sys_arm64.h
129926 new file mode 100644
129927 index 00000000..247c8d97
129928 --- /dev/null
129929 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm64.h
129930 @@ -0,0 +1,102 @@
129931 +/* Copyright 2014 Freescale Semiconductor, Inc.
129932 + *
129933 + * Redistribution and use in source and binary forms, with or without
129934 + * modification, are permitted provided that the following conditions are met:
129935 + * * Redistributions of source code must retain the above copyright
129936 + * notice, this list of conditions and the following disclaimer.
129937 + * * Redistributions in binary form must reproduce the above copyright
129938 + * notice, this list of conditions and the following disclaimer in the
129939 + * documentation and/or other materials provided with the distribution.
129940 + * * Neither the name of Freescale Semiconductor nor the
129941 + * names of its contributors may be used to endorse or promote products
129942 + * derived from this software without specific prior written permission.
129943 + *
129944 + *
129945 + * ALTERNATIVELY, this software may be distributed under the terms of the
129946 + * GNU General Public License ("GPL") as published by the Free Software
129947 + * Foundation, either version 2 of that License or (at your option) any
129948 + * later version.
129949 + *
129950 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129951 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129952 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129953 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129954 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129955 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129956 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129957 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129958 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129959 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129960 + */
129961 +
129962 +#ifndef DPA_SYS_ARM64_H
129963 +#define DPA_SYS_ARM64_H
129964 +
129965 +#include <asm/cacheflush.h>
129966 +#include <asm/barrier.h>
129967 +
129968 +/* Implementation of ARM 64 bit specific routines */
129969 +
129970 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129971 + * barriers and that dcb*() won't fall victim to compiler or execution
129972 + * reordering with respect to other code/instructions that manipulate the same
129973 + * cacheline. */
129974 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129975 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129976 +#define dcbf(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
129977 +#define dcbt_ro(p) { asm volatile("prfm pldl1keep, [%0, #0]" : : "r" (p)); }
129978 +#define dcbt_rw(p) { asm volatile("prfm pstl1keep, [%0, #0]" : : "r" (p)); }
129979 +#define dcbi(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
129980 +#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
129981 +
129982 +#define dcbz_64(p) \
129983 + do { \
129984 + dcbz(p); \
129985 + } while (0)
129986 +
129987 +#define dcbf_64(p) \
129988 + do { \
129989 + dcbf(p); \
129990 + } while (0)
129991 +/* Commonly used combo */
129992 +#define dcbit_ro(p) \
129993 + do { \
129994 + dcbi(p); \
129995 + dcbt_ro(p); \
129996 + } while (0)
129997 +
129998 +static inline u64 mfatb(void)
129999 +{
130000 + return get_cycles();
130001 +}
130002 +
130003 +static inline u32 in_be32(volatile void *addr)
130004 +{
130005 + return be32_to_cpu(*((volatile u32 *) addr));
130006 +}
130007 +
130008 +static inline void out_be32(void *addr, u32 val)
130009 +{
130010 + *((u32 *) addr) = cpu_to_be32(val);
130011 +}
130012 +
130013 +
130014 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
130015 +{
130016 + *p |= mask;
130017 +}
130018 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
130019 +{
130020 + *p &= ~mask;
130021 +}
130022 +
130023 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
130024 +{
130025 + __flush_dcache_area((void *) start, stop - start);
130026 +}
130027 +
130028 +#define hard_smp_processor_id() raw_smp_processor_id()
130029 +
130030 +
130031 +
130032 +#endif
130033 diff --git a/drivers/staging/fsl_qbman/dpa_sys_ppc32.h b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h
130034 new file mode 100644
130035 index 00000000..874616df
130036 --- /dev/null
130037 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h
130038 @@ -0,0 +1,70 @@
130039 +/* Copyright 2014 Freescale Semiconductor, Inc.
130040 + *
130041 + * Redistribution and use in source and binary forms, with or without
130042 + * modification, are permitted provided that the following conditions are met:
130043 + * * Redistributions of source code must retain the above copyright
130044 + * notice, this list of conditions and the following disclaimer.
130045 + * * Redistributions in binary form must reproduce the above copyright
130046 + * notice, this list of conditions and the following disclaimer in the
130047 + * documentation and/or other materials provided with the distribution.
130048 + * * Neither the name of Freescale Semiconductor nor the
130049 + * names of its contributors may be used to endorse or promote products
130050 + * derived from this software without specific prior written permission.
130051 + *
130052 + *
130053 + * ALTERNATIVELY, this software may be distributed under the terms of the
130054 + * GNU General Public License ("GPL") as published by the Free Software
130055 + * Foundation, either version 2 of that License or (at your option) any
130056 + * later version.
130057 + *
130058 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
130059 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
130060 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
130061 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
130062 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
130063 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
130064 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
130065 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
130066 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
130067 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
130068 + */
130069 +
130070 +#ifndef DPA_SYS_PPC32_H
130071 +#define DPA_SYS_PPC32_H
130072 +
130073 +/* Implementation of PowerPC 32 bit specific routines */
130074 +
130075 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
130076 + * barriers and that dcb*() won't fall victim to compiler or execution
130077 + * reordering with respect to other code/instructions that manipulate the same
130078 + * cacheline. */
130079 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
130080 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
130081 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
130082 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
130083 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
130084 +#define dcbi(p) dcbf(p)
130085 +
130086 +#define dcbzl(p) __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p))
130087 +#define dcbz_64(p) dcbzl(p)
130088 +#define dcbf_64(p) dcbf(p)
130089 +
130090 +/* Commonly used combo */
130091 +#define dcbit_ro(p) \
130092 + do { \
130093 + dcbi(p); \
130094 + dcbt_ro(p); \
130095 + } while (0)
130096 +
130097 +static inline u64 mfatb(void)
130098 +{
130099 + u32 hi, lo, chk;
130100 + do {
130101 + hi = mfspr(SPRN_ATBU);
130102 + lo = mfspr(SPRN_ATBL);
130103 + chk = mfspr(SPRN_ATBU);
130104 + } while (unlikely(hi != chk));
130105 + return ((u64)hi << 32) | (u64)lo;
130106 +}
130107 +
130108 +#endif
130109 diff --git a/drivers/staging/fsl_qbman/dpa_sys_ppc64.h b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h
130110 new file mode 100644
130111 index 00000000..d9803199
130112 --- /dev/null
130113 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h
130114 @@ -0,0 +1,79 @@
130115 +/* Copyright 2014 Freescale Semiconductor, Inc.
130116 + *
130117 + * Redistribution and use in source and binary forms, with or without
130118 + * modification, are permitted provided that the following conditions are met:
130119 + * * Redistributions of source code must retain the above copyright
130120 + * notice, this list of conditions and the following disclaimer.
130121 + * * Redistributions in binary form must reproduce the above copyright
130122 + * notice, this list of conditions and the following disclaimer in the
130123 + * documentation and/or other materials provided with the distribution.
130124 + * * Neither the name of Freescale Semiconductor nor the
130125 + * names of its contributors may be used to endorse or promote products
130126 + * derived from this software without specific prior written permission.
130127 + *
130128 + *
130129 + * ALTERNATIVELY, this software may be distributed under the terms of the
130130 + * GNU General Public License ("GPL") as published by the Free Software
130131 + * Foundation, either version 2 of that License or (at your option) any
130132 + * later version.
130133 + *
130134 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
130135 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
130136 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
130137 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
130138 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
130139 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
130140 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
130141 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
130142 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
130143 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
130144 + */
130145 +
130146 +#ifndef DPA_SYS_PPC64_H
130147 +#define DPA_SYS_PPC64_H
130148 +
130149 +/* Implementation of PowerPC 64 bit specific routines */
130150 +
130151 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
130152 + * barriers and that dcb*() won't fall victim to compiler or execution
130153 + * reordering with respect to other code/instructions that manipulate the same
130154 + * cacheline. */
130155 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
130156 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
130157 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
130158 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
130159 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
130160 +#define dcbi(p) dcbf(p)
130161 +
130162 +#define dcbz(p) __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p))
130163 +#define dcbz_64(p) \
130164 + do { \
130165 + dcbz((void*)p + 32); \
130166 + dcbz(p); \
130167 + } while (0)
130168 +#define dcbf_64(p) \
130169 + do { \
130170 + dcbf((void*)p + 32); \
130171 + dcbf(p); \
130172 + } while (0)
130173 +/* Commonly used combo */
130174 +#define dcbit_ro(p) \
130175 + do { \
130176 + dcbi(p); \
130177 + dcbi((void*)p + 32); \
130178 + dcbt_ro(p); \
130179 + dcbt_ro((void*)p + 32); \
130180 + } while (0)
130181 +
130182 +static inline u64 mfatb(void)
130183 +{
130184 + u32 hi, lo, chk;
130185 + do {
130186 + hi = mfspr(SPRN_ATBU);
130187 + lo = mfspr(SPRN_ATBL);
130188 + chk = mfspr(SPRN_ATBU);
130189 + } while (unlikely(hi != chk));
130190 + return ((u64)hi << 32) | (u64)lo;
130191 +}
130192 +
130193 +#endif
130194 diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa.c b/drivers/staging/fsl_qbman/fsl_usdpaa.c
130195 new file mode 100644
130196 index 00000000..3a6d3722
130197 --- /dev/null
130198 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
130199 @@ -0,0 +1,1983 @@
130200 +/* Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
130201 + * Authors: Andy Fleming <afleming@freescale.com>
130202 + * Timur Tabi <timur@freescale.com>
130203 + * Geoff Thorpe <Geoff.Thorpe@freescale.com>
130204 + *
130205 + * This file is licensed under the terms of the GNU General Public License
130206 + * version 2. This program is licensed "as is" without any warranty of any
130207 + * kind, whether express or implied.
130208 + */
130209 +
130210 +
130211 +#include <linux/miscdevice.h>
130212 +#include <linux/fs.h>
130213 +#include <linux/cdev.h>
130214 +#include <linux/mm.h>
130215 +#include <linux/of.h>
130216 +#include <linux/memblock.h>
130217 +#include <linux/slab.h>
130218 +#include <linux/mman.h>
130219 +#include <linux/of_reserved_mem.h>
130220 +
130221 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
130222 +#include <mm/mmu_decl.h>
130223 +#endif
130224 +
130225 +#include "dpa_sys.h"
130226 +#include <linux/fsl_usdpaa.h>
130227 +#include "bman_low.h"
130228 +#include "qman_low.h"
130229 +
130230 +/* Physical address range of the memory reservation, exported for mm/mem.c */
130231 +static u64 phys_start;
130232 +static u64 phys_size;
130233 +static u64 arg_phys_size;
130234 +
130235 +/* PFN versions of the above */
130236 +static unsigned long pfn_start;
130237 +static unsigned long pfn_size;
130238 +
130239 +/* Memory reservations are manipulated under this spinlock (which is why 'refs'
130240 + * isn't atomic_t). */
130241 +static DEFINE_SPINLOCK(mem_lock);
130242 +
130243 +/* The range of TLB1 indices */
130244 +static unsigned int first_tlb;
130245 +static unsigned int num_tlb = 1;
130246 +static unsigned int current_tlb; /* loops around for fault handling */
130247 +
130248 +/* Memory reservation is represented as a list of 'mem_fragment's, some of which
130249 + * may be mapped. Unmapped fragments are always merged where possible. */
130250 +static LIST_HEAD(mem_list);
130251 +
130252 +struct mem_mapping;
130253 +
130254 +/* Memory fragments are in 'mem_list'. */
130255 +struct mem_fragment {
130256 + u64 base;
130257 + u64 len;
130258 + unsigned long pfn_base; /* PFN version of 'base' */
130259 + unsigned long pfn_len; /* PFN version of 'len' */
130260 + unsigned int refs; /* zero if unmapped */
130261 + u64 root_len; /* Size of the orignal fragment */
130262 + unsigned long root_pfn; /* PFN of the orignal fragment */
130263 + struct list_head list;
130264 + /* if mapped, flags+name captured at creation time */
130265 + u32 flags;
130266 + char name[USDPAA_DMA_NAME_MAX];
130267 + u64 map_len;
130268 + /* support multi-process locks per-memory-fragment. */
130269 + int has_locking;
130270 + wait_queue_head_t wq;
130271 + struct mem_mapping *owner;
130272 +};
130273 +
130274 +/* Mappings of memory fragments in 'struct ctx'. These are created from
130275 + * ioctl(USDPAA_IOCTL_DMA_MAP), though the actual mapping then happens via a
130276 + * mmap(). */
130277 +struct mem_mapping {
130278 + struct mem_fragment *root_frag;
130279 + u32 frag_count;
130280 + u64 total_size;
130281 + struct list_head list;
130282 + int refs;
130283 + void *virt_addr;
130284 +};
130285 +
130286 +struct portal_mapping {
130287 + struct usdpaa_ioctl_portal_map user;
130288 + union {
130289 + struct qm_portal_config *qportal;
130290 + struct bm_portal_config *bportal;
130291 + };
130292 + /* Declare space for the portals in case the process
130293 + exits unexpectedly and needs to be cleaned by the kernel */
130294 + union {
130295 + struct qm_portal qman_portal_low;
130296 + struct bm_portal bman_portal_low;
130297 + };
130298 + struct list_head list;
130299 + struct resource *phys;
130300 + struct iommu_domain *iommu_domain;
130301 +};
130302 +
130303 +/* Track the DPAA resources the process is using */
130304 +struct active_resource {
130305 + struct list_head list;
130306 + u32 id;
130307 + u32 num;
130308 + unsigned int refcount;
130309 +};
130310 +
130311 +/* Per-FD state (which should also be per-process but we don't enforce that) */
130312 +struct ctx {
130313 + /* Lock to protect the context */
130314 + spinlock_t lock;
130315 + /* Allocated resources get put here for accounting */
130316 + struct list_head resources[usdpaa_id_max];
130317 + /* list of DMA maps */
130318 + struct list_head maps;
130319 + /* list of portal maps */
130320 + struct list_head portals;
130321 +};
130322 +
130323 +/* Different resource classes */
130324 +static const struct alloc_backend {
130325 + enum usdpaa_id_type id_type;
130326 + int (*alloc)(u32 *, u32, u32, int);
130327 + void (*release)(u32 base, unsigned int count);
130328 + int (*reserve)(u32 base, unsigned int count);
130329 + const char *acronym;
130330 +} alloc_backends[] = {
130331 + {
130332 + .id_type = usdpaa_id_fqid,
130333 + .alloc = qman_alloc_fqid_range,
130334 + .release = qman_release_fqid_range,
130335 + .reserve = qman_reserve_fqid_range,
130336 + .acronym = "FQID"
130337 + },
130338 + {
130339 + .id_type = usdpaa_id_bpid,
130340 + .alloc = bman_alloc_bpid_range,
130341 + .release = bman_release_bpid_range,
130342 + .reserve = bman_reserve_bpid_range,
130343 + .acronym = "BPID"
130344 + },
130345 + {
130346 + .id_type = usdpaa_id_qpool,
130347 + .alloc = qman_alloc_pool_range,
130348 + .release = qman_release_pool_range,
130349 + .reserve = qman_reserve_pool_range,
130350 + .acronym = "QPOOL"
130351 + },
130352 + {
130353 + .id_type = usdpaa_id_cgrid,
130354 + .alloc = qman_alloc_cgrid_range,
130355 + .release = qman_release_cgrid_range,
130356 + .acronym = "CGRID"
130357 + },
130358 + {
130359 + .id_type = usdpaa_id_ceetm0_lfqid,
130360 + .alloc = qman_alloc_ceetm0_lfqid_range,
130361 + .release = qman_release_ceetm0_lfqid_range,
130362 + .acronym = "CEETM0_LFQID"
130363 + },
130364 + {
130365 + .id_type = usdpaa_id_ceetm0_channelid,
130366 + .alloc = qman_alloc_ceetm0_channel_range,
130367 + .release = qman_release_ceetm0_channel_range,
130368 + .acronym = "CEETM0_LFQID"
130369 + },
130370 + {
130371 + .id_type = usdpaa_id_ceetm1_lfqid,
130372 + .alloc = qman_alloc_ceetm1_lfqid_range,
130373 + .release = qman_release_ceetm1_lfqid_range,
130374 + .acronym = "CEETM1_LFQID"
130375 + },
130376 + {
130377 + .id_type = usdpaa_id_ceetm1_channelid,
130378 + .alloc = qman_alloc_ceetm1_channel_range,
130379 + .release = qman_release_ceetm1_channel_range,
130380 + .acronym = "CEETM1_LFQID"
130381 + },
130382 + {
130383 + /* This terminates the array */
130384 + .id_type = usdpaa_id_max
130385 + }
130386 +};
130387 +
130388 +/* Determines the largest acceptable page size for a given size
130389 + The sizes are determined by what the TLB1 acceptable page sizes are */
130390 +static u32 largest_page_size(u32 size)
130391 +{
130392 + int shift = 30; /* Start at 1G size */
130393 + if (size < 4096)
130394 + return 0;
130395 + do {
130396 + if (size >= (1<<shift))
130397 + return 1<<shift;
130398 + shift -= 2;
130399 + } while (shift >= 12); /* Up to 4k */
130400 + return 0;
130401 +}
130402 +
130403 +/* Determine if value is power of 4 */
130404 +static inline bool is_power_of_4(u64 x)
130405 +{
130406 + if (x == 0 || ((x & (x - 1)) != 0))
130407 + return false;
130408 + return !!(x & 0x5555555555555555ull);
130409 +}
130410 +
130411 +/* Helper for ioctl_dma_map() when we have a larger fragment than we need. This
130412 + * splits the fragment into 4 and returns the upper-most. (The caller can loop
130413 + * until it has a suitable fragment size.) */
130414 +static struct mem_fragment *split_frag(struct mem_fragment *frag)
130415 +{
130416 + struct mem_fragment *x[3];
130417 +
130418 + x[0] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
130419 + x[1] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
130420 + x[2] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
130421 + if (!x[0] || !x[1] || !x[2]) {
130422 + kfree(x[0]);
130423 + kfree(x[1]);
130424 + kfree(x[2]);
130425 + return NULL;
130426 + }
130427 + BUG_ON(frag->refs);
130428 + frag->len >>= 2;
130429 + frag->pfn_len >>= 2;
130430 + x[0]->base = frag->base + frag->len;
130431 + x[1]->base = x[0]->base + frag->len;
130432 + x[2]->base = x[1]->base + frag->len;
130433 + x[0]->len = x[1]->len = x[2]->len = frag->len;
130434 + x[0]->pfn_base = frag->pfn_base + frag->pfn_len;
130435 + x[1]->pfn_base = x[0]->pfn_base + frag->pfn_len;
130436 + x[2]->pfn_base = x[1]->pfn_base + frag->pfn_len;
130437 + x[0]->pfn_len = x[1]->pfn_len = x[2]->pfn_len = frag->pfn_len;
130438 + x[0]->refs = x[1]->refs = x[2]->refs = 0;
130439 + x[0]->root_len = x[1]->root_len = x[2]->root_len = frag->root_len;
130440 + x[0]->root_pfn = x[1]->root_pfn = x[2]->root_pfn = frag->root_pfn;
130441 + x[0]->name[0] = x[1]->name[0] = x[2]->name[0] = 0;
130442 + list_add_tail(&x[0]->list, &frag->list);
130443 + list_add_tail(&x[1]->list, &x[0]->list);
130444 + list_add_tail(&x[2]->list, &x[1]->list);
130445 + return x[2];
130446 +}
130447 +
130448 +static __maybe_unused void dump_frags(void)
130449 +{
130450 + struct mem_fragment *frag;
130451 + int i = 0;
130452 + list_for_each_entry(frag, &mem_list, list) {
130453 + 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",
130454 + i, frag->base, frag->pfn_base,
130455 + frag->len, frag->root_len, frag->root_pfn,
130456 + frag->refs, frag->name);
130457 + ++i;
130458 + }
130459 +}
130460 +
130461 +/* Walk the list of fragments and adjoin neighbouring segments if possible */
130462 +static void compress_frags(void)
130463 +{
130464 + /* Walk the fragment list and combine fragments */
130465 + struct mem_fragment *frag, *nxtfrag;
130466 + u64 len = 0;
130467 +
130468 + int i, numfrags;
130469 +
130470 +
130471 + frag = list_entry(mem_list.next, struct mem_fragment, list);
130472 +
130473 + while (&frag->list != &mem_list) {
130474 + /* Must combine consecutive fragemenst with
130475 + same root_pfn such that they are power of 4 */
130476 + if (frag->refs != 0) {
130477 + frag = list_entry(frag->list.next,
130478 + struct mem_fragment, list);
130479 + continue; /* Not this window */
130480 + }
130481 + len = frag->len;
130482 + numfrags = 0;
130483 + nxtfrag = list_entry(frag->list.next,
130484 + struct mem_fragment, list);
130485 + while (true) {
130486 + if (&nxtfrag->list == &mem_list) {
130487 + numfrags = 0;
130488 + break; /* End of list */
130489 + }
130490 + if (nxtfrag->refs) {
130491 + numfrags = 0;
130492 + break; /* In use still */
130493 + }
130494 + if (nxtfrag->root_pfn != frag->root_pfn) {
130495 + numfrags = 0;
130496 + break; /* Crosses root fragment boundary */
130497 + }
130498 + len += nxtfrag->len;
130499 + numfrags++;
130500 + if (is_power_of_4(len)) {
130501 + /* These fragments can be combined */
130502 + break;
130503 + }
130504 + nxtfrag = list_entry(nxtfrag->list.next,
130505 + struct mem_fragment, list);
130506 + }
130507 + if (numfrags == 0) {
130508 + frag = list_entry(frag->list.next,
130509 + struct mem_fragment, list);
130510 + continue; /* try the next window */
130511 + }
130512 + for (i = 0; i < numfrags; i++) {
130513 + struct mem_fragment *todel =
130514 + list_entry(nxtfrag->list.prev,
130515 + struct mem_fragment, list);
130516 + nxtfrag->len += todel->len;
130517 + nxtfrag->pfn_len += todel->pfn_len;
130518 + list_del(&todel->list);
130519 + }
130520 + /* Re evaluate the list, things may merge now */
130521 + frag = list_entry(mem_list.next, struct mem_fragment, list);
130522 + }
130523 +}
130524 +
130525 +/* Hook from arch/powerpc/mm/mem.c */
130526 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size)
130527 +{
130528 + struct mem_fragment *frag;
130529 + int idx = -1;
130530 + if ((pfn < pfn_start) || (pfn >= (pfn_start + pfn_size)))
130531 + return -1;
130532 + /* It's in-range, we need to find the fragment */
130533 + spin_lock(&mem_lock);
130534 + list_for_each_entry(frag, &mem_list, list) {
130535 + if ((pfn >= frag->pfn_base) && (pfn < (frag->pfn_base +
130536 + frag->pfn_len))) {
130537 + *phys_addr = frag->base;
130538 + *size = frag->len;
130539 + idx = current_tlb++;
130540 + if (current_tlb >= (first_tlb + num_tlb))
130541 + current_tlb = first_tlb;
130542 + break;
130543 + }
130544 + }
130545 + spin_unlock(&mem_lock);
130546 + return idx;
130547 +}
130548 +
130549 +static int usdpaa_open(struct inode *inode, struct file *filp)
130550 +{
130551 + const struct alloc_backend *backend = &alloc_backends[0];
130552 + struct ctx *ctx = kmalloc(sizeof(struct ctx), GFP_KERNEL);
130553 + if (!ctx)
130554 + return -ENOMEM;
130555 + filp->private_data = ctx;
130556 +
130557 + while (backend->id_type != usdpaa_id_max) {
130558 + INIT_LIST_HEAD(&ctx->resources[backend->id_type]);
130559 + backend++;
130560 + }
130561 +
130562 + INIT_LIST_HEAD(&ctx->maps);
130563 + INIT_LIST_HEAD(&ctx->portals);
130564 + spin_lock_init(&ctx->lock);
130565 +
130566 + //filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi;
130567 +
130568 + return 0;
130569 +}
130570 +
130571 +#define DQRR_MAXFILL 15
130572 +
130573 +/* Reset a QMan portal to its default state */
130574 +static int init_qm_portal(struct qm_portal_config *config,
130575 + struct qm_portal *portal)
130576 +{
130577 + const struct qm_dqrr_entry *dqrr = NULL;
130578 + int i;
130579 +
130580 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
130581 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
130582 +
130583 + /* Make sure interrupts are inhibited */
130584 + qm_out(IIR, 1);
130585 +
130586 + /* Initialize the DQRR. This will stop any dequeue
130587 + commands that are in progress */
130588 + if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb,
130589 + qm_dqrr_cdc, DQRR_MAXFILL)) {
130590 + pr_err("qm_dqrr_init() failed when trying to"
130591 + " recover portal, portal will be leaked\n");
130592 + return 1;
130593 + }
130594 +
130595 + /* Discard any entries on the DQRR */
130596 + /* If we consume the ring twice something is wrong */
130597 + for (i = 0; i < DQRR_MAXFILL * 2; i++) {
130598 + qm_dqrr_pvb_update(portal);
130599 + dqrr = qm_dqrr_current(portal);
130600 + if (!dqrr)
130601 + break;
130602 + qm_dqrr_cdc_consume_1ptr(portal, dqrr, 0);
130603 + qm_dqrr_pvb_update(portal);
130604 + qm_dqrr_next(portal);
130605 + }
130606 + /* Initialize the EQCR */
130607 + if (qm_eqcr_init(portal, qm_eqcr_pvb,
130608 + qm_eqcr_get_ci_stashing(portal), 1)) {
130609 + pr_err("Qman EQCR initialisation failed\n");
130610 + return 1;
130611 + }
130612 + /* initialize the MR */
130613 + if (qm_mr_init(portal, qm_mr_pvb, qm_mr_cci)) {
130614 + pr_err("Qman MR initialisation failed\n");
130615 + return 1;
130616 + }
130617 + qm_mr_pvb_update(portal);
130618 + while (qm_mr_current(portal)) {
130619 + qm_mr_next(portal);
130620 + qm_mr_cci_consume_to_current(portal);
130621 + qm_mr_pvb_update(portal);
130622 + }
130623 +
130624 + if (qm_mc_init(portal)) {
130625 + pr_err("Qman MC initialisation failed\n");
130626 + return 1;
130627 + }
130628 + return 0;
130629 +}
130630 +
130631 +static int init_bm_portal(struct bm_portal_config *config,
130632 + struct bm_portal *portal)
130633 +{
130634 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
130635 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
130636 +
130637 + if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) {
130638 + pr_err("Bman RCR initialisation failed\n");
130639 + return 1;
130640 + }
130641 + if (bm_mc_init(portal)) {
130642 + pr_err("Bman MC initialisation failed\n");
130643 + return 1;
130644 + }
130645 + return 0;
130646 +}
130647 +
130648 +/* Function that will scan all FQ's in the system. For each FQ that is not
130649 + OOS it will call the check_channel helper to determine if the FQ should
130650 + be torn down. If the check_channel helper returns true the FQ will be
130651 + transitioned to the OOS state */
130652 +static int qm_check_and_destroy_fqs(struct qm_portal *portal, void *ctx,
130653 + bool (*check_channel)(void*, u32))
130654 +{
130655 + u32 fq_id = 0;
130656 + while (1) {
130657 + struct qm_mc_command *mcc;
130658 + struct qm_mc_result *mcr;
130659 + u8 state;
130660 + u32 channel;
130661 +
130662 + /* Determine the channel for the FQID */
130663 + mcc = qm_mc_start(portal);
130664 + mcc->queryfq.fqid = fq_id;
130665 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ);
130666 + while (!(mcr = qm_mc_result(portal)))
130667 + cpu_relax();
130668 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
130669 + == QM_MCR_VERB_QUERYFQ);
130670 + if (mcr->result != QM_MCR_RESULT_OK)
130671 + break; /* End of valid FQIDs */
130672 +
130673 + channel = mcr->queryfq.fqd.dest.channel;
130674 + /* Determine the state of the FQID */
130675 + mcc = qm_mc_start(portal);
130676 + mcc->queryfq_np.fqid = fq_id;
130677 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ_NP);
130678 + while (!(mcr = qm_mc_result(portal)))
130679 + cpu_relax();
130680 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
130681 + == QM_MCR_VERB_QUERYFQ_NP);
130682 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
130683 + if (state == QM_MCR_NP_STATE_OOS)
130684 + /* Already OOS, no need to do anymore checks */
130685 + goto next;
130686 +
130687 + if (check_channel(ctx, channel))
130688 + qm_shutdown_fq(&portal, 1, fq_id);
130689 + next:
130690 + ++fq_id;
130691 + }
130692 + return 0;
130693 +}
130694 +
130695 +static bool check_channel_device(void *_ctx, u32 channel)
130696 +{
130697 + struct ctx *ctx = _ctx;
130698 + struct portal_mapping *portal, *tmpportal;
130699 + struct active_resource *res;
130700 +
130701 + /* See if the FQ is destined for one of the portals we're cleaning up */
130702 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130703 + if (portal->user.type == usdpaa_portal_qman) {
130704 + if (portal->qportal->public_cfg.channel == channel) {
130705 + /* This FQs destination is a portal
130706 + we're cleaning, send a retire */
130707 + return true;
130708 + }
130709 + }
130710 + }
130711 +
130712 + /* Check the pool channels that will be released as well */
130713 + list_for_each_entry(res, &ctx->resources[usdpaa_id_qpool], list) {
130714 + if ((res->id >= channel) &&
130715 + ((res->id + res->num - 1) <= channel))
130716 + return true;
130717 + }
130718 + return false;
130719 +}
130720 +
130721 +static bool check_portal_channel(void *ctx, u32 channel)
130722 +{
130723 + u32 portal_channel = *(u32 *)ctx;
130724 + if (portal_channel == channel) {
130725 + /* This FQs destination is a portal
130726 + we're cleaning, send a retire */
130727 + return true;
130728 + }
130729 + return false;
130730 +}
130731 +
130732 +
130733 +
130734 +
130735 +static int usdpaa_release(struct inode *inode, struct file *filp)
130736 +{
130737 + struct ctx *ctx = filp->private_data;
130738 + struct mem_mapping *map, *tmpmap;
130739 + struct portal_mapping *portal, *tmpportal;
130740 + const struct alloc_backend *backend = &alloc_backends[0];
130741 + struct active_resource *res;
130742 + struct qm_portal *qm_cleanup_portal = NULL;
130743 + struct bm_portal *bm_cleanup_portal = NULL;
130744 + struct qm_portal_config *qm_alloced_portal = NULL;
130745 + struct bm_portal_config *bm_alloced_portal = NULL;
130746 +
130747 + struct qm_portal *portal_array[qman_portal_max];
130748 + int portal_count = 0;
130749 +
130750 + /* Ensure the release operation cannot be migrated to another
130751 + CPU as CPU specific variables may be needed during cleanup */
130752 +#ifdef CONFIG_PREEMPT_RT_FULL
130753 + migrate_disable();
130754 +#endif
130755 + /* The following logic is used to recover resources that were not
130756 + correctly released by the process that is closing the FD.
130757 + Step 1: syncronize the HW with the qm_portal/bm_portal structures
130758 + in the kernel
130759 + */
130760 +
130761 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130762 + /* Try to recover any portals that weren't shut down */
130763 + if (portal->user.type == usdpaa_portal_qman) {
130764 + portal_array[portal_count] = &portal->qman_portal_low;
130765 + ++portal_count;
130766 + init_qm_portal(portal->qportal,
130767 + &portal->qman_portal_low);
130768 + if (!qm_cleanup_portal) {
130769 + qm_cleanup_portal = &portal->qman_portal_low;
130770 + } else {
130771 + /* Clean FQs on the dedicated channel */
130772 + u32 chan = portal->qportal->public_cfg.channel;
130773 + qm_check_and_destroy_fqs(
130774 + &portal->qman_portal_low, &chan,
130775 + check_portal_channel);
130776 + }
130777 + } else {
130778 + /* BMAN */
130779 + init_bm_portal(portal->bportal,
130780 + &portal->bman_portal_low);
130781 + if (!bm_cleanup_portal)
130782 + bm_cleanup_portal = &portal->bman_portal_low;
130783 + }
130784 + }
130785 + /* If no portal was found, allocate one for cleanup */
130786 + if (!qm_cleanup_portal) {
130787 + qm_alloced_portal = qm_get_unused_portal();
130788 + if (!qm_alloced_portal) {
130789 + pr_crit("No QMan portal avalaible for cleanup\n");
130790 +#ifdef CONFIG_PREEMPT_RT_FULL
130791 + migrate_enable();
130792 +#endif
130793 + return -1;
130794 + }
130795 + qm_cleanup_portal = kmalloc(sizeof(struct qm_portal),
130796 + GFP_KERNEL);
130797 + if (!qm_cleanup_portal) {
130798 +#ifdef CONFIG_PREEMPT_RT_FULL
130799 + migrate_enable();
130800 +#endif
130801 + return -ENOMEM;
130802 + }
130803 + init_qm_portal(qm_alloced_portal, qm_cleanup_portal);
130804 + portal_array[portal_count] = qm_cleanup_portal;
130805 + ++portal_count;
130806 + }
130807 + if (!bm_cleanup_portal) {
130808 + bm_alloced_portal = bm_get_unused_portal();
130809 + if (!bm_alloced_portal) {
130810 + pr_crit("No BMan portal avalaible for cleanup\n");
130811 +#ifdef CONFIG_PREEMPT_RT_FULL
130812 + migrate_enable();
130813 +#endif
130814 + return -1;
130815 + }
130816 + bm_cleanup_portal = kmalloc(sizeof(struct bm_portal),
130817 + GFP_KERNEL);
130818 + if (!bm_cleanup_portal) {
130819 +#ifdef CONFIG_PREEMPT_RT_FULL
130820 + migrate_enable();
130821 +#endif
130822 + return -ENOMEM;
130823 + }
130824 + init_bm_portal(bm_alloced_portal, bm_cleanup_portal);
130825 + }
130826 +
130827 + /* OOS the FQs associated with this process */
130828 + qm_check_and_destroy_fqs(qm_cleanup_portal, ctx, check_channel_device);
130829 +
130830 + while (backend->id_type != usdpaa_id_max) {
130831 + int leaks = 0;
130832 + list_for_each_entry(res, &ctx->resources[backend->id_type],
130833 + list) {
130834 + if (backend->id_type == usdpaa_id_fqid) {
130835 + int i = 0;
130836 + for (; i < res->num; i++) {
130837 + /* Clean FQs with the cleanup portal */
130838 + qm_shutdown_fq(portal_array,
130839 + portal_count,
130840 + res->id + i);
130841 + }
130842 + }
130843 + leaks += res->num;
130844 + backend->release(res->id, res->num);
130845 + }
130846 + if (leaks)
130847 + pr_crit("USDPAA process leaking %d %s%s\n", leaks,
130848 + backend->acronym, (leaks > 1) ? "s" : "");
130849 + backend++;
130850 + }
130851 + /* Release any DMA regions */
130852 + spin_lock(&mem_lock);
130853 + list_for_each_entry_safe(map, tmpmap, &ctx->maps, list) {
130854 + struct mem_fragment *current_frag = map->root_frag;
130855 + int i;
130856 + if (map->root_frag->has_locking &&
130857 + (map->root_frag->owner == map)) {
130858 + map->root_frag->owner = NULL;
130859 + wake_up(&map->root_frag->wq);
130860 + }
130861 + /* Check each fragment and merge if the ref count is 0 */
130862 + for (i = 0; i < map->frag_count; i++) {
130863 + --current_frag->refs;
130864 + current_frag = list_entry(current_frag->list.prev,
130865 + struct mem_fragment, list);
130866 + }
130867 +
130868 + compress_frags();
130869 + list_del(&map->list);
130870 + kfree(map);
130871 + }
130872 + spin_unlock(&mem_lock);
130873 +
130874 + /* Return portals */
130875 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130876 + if (portal->user.type == usdpaa_portal_qman) {
130877 + /* Give the portal back to the allocator */
130878 + init_qm_portal(portal->qportal,
130879 + &portal->qman_portal_low);
130880 + qm_put_unused_portal(portal->qportal);
130881 + } else {
130882 + init_bm_portal(portal->bportal,
130883 + &portal->bman_portal_low);
130884 + bm_put_unused_portal(portal->bportal);
130885 + }
130886 + list_del(&portal->list);
130887 + kfree(portal);
130888 + }
130889 + if (qm_alloced_portal) {
130890 + qm_put_unused_portal(qm_alloced_portal);
130891 + kfree(qm_cleanup_portal);
130892 + }
130893 + if (bm_alloced_portal) {
130894 + bm_put_unused_portal(bm_alloced_portal);
130895 + kfree(bm_cleanup_portal);
130896 + }
130897 +
130898 + kfree(ctx);
130899 +#ifdef CONFIG_PREEMPT_RT_FULL
130900 + migrate_enable();
130901 +#endif
130902 + return 0;
130903 +}
130904 +
130905 +static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma,
130906 + int *match, unsigned long *pfn)
130907 +{
130908 + struct mem_mapping *map;
130909 +
130910 + list_for_each_entry(map, &ctx->maps, list) {
130911 + int i;
130912 + struct mem_fragment *frag = map->root_frag;
130913 +
130914 + for (i = 0; i < map->frag_count; i++) {
130915 + if (frag->pfn_base == vma->vm_pgoff) {
130916 + *match = 1;
130917 + *pfn = frag->pfn_base;
130918 + return 0;
130919 + }
130920 + frag = list_entry(frag->list.next, struct mem_fragment,
130921 + list);
130922 + }
130923 + }
130924 + *match = 0;
130925 + return 0;
130926 +}
130927 +
130928 +static int check_mmap_resource(struct resource *res, struct vm_area_struct *vma,
130929 + int *match, unsigned long *pfn)
130930 +{
130931 + *pfn = res->start >> PAGE_SHIFT;
130932 + if (*pfn == vma->vm_pgoff) {
130933 + *match = 1;
130934 + if ((vma->vm_end - vma->vm_start) != resource_size(res))
130935 + return -EINVAL;
130936 + } else
130937 + *match = 0;
130938 + return 0;
130939 +}
130940 +
130941 +static int check_mmap_portal(struct ctx *ctx, struct vm_area_struct *vma,
130942 + int *match, unsigned long *pfn)
130943 +{
130944 + struct portal_mapping *portal;
130945 + int ret;
130946 +
130947 + list_for_each_entry(portal, &ctx->portals, list) {
130948 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CE], vma,
130949 + match, pfn);
130950 + if (*match) {
130951 + vma->vm_page_prot =
130952 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
130953 + pgprot_cached_ns(vma->vm_page_prot);
130954 +#else
130955 + pgprot_cached_noncoherent(vma->vm_page_prot);
130956 +#endif
130957 + return ret;
130958 + }
130959 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CI], vma,
130960 + match, pfn);
130961 + if (*match) {
130962 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
130963 + return ret;
130964 + }
130965 + }
130966 + *match = 0;
130967 + return 0;
130968 +}
130969 +
130970 +static int usdpaa_mmap(struct file *filp, struct vm_area_struct *vma)
130971 +{
130972 + struct ctx *ctx = filp->private_data;
130973 + unsigned long pfn = 0;
130974 + int match, ret;
130975 +
130976 + spin_lock(&mem_lock);
130977 + ret = check_mmap_dma(ctx, vma, &match, &pfn);
130978 + if (!match)
130979 + ret = check_mmap_portal(ctx, vma, &match, &pfn);
130980 + spin_unlock(&mem_lock);
130981 + if (!match)
130982 + return -EINVAL;
130983 + if (!ret)
130984 + ret = remap_pfn_range(vma, vma->vm_start, pfn,
130985 + vma->vm_end - vma->vm_start,
130986 + vma->vm_page_prot);
130987 + return ret;
130988 +}
130989 +
130990 +/* Return the nearest rounded-up address >= 'addr' that is 'sz'-aligned. 'sz'
130991 + * must be a power of 2, but both 'addr' and 'sz' can be expressions. */
130992 +#define USDPAA_MEM_ROUNDUP(addr, sz) \
130993 + ({ \
130994 + unsigned long foo_align = (sz) - 1; \
130995 + ((addr) + foo_align) & ~foo_align; \
130996 + })
130997 +/* Searching for a size-aligned virtual address range starting from 'addr' */
130998 +static unsigned long usdpaa_get_unmapped_area(struct file *file,
130999 + unsigned long addr,
131000 + unsigned long len,
131001 + unsigned long pgoff,
131002 + unsigned long flags)
131003 +{
131004 + struct vm_area_struct *vma;
131005 +
131006 + if (len % PAGE_SIZE)
131007 + return -EINVAL;
131008 + if (!len)
131009 + return -EINVAL;
131010 +
131011 + /* Need to align the address to the largest pagesize of the mapping
131012 + * because the MMU requires the virtual address to have the same
131013 + * alignment as the physical address */
131014 + addr = USDPAA_MEM_ROUNDUP(addr, largest_page_size(len));
131015 + vma = find_vma(current->mm, addr);
131016 + /* Keep searching until we reach the end of currently-used virtual
131017 + * address-space or we find a big enough gap. */
131018 + while (vma) {
131019 + if ((addr + len) < vma->vm_start)
131020 + return addr;
131021 +
131022 + addr = USDPAA_MEM_ROUNDUP(vma->vm_end, largest_page_size(len));
131023 + vma = vma->vm_next;
131024 + }
131025 + if ((TASK_SIZE - len) < addr)
131026 + return -ENOMEM;
131027 + return addr;
131028 +}
131029 +
131030 +static long ioctl_id_alloc(struct ctx *ctx, void __user *arg)
131031 +{
131032 + struct usdpaa_ioctl_id_alloc i;
131033 + const struct alloc_backend *backend;
131034 + struct active_resource *res;
131035 + int ret = copy_from_user(&i, arg, sizeof(i));
131036 + if (ret)
131037 + return ret;
131038 + if ((i.id_type >= usdpaa_id_max) || !i.num)
131039 + return -EINVAL;
131040 + backend = &alloc_backends[i.id_type];
131041 + /* Allocate the required resource type */
131042 + ret = backend->alloc(&i.base, i.num, i.align, i.partial);
131043 + if (ret < 0)
131044 + return ret;
131045 + i.num = ret;
131046 + /* Copy the result to user-space */
131047 + ret = copy_to_user(arg, &i, sizeof(i));
131048 + if (ret) {
131049 + backend->release(i.base, i.num);
131050 + return ret;
131051 + }
131052 + /* Assign the allocated range to the FD accounting */
131053 + res = kmalloc(sizeof(*res), GFP_KERNEL);
131054 + if (!res) {
131055 + backend->release(i.base, i.num);
131056 + return -ENOMEM;
131057 + }
131058 + spin_lock(&ctx->lock);
131059 + res->id = i.base;
131060 + res->num = i.num;
131061 + res->refcount = 1;
131062 + list_add(&res->list, &ctx->resources[i.id_type]);
131063 + spin_unlock(&ctx->lock);
131064 + return 0;
131065 +}
131066 +
131067 +static long ioctl_id_release(struct ctx *ctx, void __user *arg)
131068 +{
131069 + struct usdpaa_ioctl_id_release i;
131070 + const struct alloc_backend *backend;
131071 + struct active_resource *tmp, *pos;
131072 +
131073 + int ret = copy_from_user(&i, arg, sizeof(i));
131074 + if (ret)
131075 + return ret;
131076 + if ((i.id_type >= usdpaa_id_max) || !i.num)
131077 + return -EINVAL;
131078 + backend = &alloc_backends[i.id_type];
131079 + /* Pull the range out of the FD accounting - the range is valid iff this
131080 + * succeeds. */
131081 + spin_lock(&ctx->lock);
131082 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
131083 + if (pos->id == i.base && pos->num == i.num) {
131084 + pos->refcount--;
131085 + if (pos->refcount) {
131086 + spin_unlock(&ctx->lock);
131087 + return 0; /* Still being used */
131088 + }
131089 + list_del(&pos->list);
131090 + kfree(pos);
131091 + spin_unlock(&ctx->lock);
131092 + goto found;
131093 + }
131094 + }
131095 + /* Failed to find the resource */
131096 + spin_unlock(&ctx->lock);
131097 + pr_err("Couldn't find resource type %d base 0x%x num %d\n",
131098 + i.id_type, i.base, i.num);
131099 + return -EINVAL;
131100 +found:
131101 + /* Release the resource to the backend */
131102 + backend->release(i.base, i.num);
131103 + return 0;
131104 +}
131105 +
131106 +static long ioctl_id_reserve(struct ctx *ctx, void __user *arg)
131107 +{
131108 + struct usdpaa_ioctl_id_reserve i;
131109 + const struct alloc_backend *backend;
131110 + struct active_resource *tmp, *pos;
131111 +
131112 + int ret = copy_from_user(&i, arg, sizeof(i));
131113 + if (ret)
131114 + return ret;
131115 + if ((i.id_type >= usdpaa_id_max) || !i.num)
131116 + return -EINVAL;
131117 + backend = &alloc_backends[i.id_type];
131118 + if (!backend->reserve)
131119 + return -EINVAL;
131120 + /* Pull the range out of the FD accounting - the range is valid iff this
131121 + * succeeds. */
131122 + spin_lock(&ctx->lock);
131123 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
131124 + if (pos->id == i.base && pos->num == i.num) {
131125 + pos->refcount++;
131126 + spin_unlock(&ctx->lock);
131127 + return 0;
131128 + }
131129 + }
131130 +
131131 + /* Failed to find the resource */
131132 + spin_unlock(&ctx->lock);
131133 +
131134 + /* Reserve the resource in the backend */
131135 + ret = backend->reserve(i.base, i.num);
131136 + if (ret)
131137 + return ret;
131138 + /* Assign the reserved range to the FD accounting */
131139 + pos = kmalloc(sizeof(*pos), GFP_KERNEL);
131140 + if (!pos) {
131141 + backend->release(i.base, i.num);
131142 + return -ENOMEM;
131143 + }
131144 + spin_lock(&ctx->lock);
131145 + pos->id = i.base;
131146 + pos->num = i.num;
131147 + pos->refcount = 1;
131148 + list_add(&pos->list, &ctx->resources[i.id_type]);
131149 + spin_unlock(&ctx->lock);
131150 + return 0;
131151 +}
131152 +
131153 +static long ioctl_dma_map(struct file *fp, struct ctx *ctx,
131154 + struct usdpaa_ioctl_dma_map *i)
131155 +{
131156 + struct mem_fragment *frag, *start_frag, *next_frag;
131157 + struct mem_mapping *map, *tmp;
131158 + int ret = 0;
131159 + u32 largest_page, so_far = 0;
131160 + int frag_count = 0;
131161 + unsigned long next_addr = PAGE_SIZE, populate;
131162 +
131163 + /* error checking to ensure values copied from user space are valid */
131164 + if (i->len % PAGE_SIZE)
131165 + return -EINVAL;
131166 +
131167 + map = kmalloc(sizeof(*map), GFP_KERNEL);
131168 + if (!map)
131169 + return -ENOMEM;
131170 +
131171 + spin_lock(&mem_lock);
131172 + if (i->flags & USDPAA_DMA_FLAG_SHARE) {
131173 + list_for_each_entry(frag, &mem_list, list) {
131174 + if (frag->refs && (frag->flags &
131175 + USDPAA_DMA_FLAG_SHARE) &&
131176 + !strncmp(i->name, frag->name,
131177 + USDPAA_DMA_NAME_MAX)) {
131178 + /* Matching entry */
131179 + if ((i->flags & USDPAA_DMA_FLAG_CREATE) &&
131180 + !(i->flags & USDPAA_DMA_FLAG_LAZY)) {
131181 + ret = -EBUSY;
131182 + goto out;
131183 + }
131184 +
131185 + /* Check to ensure size matches record */
131186 + if (i->len != frag->map_len && i->len) {
131187 + pr_err("ioctl_dma_map() Size requested does not match %s and is none zero\n",
131188 + frag->name);
131189 + return -EINVAL;
131190 + }
131191 +
131192 + /* Check if this has already been mapped
131193 + to this process */
131194 + list_for_each_entry(tmp, &ctx->maps, list)
131195 + if (tmp->root_frag == frag) {
131196 + /* Already mapped, just need to
131197 + inc ref count */
131198 + tmp->refs++;
131199 + kfree(map);
131200 + i->did_create = 0;
131201 + i->len = tmp->total_size;
131202 + i->phys_addr = frag->base;
131203 + i->ptr = tmp->virt_addr;
131204 + spin_unlock(&mem_lock);
131205 + return 0;
131206 + }
131207 + /* Matching entry - just need to map */
131208 + i->has_locking = frag->has_locking;
131209 + i->did_create = 0;
131210 + i->len = frag->map_len;
131211 + start_frag = frag;
131212 + goto do_map;
131213 + }
131214 + }
131215 + /* No matching entry */
131216 + if (!(i->flags & USDPAA_DMA_FLAG_CREATE)) {
131217 + pr_err("ioctl_dma_map() No matching entry\n");
131218 + ret = -ENOMEM;
131219 + goto out;
131220 + }
131221 + }
131222 + /* New fragment required, size must be provided. */
131223 + if (!i->len) {
131224 + ret = -EINVAL;
131225 + goto out;
131226 + }
131227 +
131228 + /* Find one of more contiguous fragments that satisfy the total length
131229 + trying to minimize the number of fragments
131230 + compute the largest page size that the allocation could use */
131231 + largest_page = largest_page_size(i->len);
131232 + start_frag = NULL;
131233 + while (largest_page &&
131234 + largest_page <= largest_page_size(phys_size) &&
131235 + start_frag == NULL) {
131236 + /* Search the list for a frag of that size */
131237 + list_for_each_entry(frag, &mem_list, list) {
131238 + if (!frag->refs && (frag->len == largest_page)) {
131239 + /* See if the next x fragments are free
131240 + and can accomidate the size */
131241 + u32 found_size = largest_page;
131242 + next_frag = list_entry(frag->list.prev,
131243 + struct mem_fragment,
131244 + list);
131245 + /* If the fragement is too small check
131246 + if the neighbours cab support it */
131247 + while (found_size < i->len) {
131248 + if (&mem_list == &next_frag->list)
131249 + break; /* End of list */
131250 + if (next_frag->refs != 0 ||
131251 + next_frag->len == 0)
131252 + break; /* not enough space */
131253 + found_size += next_frag->len;
131254 + next_frag = list_entry(
131255 + next_frag->list.prev,
131256 + struct mem_fragment,
131257 + list);
131258 + }
131259 + if (found_size >= i->len) {
131260 + /* Success! there is enough contigous
131261 + free space */
131262 + start_frag = frag;
131263 + break;
131264 + }
131265 + }
131266 + } /* next frag loop */
131267 + /* Couldn't statisfy the request with this
131268 + largest page size, try a smaller one */
131269 + largest_page <<= 2;
131270 + }
131271 + if (start_frag == NULL) {
131272 + /* Couldn't find proper amount of space */
131273 + ret = -ENOMEM;
131274 + goto out;
131275 + }
131276 + i->did_create = 1;
131277 +do_map:
131278 + /* Verify there is sufficient space to do the mapping */
131279 + down_write(&current->mm->mmap_sem);
131280 + next_addr = usdpaa_get_unmapped_area(fp, next_addr, i->len, 0, 0);
131281 + up_write(&current->mm->mmap_sem);
131282 +
131283 + if (next_addr & ~PAGE_MASK) {
131284 + ret = -ENOMEM;
131285 + goto out;
131286 + }
131287 +
131288 + /* We may need to divide the final fragment to accomidate the mapping */
131289 + next_frag = start_frag;
131290 + while (so_far != i->len) {
131291 + BUG_ON(next_frag->len == 0);
131292 + while ((next_frag->len + so_far) > i->len) {
131293 + /* Split frag until they match */
131294 + split_frag(next_frag);
131295 + }
131296 + so_far += next_frag->len;
131297 + next_frag->refs++;
131298 + ++frag_count;
131299 + next_frag = list_entry(next_frag->list.prev,
131300 + struct mem_fragment, list);
131301 + }
131302 + if (i->did_create) {
131303 + size_t name_len = 0;
131304 + start_frag->flags = i->flags;
131305 + strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX);
131306 + name_len = strnlen(start_frag->name, USDPAA_DMA_NAME_MAX);
131307 + if (name_len >= USDPAA_DMA_NAME_MAX) {
131308 + ret = -EFAULT;
131309 + goto out;
131310 + }
131311 + start_frag->map_len = i->len;
131312 + start_frag->has_locking = i->has_locking;
131313 + init_waitqueue_head(&start_frag->wq);
131314 + start_frag->owner = NULL;
131315 + }
131316 +
131317 + /* Setup the map entry */
131318 + map->root_frag = start_frag;
131319 + map->total_size = i->len;
131320 + map->frag_count = frag_count;
131321 + map->refs = 1;
131322 + list_add(&map->list, &ctx->maps);
131323 + i->phys_addr = start_frag->base;
131324 +out:
131325 + spin_unlock(&mem_lock);
131326 +
131327 + if (!ret) {
131328 + unsigned long longret;
131329 + down_write(&current->mm->mmap_sem);
131330 + longret = do_mmap_pgoff(fp, next_addr, map->total_size,
131331 + PROT_READ |
131332 + (i->flags &
131333 + USDPAA_DMA_FLAG_RDONLY ? 0
131334 + : PROT_WRITE),
131335 + MAP_SHARED,
131336 + start_frag->pfn_base,
131337 + &populate);
131338 + up_write(&current->mm->mmap_sem);
131339 + if (longret & ~PAGE_MASK) {
131340 + ret = (int)longret;
131341 + } else {
131342 + i->ptr = (void *)longret;
131343 + map->virt_addr = i->ptr;
131344 + }
131345 + } else
131346 + kfree(map);
131347 + return ret;
131348 +}
131349 +
131350 +static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg)
131351 +{
131352 + struct mem_mapping *map;
131353 + struct vm_area_struct *vma;
131354 + int ret, i;
131355 + struct mem_fragment *current_frag;
131356 + size_t sz;
131357 + unsigned long base;
131358 + unsigned long vaddr;
131359 +
131360 + down_write(&current->mm->mmap_sem);
131361 + vma = find_vma(current->mm, (unsigned long)arg);
131362 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
131363 + up_write(&current->mm->mmap_sem);
131364 + return -EFAULT;
131365 + }
131366 + spin_lock(&mem_lock);
131367 + list_for_each_entry(map, &ctx->maps, list) {
131368 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
131369 + /* Drop the map lock if we hold it */
131370 + if (map->root_frag->has_locking &&
131371 + (map->root_frag->owner == map)) {
131372 + map->root_frag->owner = NULL;
131373 + wake_up(&map->root_frag->wq);
131374 + }
131375 + goto map_match;
131376 + }
131377 + }
131378 + /* Failed to find a matching mapping for this process */
131379 + ret = -EFAULT;
131380 + spin_unlock(&mem_lock);
131381 + goto out;
131382 +map_match:
131383 + map->refs--;
131384 + if (map->refs != 0) {
131385 + /* Another call the dma_map is referencing this */
131386 + ret = 0;
131387 + spin_unlock(&mem_lock);
131388 + goto out;
131389 + }
131390 +
131391 + current_frag = map->root_frag;
131392 + vaddr = (unsigned long) map->virt_addr;
131393 + for (i = 0; i < map->frag_count; i++) {
131394 + DPA_ASSERT(current_frag->refs > 0);
131395 + --current_frag->refs;
131396 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
131397 + /*
131398 + * Make sure we invalidate the TLB entry for
131399 + * this fragment, otherwise a remap of a different
131400 + * page to this vaddr would give acces to an
131401 + * incorrect piece of memory
131402 + */
131403 + cleartlbcam(vaddr, mfspr(SPRN_PID));
131404 +#endif
131405 + vaddr += current_frag->len;
131406 + current_frag = list_entry(current_frag->list.prev,
131407 + struct mem_fragment, list);
131408 + }
131409 + map->root_frag->name[0] = 0;
131410 + list_del(&map->list);
131411 + compress_frags();
131412 + spin_unlock(&mem_lock);
131413 +
131414 + base = vma->vm_start;
131415 + sz = vma->vm_end - vma->vm_start;
131416 + do_munmap(current->mm, base, sz);
131417 + ret = 0;
131418 + out:
131419 + up_write(&current->mm->mmap_sem);
131420 + return ret;
131421 +}
131422 +
131423 +static long ioctl_dma_stats(struct ctx *ctx, void __user *arg)
131424 +{
131425 + struct mem_fragment *frag;
131426 + struct usdpaa_ioctl_dma_used result;
131427 +
131428 + result.free_bytes = 0;
131429 + result.total_bytes = phys_size;
131430 +
131431 + list_for_each_entry(frag, &mem_list, list) {
131432 + if (frag->refs == 0)
131433 + result.free_bytes += frag->len;
131434 + }
131435 +
131436 + return copy_to_user(arg, &result, sizeof(result)); }
131437 +
131438 +static int test_lock(struct mem_mapping *map)
131439 +{
131440 + int ret = 0;
131441 + spin_lock(&mem_lock);
131442 + if (!map->root_frag->owner) {
131443 + map->root_frag->owner = map;
131444 + ret = 1;
131445 + }
131446 + spin_unlock(&mem_lock);
131447 + return ret;
131448 +}
131449 +
131450 +static long ioctl_dma_lock(struct ctx *ctx, void __user *arg)
131451 +{
131452 + struct mem_mapping *map;
131453 + struct vm_area_struct *vma;
131454 +
131455 + down_read(&current->mm->mmap_sem);
131456 + vma = find_vma(current->mm, (unsigned long)arg);
131457 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
131458 + up_read(&current->mm->mmap_sem);
131459 + return -EFAULT;
131460 + }
131461 + spin_lock(&mem_lock);
131462 + list_for_each_entry(map, &ctx->maps, list) {
131463 + if (map->root_frag->pfn_base == vma->vm_pgoff)
131464 + goto map_match;
131465 + }
131466 + map = NULL;
131467 +map_match:
131468 + spin_unlock(&mem_lock);
131469 + up_read(&current->mm->mmap_sem);
131470 +
131471 + if (!map)
131472 + return -EFAULT;
131473 + if (!map->root_frag->has_locking)
131474 + return -ENODEV;
131475 + return wait_event_interruptible(map->root_frag->wq, test_lock(map));
131476 +}
131477 +
131478 +static long ioctl_dma_unlock(struct ctx *ctx, void __user *arg)
131479 +{
131480 + struct mem_mapping *map;
131481 + struct vm_area_struct *vma;
131482 + int ret;
131483 +
131484 + down_read(&current->mm->mmap_sem);
131485 + vma = find_vma(current->mm, (unsigned long)arg);
131486 + if (!vma || (vma->vm_start > (unsigned long)arg))
131487 + ret = -EFAULT;
131488 + else {
131489 + spin_lock(&mem_lock);
131490 + list_for_each_entry(map, &ctx->maps, list) {
131491 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
131492 + if (!map->root_frag->has_locking)
131493 + ret = -ENODEV;
131494 + else if (map->root_frag->owner == map) {
131495 + map->root_frag->owner = NULL;
131496 + wake_up(&map->root_frag->wq);
131497 + ret = 0;
131498 + } else
131499 + ret = -EBUSY;
131500 + goto map_match;
131501 + }
131502 + }
131503 + ret = -EINVAL;
131504 +map_match:
131505 + spin_unlock(&mem_lock);
131506 + }
131507 + up_read(&current->mm->mmap_sem);
131508 + return ret;
131509 +}
131510 +
131511 +static int portal_mmap(struct file *fp, struct resource *res, void **ptr)
131512 +{
131513 + unsigned long longret = 0, populate;
131514 + resource_size_t len;
131515 +
131516 + down_write(&current->mm->mmap_sem);
131517 + len = resource_size(res);
131518 + if (len != (unsigned long)len)
131519 + return -EINVAL;
131520 + longret = do_mmap_pgoff(fp, PAGE_SIZE, (unsigned long)len,
131521 + PROT_READ | PROT_WRITE, MAP_SHARED,
131522 + res->start >> PAGE_SHIFT, &populate);
131523 + up_write(&current->mm->mmap_sem);
131524 +
131525 + if (longret & ~PAGE_MASK)
131526 + return (int)longret;
131527 +
131528 + *ptr = (void *) longret;
131529 + return 0;
131530 +}
131531 +
131532 +static void portal_munmap(struct resource *res, void *ptr)
131533 +{
131534 + down_write(&current->mm->mmap_sem);
131535 + do_munmap(current->mm, (unsigned long)ptr, resource_size(res));
131536 + up_write(&current->mm->mmap_sem);
131537 +}
131538 +
131539 +static long ioctl_portal_map(struct file *fp, struct ctx *ctx,
131540 + struct usdpaa_ioctl_portal_map *arg)
131541 +{
131542 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
131543 + int ret;
131544 +
131545 + if (!mapping)
131546 + return -ENOMEM;
131547 +
131548 + mapping->user = *arg;
131549 + mapping->iommu_domain = NULL;
131550 +
131551 + if (mapping->user.type == usdpaa_portal_qman) {
131552 + mapping->qportal =
131553 + qm_get_unused_portal_idx(mapping->user.index);
131554 + if (!mapping->qportal) {
131555 + ret = -ENODEV;
131556 + goto err_get_portal;
131557 + }
131558 + mapping->phys = &mapping->qportal->addr_phys[0];
131559 + mapping->user.channel = mapping->qportal->public_cfg.channel;
131560 + mapping->user.pools = mapping->qportal->public_cfg.pools;
131561 + mapping->user.index = mapping->qportal->public_cfg.index;
131562 + } else if (mapping->user.type == usdpaa_portal_bman) {
131563 + mapping->bportal =
131564 + bm_get_unused_portal_idx(mapping->user.index);
131565 + if (!mapping->bportal) {
131566 + ret = -ENODEV;
131567 + goto err_get_portal;
131568 + }
131569 + mapping->phys = &mapping->bportal->addr_phys[0];
131570 + mapping->user.index = mapping->bportal->public_cfg.index;
131571 + } else {
131572 + ret = -EINVAL;
131573 + goto err_copy_from_user;
131574 + }
131575 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
131576 + * handlers look it up. */
131577 + spin_lock(&mem_lock);
131578 + list_add(&mapping->list, &ctx->portals);
131579 + spin_unlock(&mem_lock);
131580 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CE],
131581 + &mapping->user.addr.cena);
131582 + if (ret)
131583 + goto err_mmap_cena;
131584 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CI],
131585 + &mapping->user.addr.cinh);
131586 + if (ret)
131587 + goto err_mmap_cinh;
131588 + *arg = mapping->user;
131589 + return ret;
131590 +
131591 +err_mmap_cinh:
131592 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
131593 +err_mmap_cena:
131594 + if ((mapping->user.type == usdpaa_portal_qman) && mapping->qportal)
131595 + qm_put_unused_portal(mapping->qportal);
131596 + else if ((mapping->user.type == usdpaa_portal_bman) && mapping->bportal)
131597 + bm_put_unused_portal(mapping->bportal);
131598 + spin_lock(&mem_lock);
131599 + list_del(&mapping->list);
131600 + spin_unlock(&mem_lock);
131601 +err_get_portal:
131602 +err_copy_from_user:
131603 + kfree(mapping);
131604 + return ret;
131605 +}
131606 +
131607 +static long ioctl_portal_unmap(struct ctx *ctx, struct usdpaa_portal_map *i)
131608 +{
131609 + struct portal_mapping *mapping;
131610 + struct vm_area_struct *vma;
131611 + unsigned long pfn;
131612 + u32 channel;
131613 +
131614 + /* Get the PFN corresponding to one of the virt addresses */
131615 + down_read(&current->mm->mmap_sem);
131616 + vma = find_vma(current->mm, (unsigned long)i->cinh);
131617 + if (!vma || (vma->vm_start > (unsigned long)i->cinh)) {
131618 + up_read(&current->mm->mmap_sem);
131619 + return -EFAULT;
131620 + }
131621 + pfn = vma->vm_pgoff;
131622 + up_read(&current->mm->mmap_sem);
131623 +
131624 + /* Find the corresponding portal */
131625 + spin_lock(&mem_lock);
131626 + list_for_each_entry(mapping, &ctx->portals, list) {
131627 + if (pfn == (mapping->phys[DPA_PORTAL_CI].start >> PAGE_SHIFT))
131628 + goto found;
131629 + }
131630 + mapping = NULL;
131631 +found:
131632 + if (mapping)
131633 + list_del(&mapping->list);
131634 + spin_unlock(&mem_lock);
131635 + if (!mapping)
131636 + return -ENODEV;
131637 + portal_munmap(&mapping->phys[DPA_PORTAL_CI], mapping->user.addr.cinh);
131638 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
131639 + if (mapping->user.type == usdpaa_portal_qman) {
131640 + init_qm_portal(mapping->qportal,
131641 + &mapping->qman_portal_low);
131642 +
131643 + /* Tear down any FQs this portal is referencing */
131644 + channel = mapping->qportal->public_cfg.channel;
131645 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
131646 + &channel,
131647 + check_portal_channel);
131648 + qm_put_unused_portal(mapping->qportal);
131649 + } else if (mapping->user.type == usdpaa_portal_bman) {
131650 + init_bm_portal(mapping->bportal,
131651 + &mapping->bman_portal_low);
131652 + bm_put_unused_portal(mapping->bportal);
131653 + }
131654 + kfree(mapping);
131655 + return 0;
131656 +}
131657 +
131658 +static void portal_config_pamu(struct qm_portal_config *pcfg, uint8_t sdest,
131659 + uint32_t cpu, uint32_t cache, uint32_t window)
131660 +{
131661 +#ifdef CONFIG_FSL_PAMU
131662 + int ret;
131663 + int window_count = 1;
131664 + struct iommu_domain_geometry geom_attr;
131665 + struct pamu_stash_attribute stash_attr;
131666 +
131667 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
131668 + if (!pcfg->iommu_domain) {
131669 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
131670 + __func__);
131671 + goto _no_iommu;
131672 + }
131673 + geom_attr.aperture_start = 0;
131674 + geom_attr.aperture_end =
131675 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
131676 + geom_attr.force_aperture = true;
131677 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
131678 + &geom_attr);
131679 + if (ret < 0) {
131680 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131681 + __func__, ret);
131682 + goto _iommu_domain_free;
131683 + }
131684 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
131685 + &window_count);
131686 + if (ret < 0) {
131687 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131688 + __func__, ret);
131689 + goto _iommu_domain_free;
131690 + }
131691 + stash_attr.cpu = cpu;
131692 + stash_attr.cache = cache;
131693 + /* set stash information for the window */
131694 + stash_attr.window = 0;
131695 +
131696 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
131697 + DOMAIN_ATTR_FSL_PAMU_STASH,
131698 + &stash_attr);
131699 + if (ret < 0) {
131700 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131701 + __func__, ret);
131702 + goto _iommu_domain_free;
131703 + }
131704 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
131705 + IOMMU_READ | IOMMU_WRITE);
131706 + if (ret < 0) {
131707 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
131708 + __func__, ret);
131709 + goto _iommu_domain_free;
131710 + }
131711 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
131712 + if (ret < 0) {
131713 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
131714 + __func__, ret);
131715 + goto _iommu_domain_free;
131716 + }
131717 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
131718 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
131719 + &window_count);
131720 + if (ret < 0) {
131721 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131722 + __func__, ret);
131723 + goto _iommu_detach_device;
131724 + }
131725 +_no_iommu:
131726 +#endif
131727 +
131728 +#ifdef CONFIG_FSL_QMAN_CONFIG
131729 + if (qman_set_sdest(pcfg->public_cfg.channel, sdest))
131730 +#endif
131731 + pr_warn("Failed to set QMan portal's stash request queue\n");
131732 +
131733 + return;
131734 +
131735 +#ifdef CONFIG_FSL_PAMU
131736 +_iommu_detach_device:
131737 + iommu_detach_device(pcfg->iommu_domain, NULL);
131738 +_iommu_domain_free:
131739 + iommu_domain_free(pcfg->iommu_domain);
131740 +#endif
131741 +}
131742 +
131743 +static long ioctl_allocate_raw_portal(struct file *fp, struct ctx *ctx,
131744 + struct usdpaa_ioctl_raw_portal *arg)
131745 +{
131746 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
131747 + int ret;
131748 +
131749 + if (!mapping)
131750 + return -ENOMEM;
131751 +
131752 + mapping->user.type = arg->type;
131753 + mapping->iommu_domain = NULL;
131754 + if (arg->type == usdpaa_portal_qman) {
131755 + mapping->qportal = qm_get_unused_portal_idx(arg->index);
131756 + if (!mapping->qportal) {
131757 + ret = -ENODEV;
131758 + goto err;
131759 + }
131760 + mapping->phys = &mapping->qportal->addr_phys[0];
131761 + arg->index = mapping->qportal->public_cfg.index;
131762 + arg->cinh = mapping->qportal->addr_phys[DPA_PORTAL_CI].start;
131763 + arg->cena = mapping->qportal->addr_phys[DPA_PORTAL_CE].start;
131764 + if (arg->enable_stash) {
131765 + /* Setup the PAMU with the supplied parameters */
131766 + portal_config_pamu(mapping->qportal, arg->sdest,
131767 + arg->cpu, arg->cache, arg->window);
131768 + }
131769 + } else if (mapping->user.type == usdpaa_portal_bman) {
131770 + mapping->bportal =
131771 + bm_get_unused_portal_idx(arg->index);
131772 + if (!mapping->bportal) {
131773 + ret = -ENODEV;
131774 + goto err;
131775 + }
131776 + mapping->phys = &mapping->bportal->addr_phys[0];
131777 + arg->index = mapping->bportal->public_cfg.index;
131778 + arg->cinh = mapping->bportal->addr_phys[DPA_PORTAL_CI].start;
131779 + arg->cena = mapping->bportal->addr_phys[DPA_PORTAL_CE].start;
131780 + } else {
131781 + ret = -EINVAL;
131782 + goto err;
131783 + }
131784 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
131785 + * handlers look it up. */
131786 + spin_lock(&mem_lock);
131787 + list_add(&mapping->list, &ctx->portals);
131788 + spin_unlock(&mem_lock);
131789 + return 0;
131790 +err:
131791 + kfree(mapping);
131792 + return ret;
131793 +}
131794 +
131795 +static long ioctl_free_raw_portal(struct file *fp, struct ctx *ctx,
131796 + struct usdpaa_ioctl_raw_portal *arg)
131797 +{
131798 + struct portal_mapping *mapping;
131799 + u32 channel;
131800 +
131801 + /* Find the corresponding portal */
131802 + spin_lock(&mem_lock);
131803 + list_for_each_entry(mapping, &ctx->portals, list) {
131804 + if (mapping->phys[DPA_PORTAL_CI].start == arg->cinh)
131805 + goto found;
131806 + }
131807 + mapping = NULL;
131808 +found:
131809 + if (mapping)
131810 + list_del(&mapping->list);
131811 + spin_unlock(&mem_lock);
131812 + if (!mapping)
131813 + return -ENODEV;
131814 + if (mapping->user.type == usdpaa_portal_qman) {
131815 + init_qm_portal(mapping->qportal,
131816 + &mapping->qman_portal_low);
131817 +
131818 + /* Tear down any FQs this portal is referencing */
131819 + channel = mapping->qportal->public_cfg.channel;
131820 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
131821 + &channel,
131822 + check_portal_channel);
131823 + qm_put_unused_portal(mapping->qportal);
131824 + } else if (mapping->user.type == usdpaa_portal_bman) {
131825 + init_bm_portal(mapping->bportal,
131826 + &mapping->bman_portal_low);
131827 + bm_put_unused_portal(mapping->bportal);
131828 + }
131829 + kfree(mapping);
131830 + return 0;
131831 +}
131832 +
131833 +static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
131834 +{
131835 + struct ctx *ctx = fp->private_data;
131836 + void __user *a = (void __user *)arg;
131837 + switch (cmd) {
131838 + case USDPAA_IOCTL_ID_ALLOC:
131839 + return ioctl_id_alloc(ctx, a);
131840 + case USDPAA_IOCTL_ID_RELEASE:
131841 + return ioctl_id_release(ctx, a);
131842 + case USDPAA_IOCTL_ID_RESERVE:
131843 + return ioctl_id_reserve(ctx, a);
131844 + case USDPAA_IOCTL_DMA_MAP:
131845 + {
131846 + struct usdpaa_ioctl_dma_map input;
131847 + int ret;
131848 + if (copy_from_user(&input, a, sizeof(input)))
131849 + return -EFAULT;
131850 + ret = ioctl_dma_map(fp, ctx, &input);
131851 + if (copy_to_user(a, &input, sizeof(input)))
131852 + return -EFAULT;
131853 + return ret;
131854 + }
131855 + case USDPAA_IOCTL_DMA_UNMAP:
131856 + return ioctl_dma_unmap(ctx, a);
131857 + case USDPAA_IOCTL_DMA_LOCK:
131858 + return ioctl_dma_lock(ctx, a);
131859 + case USDPAA_IOCTL_DMA_UNLOCK:
131860 + return ioctl_dma_unlock(ctx, a);
131861 + case USDPAA_IOCTL_PORTAL_MAP:
131862 + {
131863 + struct usdpaa_ioctl_portal_map input;
131864 + int ret;
131865 + if (copy_from_user(&input, a, sizeof(input)))
131866 + return -EFAULT;
131867 + ret = ioctl_portal_map(fp, ctx, &input);
131868 + if (copy_to_user(a, &input, sizeof(input)))
131869 + return -EFAULT;
131870 + return ret;
131871 + }
131872 + case USDPAA_IOCTL_PORTAL_UNMAP:
131873 + {
131874 + struct usdpaa_portal_map input;
131875 + if (copy_from_user(&input, a, sizeof(input)))
131876 + return -EFAULT;
131877 + return ioctl_portal_unmap(ctx, &input);
131878 + }
131879 + case USDPAA_IOCTL_DMA_USED:
131880 + return ioctl_dma_stats(ctx, a);
131881 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL:
131882 + {
131883 + struct usdpaa_ioctl_raw_portal input;
131884 + int ret;
131885 + if (copy_from_user(&input, a, sizeof(input)))
131886 + return -EFAULT;
131887 + ret = ioctl_allocate_raw_portal(fp, ctx, &input);
131888 + if (copy_to_user(a, &input, sizeof(input)))
131889 + return -EFAULT;
131890 + return ret;
131891 + }
131892 + case USDPAA_IOCTL_FREE_RAW_PORTAL:
131893 + {
131894 + struct usdpaa_ioctl_raw_portal input;
131895 + if (copy_from_user(&input, a, sizeof(input)))
131896 + return -EFAULT;
131897 + return ioctl_free_raw_portal(fp, ctx, &input);
131898 + }
131899 + }
131900 + return -EINVAL;
131901 +}
131902 +
131903 +static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd,
131904 + unsigned long arg)
131905 +{
131906 +#ifdef CONFIG_COMPAT
131907 + struct ctx *ctx = fp->private_data;
131908 + void __user *a = (void __user *)arg;
131909 +#endif
131910 + switch (cmd) {
131911 +#ifdef CONFIG_COMPAT
131912 + case USDPAA_IOCTL_DMA_MAP_COMPAT:
131913 + {
131914 + int ret;
131915 + struct usdpaa_ioctl_dma_map_compat input;
131916 + struct usdpaa_ioctl_dma_map converted;
131917 +
131918 + if (copy_from_user(&input, a, sizeof(input)))
131919 + return -EFAULT;
131920 +
131921 + converted.ptr = compat_ptr(input.ptr);
131922 + converted.phys_addr = input.phys_addr;
131923 + converted.len = input.len;
131924 + converted.flags = input.flags;
131925 + strncpy(converted.name, input.name, USDPAA_DMA_NAME_MAX);
131926 + converted.has_locking = input.has_locking;
131927 + converted.did_create = input.did_create;
131928 +
131929 + ret = ioctl_dma_map(fp, ctx, &converted);
131930 + input.ptr = ptr_to_compat(converted.ptr);
131931 + input.phys_addr = converted.phys_addr;
131932 + input.len = converted.len;
131933 + input.flags = converted.flags;
131934 + strncpy(input.name, converted.name, USDPAA_DMA_NAME_MAX);
131935 + input.has_locking = converted.has_locking;
131936 + input.did_create = converted.did_create;
131937 + if (copy_to_user(a, &input, sizeof(input)))
131938 + return -EFAULT;
131939 + return ret;
131940 + }
131941 + case USDPAA_IOCTL_PORTAL_MAP_COMPAT:
131942 + {
131943 + int ret;
131944 + struct compat_usdpaa_ioctl_portal_map input;
131945 + struct usdpaa_ioctl_portal_map converted;
131946 + if (copy_from_user(&input, a, sizeof(input)))
131947 + return -EFAULT;
131948 + converted.type = input.type;
131949 + converted.index = input.index;
131950 + ret = ioctl_portal_map(fp, ctx, &converted);
131951 + input.addr.cinh = ptr_to_compat(converted.addr.cinh);
131952 + input.addr.cena = ptr_to_compat(converted.addr.cena);
131953 + input.channel = converted.channel;
131954 + input.pools = converted.pools;
131955 + input.index = converted.index;
131956 + if (copy_to_user(a, &input, sizeof(input)))
131957 + return -EFAULT;
131958 + return ret;
131959 + }
131960 + case USDPAA_IOCTL_PORTAL_UNMAP_COMPAT:
131961 + {
131962 + struct usdpaa_portal_map_compat input;
131963 + struct usdpaa_portal_map converted;
131964 +
131965 + if (copy_from_user(&input, a, sizeof(input)))
131966 + return -EFAULT;
131967 + converted.cinh = compat_ptr(input.cinh);
131968 + converted.cena = compat_ptr(input.cena);
131969 + return ioctl_portal_unmap(ctx, &converted);
131970 + }
131971 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT:
131972 + {
131973 + int ret;
131974 + struct usdpaa_ioctl_raw_portal converted;
131975 + struct compat_ioctl_raw_portal input;
131976 + if (copy_from_user(&input, a, sizeof(input)))
131977 + return -EFAULT;
131978 + converted.type = input.type;
131979 + converted.index = input.index;
131980 + converted.enable_stash = input.enable_stash;
131981 + converted.cpu = input.cpu;
131982 + converted.cache = input.cache;
131983 + converted.window = input.window;
131984 + converted.sdest = input.sdest;
131985 + ret = ioctl_allocate_raw_portal(fp, ctx, &converted);
131986 +
131987 + input.cinh = converted.cinh;
131988 + input.cena = converted.cena;
131989 + input.index = converted.index;
131990 +
131991 + if (copy_to_user(a, &input, sizeof(input)))
131992 + return -EFAULT;
131993 + return ret;
131994 + }
131995 + case USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT:
131996 + {
131997 + struct usdpaa_ioctl_raw_portal converted;
131998 + struct compat_ioctl_raw_portal input;
131999 + if (copy_from_user(&input, a, sizeof(input)))
132000 + return -EFAULT;
132001 + converted.type = input.type;
132002 + converted.index = input.index;
132003 + converted.cinh = input.cinh;
132004 + converted.cena = input.cena;
132005 + return ioctl_free_raw_portal(fp, ctx, &converted);
132006 + }
132007 +#endif
132008 + default:
132009 + return usdpaa_ioctl(fp, cmd, arg);
132010 + }
132011 + return -EINVAL;
132012 +}
132013 +
132014 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
132015 + enum usdpaa_portal_type ptype, unsigned int *irq,
132016 + void **iir_reg)
132017 +{
132018 + /* Walk the list of portals for filp and return the config
132019 + for the portal that matches the hint */
132020 + struct ctx *context;
132021 + struct portal_mapping *portal;
132022 +
132023 + /* First sanitize the filp */
132024 + if (filp->f_op->open != usdpaa_open)
132025 + return -ENODEV;
132026 + context = filp->private_data;
132027 + spin_lock(&context->lock);
132028 + list_for_each_entry(portal, &context->portals, list) {
132029 + if (portal->user.type == ptype &&
132030 + portal->user.addr.cinh == cinh) {
132031 + if (ptype == usdpaa_portal_qman) {
132032 + *irq = portal->qportal->public_cfg.irq;
132033 + *iir_reg = portal->qportal->addr_virt[1] +
132034 + QM_REG_IIR;
132035 + } else {
132036 + *irq = portal->bportal->public_cfg.irq;
132037 + *iir_reg = portal->bportal->addr_virt[1] +
132038 + BM_REG_IIR;
132039 + }
132040 + spin_unlock(&context->lock);
132041 + return 0;
132042 + }
132043 + }
132044 + spin_unlock(&context->lock);
132045 + return -EINVAL;
132046 +}
132047 +
132048 +static const struct file_operations usdpaa_fops = {
132049 + .open = usdpaa_open,
132050 + .release = usdpaa_release,
132051 + .mmap = usdpaa_mmap,
132052 + .get_unmapped_area = usdpaa_get_unmapped_area,
132053 + .unlocked_ioctl = usdpaa_ioctl,
132054 + .compat_ioctl = usdpaa_ioctl_compat
132055 +};
132056 +
132057 +static struct miscdevice usdpaa_miscdev = {
132058 + .name = "fsl-usdpaa",
132059 + .fops = &usdpaa_fops,
132060 + .minor = MISC_DYNAMIC_MINOR,
132061 +};
132062 +
132063 +/* Early-boot memory allocation. The boot-arg "usdpaa_mem=<x>" is used to
132064 + * indicate how much memory (if any) to allocate during early boot. If the
132065 + * format "usdpaa_mem=<x>,<y>" is used, then <y> will be interpreted as the
132066 + * number of TLB1 entries to reserve (default is 1). If there are more mappings
132067 + * than there are TLB1 entries, fault-handling will occur. */
132068 +
132069 +static __init int usdpaa_mem(char *arg)
132070 +{
132071 + pr_warn("uspdaa_mem argument is depracated\n");
132072 + arg_phys_size = memparse(arg, &arg);
132073 + num_tlb = 1;
132074 + if (*arg == ',') {
132075 + unsigned long ul;
132076 + int err = kstrtoul(arg + 1, 0, &ul);
132077 + if (err < 0) {
132078 + num_tlb = 1;
132079 + pr_warn("ERROR, usdpaa_mem arg is invalid\n");
132080 + } else
132081 + num_tlb = (unsigned int)ul;
132082 + }
132083 + return 0;
132084 +}
132085 +early_param("usdpaa_mem", usdpaa_mem);
132086 +
132087 +static int usdpaa_mem_init(struct reserved_mem *rmem)
132088 +{
132089 + phys_start = rmem->base;
132090 + phys_size = rmem->size;
132091 +
132092 + WARN_ON(!(phys_start && phys_size));
132093 +
132094 + return 0;
132095 +}
132096 +RESERVEDMEM_OF_DECLARE(usdpaa_mem_init, "fsl,usdpaa-mem", usdpaa_mem_init);
132097 +
132098 +__init int fsl_usdpaa_init_early(void)
132099 +{
132100 + if (!phys_size || !phys_start) {
132101 + pr_info("No USDPAA memory, no 'fsl,usdpaa-mem' in device-tree\n");
132102 + return 0;
132103 + }
132104 + if (phys_size % PAGE_SIZE) {
132105 + pr_err("'fsl,usdpaa-mem' size must be a multiple of page size\n");
132106 + phys_size = 0;
132107 + return 0;
132108 + }
132109 + if (arg_phys_size && phys_size != arg_phys_size) {
132110 + pr_err("'usdpaa_mem argument size (0x%llx) does not match device tree size (0x%llx)\n",
132111 + arg_phys_size, phys_size);
132112 + phys_size = 0;
132113 + return 0;
132114 + }
132115 + pfn_start = phys_start >> PAGE_SHIFT;
132116 + pfn_size = phys_size >> PAGE_SHIFT;
132117 +#ifdef CONFIG_PPC
132118 + first_tlb = current_tlb = tlbcam_index;
132119 + tlbcam_index += num_tlb;
132120 +#endif
132121 + pr_info("USDPAA region at %llx:%llx(%lx:%lx), %d TLB1 entries)\n",
132122 + phys_start, phys_size, pfn_start, pfn_size, num_tlb);
132123 + return 0;
132124 +}
132125 +subsys_initcall(fsl_usdpaa_init_early);
132126 +
132127 +
132128 +static int __init usdpaa_init(void)
132129 +{
132130 + struct mem_fragment *frag;
132131 + int ret;
132132 + u64 tmp_size = phys_size;
132133 + u64 tmp_start = phys_start;
132134 + u64 tmp_pfn_size = pfn_size;
132135 + u64 tmp_pfn_start = pfn_start;
132136 +
132137 + pr_info("Freescale USDPAA process driver\n");
132138 + if (!phys_start) {
132139 + pr_warn("fsl-usdpaa: no region found\n");
132140 + return 0;
132141 + }
132142 +
132143 + while (tmp_size != 0) {
132144 + u32 frag_size = largest_page_size(tmp_size);
132145 + frag = kmalloc(sizeof(*frag), GFP_KERNEL);
132146 + if (!frag) {
132147 + pr_err("Failed to setup USDPAA memory accounting\n");
132148 + return -ENOMEM;
132149 + }
132150 + frag->base = tmp_start;
132151 + frag->len = frag->root_len = frag_size;
132152 + frag->root_pfn = tmp_pfn_start;
132153 + frag->pfn_base = tmp_pfn_start;
132154 + frag->pfn_len = frag_size / PAGE_SIZE;
132155 + frag->refs = 0;
132156 + init_waitqueue_head(&frag->wq);
132157 + frag->owner = NULL;
132158 + list_add(&frag->list, &mem_list);
132159 +
132160 + /* Adjust for this frag */
132161 + tmp_start += frag_size;
132162 + tmp_size -= frag_size;
132163 + tmp_pfn_start += frag_size / PAGE_SIZE;
132164 + tmp_pfn_size -= frag_size / PAGE_SIZE;
132165 + }
132166 + ret = misc_register(&usdpaa_miscdev);
132167 + if (ret)
132168 + pr_err("fsl-usdpaa: failed to register misc device\n");
132169 + return ret;
132170 +}
132171 +
132172 +static void __exit usdpaa_exit(void)
132173 +{
132174 + misc_deregister(&usdpaa_miscdev);
132175 +}
132176 +
132177 +module_init(usdpaa_init);
132178 +module_exit(usdpaa_exit);
132179 +
132180 +MODULE_LICENSE("GPL");
132181 +MODULE_AUTHOR("Freescale Semiconductor");
132182 +MODULE_DESCRIPTION("Freescale USDPAA process driver");
132183 diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
132184 new file mode 100644
132185 index 00000000..914c7471
132186 --- /dev/null
132187 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
132188 @@ -0,0 +1,289 @@
132189 +/* Copyright (c) 2013 Freescale Semiconductor, Inc.
132190 + * All rights reserved.
132191 + *
132192 + * Redistribution and use in source and binary forms, with or without
132193 + * modification, are permitted provided that the following conditions are met:
132194 + * * Redistributions of source code must retain the above copyright
132195 + * notice, this list of conditions and the following disclaimer.
132196 + * * Redistributions in binary form must reproduce the above copyright
132197 + * notice, this list of conditions and the following disclaimer in the
132198 + * documentation and/or other materials provided with the distribution.
132199 + * * Neither the name of Freescale Semiconductor nor the
132200 + * names of its contributors may be used to endorse or promote products
132201 + * derived from this software without specific prior written permission.
132202 + *
132203 + *
132204 + * ALTERNATIVELY, this software may be distributed under the terms of the
132205 + * GNU General Public License ("GPL") as published by the Free Software
132206 + * Foundation, either version 2 of that License or (at your option) any
132207 + * later version.
132208 + *
132209 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
132210 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
132211 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
132212 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
132213 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
132214 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
132215 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
132216 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
132217 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
132218 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
132219 + */
132220 +
132221 +/* define a device that allows USPDAA processes to open a file
132222 + descriptor and specify which IRQ it wants to montior using an ioctl()
132223 + When an IRQ is received, the device becomes readable so that a process
132224 + can use read() or select() type calls to monitor for IRQs */
132225 +
132226 +#include <linux/miscdevice.h>
132227 +#include <linux/fs.h>
132228 +#include <linux/cdev.h>
132229 +#include <linux/slab.h>
132230 +#include <linux/interrupt.h>
132231 +#include <linux/poll.h>
132232 +#include <linux/uaccess.h>
132233 +#include <linux/fsl_usdpaa.h>
132234 +#include <linux/module.h>
132235 +#include <linux/fdtable.h>
132236 +#include <linux/file.h>
132237 +
132238 +#include "qman_low.h"
132239 +#include "bman_low.h"
132240 +
132241 +struct usdpaa_irq_ctx {
132242 + int irq_set; /* Set to true once the irq is set via ioctl */
132243 + unsigned int irq_num;
132244 + u32 last_irq_count; /* Last value returned from read */
132245 + u32 irq_count; /* Number of irqs since last read */
132246 + wait_queue_head_t wait_queue; /* Waiting processes */
132247 + spinlock_t lock;
132248 + void *inhibit_addr; /* inhibit register address */
132249 + struct file *usdpaa_filp;
132250 + char irq_name[128];
132251 +};
132252 +
132253 +static int usdpaa_irq_open(struct inode *inode, struct file *filp)
132254 +{
132255 + struct usdpaa_irq_ctx *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
132256 + if (!ctx)
132257 + return -ENOMEM;
132258 + ctx->irq_set = 0;
132259 + ctx->irq_count = 0;
132260 + ctx->last_irq_count = 0;
132261 + init_waitqueue_head(&ctx->wait_queue);
132262 + spin_lock_init(&ctx->lock);
132263 + filp->private_data = ctx;
132264 + return 0;
132265 +}
132266 +
132267 +static int usdpaa_irq_release(struct inode *inode, struct file *filp)
132268 +{
132269 + struct usdpaa_irq_ctx *ctx = filp->private_data;
132270 + if (ctx->irq_set) {
132271 + /* Inhibit the IRQ */
132272 + out_be32(ctx->inhibit_addr, 0x1);
132273 + irq_set_affinity_hint(ctx->irq_num, NULL);
132274 + free_irq(ctx->irq_num, ctx);
132275 + ctx->irq_set = 0;
132276 + fput(ctx->usdpaa_filp);
132277 + }
132278 + kfree(filp->private_data);
132279 + return 0;
132280 +}
132281 +
132282 +static irqreturn_t usdpaa_irq_handler(int irq, void *_ctx)
132283 +{
132284 + unsigned long flags;
132285 + struct usdpaa_irq_ctx *ctx = _ctx;
132286 + spin_lock_irqsave(&ctx->lock, flags);
132287 + ++ctx->irq_count;
132288 + spin_unlock_irqrestore(&ctx->lock, flags);
132289 + wake_up_all(&ctx->wait_queue);
132290 + /* Set the inhibit register. This will be reenabled
132291 + once the USDPAA code handles the IRQ */
132292 + out_be32(ctx->inhibit_addr, 0x1);
132293 + pr_info("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count);
132294 + return IRQ_HANDLED;
132295 +}
132296 +
132297 +static int map_irq(struct file *fp, struct usdpaa_ioctl_irq_map *irq_map)
132298 +{
132299 + struct usdpaa_irq_ctx *ctx = fp->private_data;
132300 + int ret;
132301 +
132302 + if (ctx->irq_set) {
132303 + pr_debug("Setting USDPAA IRQ when it was already set!\n");
132304 + return -EBUSY;
132305 + }
132306 +
132307 + ctx->usdpaa_filp = fget(irq_map->fd);
132308 + if (!ctx->usdpaa_filp) {
132309 + pr_debug("USDPAA fget(%d) returned NULL\n", irq_map->fd);
132310 + return -EINVAL;
132311 + }
132312 +
132313 + ret = usdpaa_get_portal_config(ctx->usdpaa_filp, irq_map->portal_cinh,
132314 + irq_map->type, &ctx->irq_num,
132315 + &ctx->inhibit_addr);
132316 + if (ret) {
132317 + pr_debug("USDPAA IRQ couldn't identify portal\n");
132318 + fput(ctx->usdpaa_filp);
132319 + return ret;
132320 + }
132321 +
132322 + ctx->irq_set = 1;
132323 +
132324 + snprintf(ctx->irq_name, sizeof(ctx->irq_name),
132325 + "usdpaa_irq %d", ctx->irq_num);
132326 +
132327 + ret = request_irq(ctx->irq_num, usdpaa_irq_handler, 0,
132328 + ctx->irq_name, ctx);
132329 + if (ret) {
132330 + pr_err("USDPAA request_irq(%d) failed, ret= %d\n",
132331 + ctx->irq_num, ret);
132332 + ctx->irq_set = 0;
132333 + fput(ctx->usdpaa_filp);
132334 + return ret;
132335 + }
132336 + ret = irq_set_affinity(ctx->irq_num, &current->cpus_allowed);
132337 + if (ret)
132338 + pr_err("USDPAA irq_set_affinity() failed, ret= %d\n", ret);
132339 +
132340 + ret = irq_set_affinity_hint(ctx->irq_num, &current->cpus_allowed);
132341 + if (ret)
132342 + pr_err("USDPAA irq_set_affinity_hint() failed, ret= %d\n", ret);
132343 +
132344 + return 0;
132345 +}
132346 +
132347 +static long usdpaa_irq_ioctl(struct file *fp, unsigned int cmd,
132348 + unsigned long arg)
132349 +{
132350 + int ret;
132351 + struct usdpaa_ioctl_irq_map irq_map;
132352 +
132353 + if (cmd != USDPAA_IOCTL_PORTAL_IRQ_MAP) {
132354 + pr_debug("USDPAA IRQ unknown command 0x%x\n", cmd);
132355 + return -EINVAL;
132356 + }
132357 +
132358 + ret = copy_from_user(&irq_map, (void __user *)arg,
132359 + sizeof(irq_map));
132360 + if (ret)
132361 + return ret;
132362 + return map_irq(fp, &irq_map);
132363 +}
132364 +
132365 +static ssize_t usdpaa_irq_read(struct file *filp, char __user *buff,
132366 + size_t count, loff_t *offp)
132367 +{
132368 + struct usdpaa_irq_ctx *ctx = filp->private_data;
132369 + int ret;
132370 +
132371 + if (!ctx->irq_set) {
132372 + pr_debug("Reading USDPAA IRQ before it was set\n");
132373 + return -EINVAL;
132374 + }
132375 +
132376 + if (count < sizeof(ctx->irq_count)) {
132377 + pr_debug("USDPAA IRQ Read too small\n");
132378 + return -EINVAL;
132379 + }
132380 + if (ctx->irq_count == ctx->last_irq_count) {
132381 + if (filp->f_flags & O_NONBLOCK)
132382 + return -EAGAIN;
132383 +
132384 + ret = wait_event_interruptible(ctx->wait_queue,
132385 + ctx->irq_count != ctx->last_irq_count);
132386 + if (ret == -ERESTARTSYS)
132387 + return ret;
132388 + }
132389 +
132390 + ctx->last_irq_count = ctx->irq_count;
132391 +
132392 + if (copy_to_user(buff, &ctx->last_irq_count,
132393 + sizeof(ctx->last_irq_count)))
132394 + return -EFAULT;
132395 + return sizeof(ctx->irq_count);
132396 +}
132397 +
132398 +static unsigned int usdpaa_irq_poll(struct file *filp, poll_table *wait)
132399 +{
132400 + struct usdpaa_irq_ctx *ctx = filp->private_data;
132401 + unsigned int ret = 0;
132402 + unsigned long flags;
132403 +
132404 + if (!ctx->irq_set)
132405 + return POLLHUP;
132406 +
132407 + poll_wait(filp, &ctx->wait_queue, wait);
132408 +
132409 + spin_lock_irqsave(&ctx->lock, flags);
132410 + if (ctx->irq_count != ctx->last_irq_count)
132411 + ret |= POLLIN | POLLRDNORM;
132412 + spin_unlock_irqrestore(&ctx->lock, flags);
132413 + return ret;
132414 +}
132415 +
132416 +static long usdpaa_irq_ioctl_compat(struct file *fp, unsigned int cmd,
132417 + unsigned long arg)
132418 +{
132419 +#ifdef CONFIG_COMPAT
132420 + void __user *a = (void __user *)arg;
132421 +#endif
132422 + switch (cmd) {
132423 +#ifdef CONFIG_COMPAT
132424 + case USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT:
132425 + {
132426 + struct compat_ioctl_irq_map input;
132427 + struct usdpaa_ioctl_irq_map converted;
132428 + if (copy_from_user(&input, a, sizeof(input)))
132429 + return -EFAULT;
132430 + converted.type = input.type;
132431 + converted.fd = input.fd;
132432 + converted.portal_cinh = compat_ptr(input.portal_cinh);
132433 + return map_irq(fp, &converted);
132434 + }
132435 +#endif
132436 + default:
132437 + return usdpaa_irq_ioctl(fp, cmd, arg);
132438 + }
132439 +}
132440 +
132441 +static const struct file_operations usdpaa_irq_fops = {
132442 + .open = usdpaa_irq_open,
132443 + .release = usdpaa_irq_release,
132444 + .unlocked_ioctl = usdpaa_irq_ioctl,
132445 + .compat_ioctl = usdpaa_irq_ioctl_compat,
132446 + .read = usdpaa_irq_read,
132447 + .poll = usdpaa_irq_poll
132448 +};
132449 +
132450 +static struct miscdevice usdpaa_miscdev = {
132451 + .name = "fsl-usdpaa-irq",
132452 + .fops = &usdpaa_irq_fops,
132453 + .minor = MISC_DYNAMIC_MINOR,
132454 +};
132455 +
132456 +static int __init usdpaa_irq_init(void)
132457 +{
132458 + int ret;
132459 +
132460 + pr_info("Freescale USDPAA process IRQ driver\n");
132461 + ret = misc_register(&usdpaa_miscdev);
132462 + if (ret)
132463 + pr_err("fsl-usdpaa-irq: failed to register misc device\n");
132464 + return ret;
132465 +}
132466 +
132467 +static void __exit usdpaa_irq_exit(void)
132468 +{
132469 + misc_deregister(&usdpaa_miscdev);
132470 +}
132471 +
132472 +module_init(usdpaa_irq_init);
132473 +module_exit(usdpaa_irq_exit);
132474 +
132475 +MODULE_LICENSE("GPL");
132476 +MODULE_AUTHOR("Freescale Semiconductor");
132477 +MODULE_DESCRIPTION("Freescale USDPAA process IRQ driver");
132478 diff --git a/drivers/staging/fsl_qbman/qbman_driver.c b/drivers/staging/fsl_qbman/qbman_driver.c
132479 new file mode 100644
132480 index 00000000..ab487d5f
132481 --- /dev/null
132482 +++ b/drivers/staging/fsl_qbman/qbman_driver.c
132483 @@ -0,0 +1,88 @@
132484 +/* Copyright 2013 Freescale Semiconductor, Inc.
132485 + *
132486 + * Redistribution and use in source and binary forms, with or without
132487 + * modification, are permitted provided that the following conditions are met:
132488 + * * Redistributions of source code must retain the above copyright
132489 + * notice, this list of conditions and the following disclaimer.
132490 + * * Redistributions in binary form must reproduce the above copyright
132491 + * notice, this list of conditions and the following disclaimer in the
132492 + * documentation and/or other materials provided with the distribution.
132493 + * * Neither the name of Freescale Semiconductor nor the
132494 + * names of its contributors may be used to endorse or promote products
132495 + * derived from this software without specific prior written permission.
132496 + *
132497 + *
132498 + * ALTERNATIVELY, this software may be distributed under the terms of the
132499 + * GNU General Public License ("GPL") as published by the Free Software
132500 + * Foundation, either version 2 of that License or (at your option) any
132501 + * later version.
132502 + *
132503 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
132504 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
132505 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
132506 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
132507 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
132508 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
132509 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
132510 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
132511 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
132512 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
132513 + */
132514 +
132515 +#include <linux/time.h>
132516 +#include "qman_private.h"
132517 +#include "bman_private.h"
132518 +__init void qman_init_early(void);
132519 +__init void bman_init_early(void);
132520 +
132521 +static __init int qbman_init(void)
132522 +{
132523 + struct device_node *dn;
132524 + u32 is_portal_available;
132525 +
132526 + bman_init();
132527 + qman_init();
132528 +
132529 + is_portal_available = 0;
132530 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
132531 + if (!of_device_is_available(dn))
132532 + continue;
132533 + else
132534 + is_portal_available = 1;
132535 + }
132536 +
132537 + if (!qman_have_ccsr() && is_portal_available) {
132538 + struct qman_fq fq = {
132539 + .fqid = 1
132540 + };
132541 + struct qm_mcr_queryfq_np np;
132542 + int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT;
132543 + struct timespec nowts, diffts, startts = current_kernel_time();
132544 + /* Loop while querying given fqid succeeds or time out */
132545 + while (1) {
132546 + err = qman_query_fq_np(&fq, &np);
132547 + if (!err) {
132548 + /* success, control-plane has configured QMan */
132549 + break;
132550 + } else if (err != -ERANGE) {
132551 + pr_err("QMan: I/O error, continuing anyway\n");
132552 + break;
132553 + }
132554 + nowts = current_kernel_time();
132555 + diffts = timespec_sub(nowts, startts);
132556 + if (diffts.tv_sec > 0) {
132557 + if (!retry--) {
132558 + pr_err("QMan: time out, control-plane"
132559 + " dead?\n");
132560 + break;
132561 + }
132562 + pr_warn("QMan: polling for the control-plane"
132563 + " (%d)\n", retry);
132564 + }
132565 + }
132566 + }
132567 + bman_resource_init();
132568 + qman_resource_init();
132569 + return 0;
132570 +}
132571 +subsys_initcall(qbman_init);
132572 diff --git a/drivers/staging/fsl_qbman/qman_config.c b/drivers/staging/fsl_qbman/qman_config.c
132573 new file mode 100644
132574 index 00000000..9bb1e11a
132575 --- /dev/null
132576 +++ b/drivers/staging/fsl_qbman/qman_config.c
132577 @@ -0,0 +1,1224 @@
132578 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
132579 + *
132580 + * Redistribution and use in source and binary forms, with or without
132581 + * modification, are permitted provided that the following conditions are met:
132582 + * * Redistributions of source code must retain the above copyright
132583 + * notice, this list of conditions and the following disclaimer.
132584 + * * Redistributions in binary form must reproduce the above copyright
132585 + * notice, this list of conditions and the following disclaimer in the
132586 + * documentation and/or other materials provided with the distribution.
132587 + * * Neither the name of Freescale Semiconductor nor the
132588 + * names of its contributors may be used to endorse or promote products
132589 + * derived from this software without specific prior written permission.
132590 + *
132591 + *
132592 + * ALTERNATIVELY, this software may be distributed under the terms of the
132593 + * GNU General Public License ("GPL") as published by the Free Software
132594 + * Foundation, either version 2 of that License or (at your option) any
132595 + * later version.
132596 + *
132597 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
132598 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
132599 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
132600 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
132601 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
132602 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
132603 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
132604 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
132605 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
132606 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
132607 + */
132608 +
132609 +#include <asm/cacheflush.h>
132610 +#include "qman_private.h"
132611 +#include <linux/highmem.h>
132612 +#include <linux/of_reserved_mem.h>
132613 +
132614 +/* Last updated for v00.800 of the BG */
132615 +
132616 +/* Register offsets */
132617 +#define REG_QCSP_LIO_CFG(n) (0x0000 + ((n) * 0x10))
132618 +#define REG_QCSP_IO_CFG(n) (0x0004 + ((n) * 0x10))
132619 +#define REG_QCSP_DD_CFG(n) (0x000c + ((n) * 0x10))
132620 +#define REG_DD_CFG 0x0200
132621 +#define REG_DCP_CFG(n) (0x0300 + ((n) * 0x10))
132622 +#define REG_DCP_DD_CFG(n) (0x0304 + ((n) * 0x10))
132623 +#define REG_DCP_DLM_AVG(n) (0x030c + ((n) * 0x10))
132624 +#define REG_PFDR_FPC 0x0400
132625 +#define REG_PFDR_FP_HEAD 0x0404
132626 +#define REG_PFDR_FP_TAIL 0x0408
132627 +#define REG_PFDR_FP_LWIT 0x0410
132628 +#define REG_PFDR_CFG 0x0414
132629 +#define REG_SFDR_CFG 0x0500
132630 +#define REG_SFDR_IN_USE 0x0504
132631 +#define REG_WQ_CS_CFG(n) (0x0600 + ((n) * 0x04))
132632 +#define REG_WQ_DEF_ENC_WQID 0x0630
132633 +#define REG_WQ_SC_DD_CFG(n) (0x640 + ((n) * 0x04))
132634 +#define REG_WQ_PC_DD_CFG(n) (0x680 + ((n) * 0x04))
132635 +#define REG_WQ_DC0_DD_CFG(n) (0x6c0 + ((n) * 0x04))
132636 +#define REG_WQ_DC1_DD_CFG(n) (0x700 + ((n) * 0x04))
132637 +#define REG_WQ_DCn_DD_CFG(n) (0x6c0 + ((n) * 0x40)) /* n=2,3 */
132638 +#define REG_CM_CFG 0x0800
132639 +#define REG_ECSR 0x0a00
132640 +#define REG_ECIR 0x0a04
132641 +#define REG_EADR 0x0a08
132642 +#define REG_ECIR2 0x0a0c
132643 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
132644 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
132645 +#define REG_MCR 0x0b00
132646 +#define REG_MCP(n) (0x0b04 + ((n) * 0x04))
132647 +#define REG_MISC_CFG 0x0be0
132648 +#define REG_HID_CFG 0x0bf0
132649 +#define REG_IDLE_STAT 0x0bf4
132650 +#define REG_IP_REV_1 0x0bf8
132651 +#define REG_IP_REV_2 0x0bfc
132652 +#define REG_FQD_BARE 0x0c00
132653 +#define REG_PFDR_BARE 0x0c20
132654 +#define REG_offset_BAR 0x0004 /* relative to REG_[FQD|PFDR]_BARE */
132655 +#define REG_offset_AR 0x0010 /* relative to REG_[FQD|PFDR]_BARE */
132656 +#define REG_QCSP_BARE 0x0c80
132657 +#define REG_QCSP_BAR 0x0c84
132658 +#define REG_CI_SCHED_CFG 0x0d00
132659 +#define REG_SRCIDR 0x0d04
132660 +#define REG_LIODNR 0x0d08
132661 +#define REG_CI_RLM_AVG 0x0d14
132662 +#define REG_ERR_ISR 0x0e00 /* + "enum qm_isr_reg" */
132663 +#define REG_REV3_QCSP_LIO_CFG(n) (0x1000 + ((n) * 0x10))
132664 +#define REG_REV3_QCSP_IO_CFG(n) (0x1004 + ((n) * 0x10))
132665 +#define REG_REV3_QCSP_DD_CFG(n) (0x100c + ((n) * 0x10))
132666 +#define REG_CEETM_CFG_IDX 0x900
132667 +#define REG_CEETM_CFG_PRES 0x904
132668 +#define REG_CEETM_XSFDR_IN_USE 0x908
132669 +
132670 +/* Assists for QMAN_MCR */
132671 +#define MCR_INIT_PFDR 0x01000000
132672 +#define MCR_get_rslt(v) (u8)((v) >> 24)
132673 +#define MCR_rslt_idle(r) (!rslt || (rslt >= 0xf0))
132674 +#define MCR_rslt_ok(r) (rslt == 0xf0)
132675 +#define MCR_rslt_eaccess(r) (rslt == 0xf8)
132676 +#define MCR_rslt_inval(r) (rslt == 0xff)
132677 +
132678 +struct qman;
132679 +
132680 +/* Follows WQ_CS_CFG0-5 */
132681 +enum qm_wq_class {
132682 + qm_wq_portal = 0,
132683 + qm_wq_pool = 1,
132684 + qm_wq_fman0 = 2,
132685 + qm_wq_fman1 = 3,
132686 + qm_wq_caam = 4,
132687 + qm_wq_pme = 5,
132688 + qm_wq_first = qm_wq_portal,
132689 + qm_wq_last = qm_wq_pme
132690 +};
132691 +
132692 +/* Follows FQD_[BARE|BAR|AR] and PFDR_[BARE|BAR|AR] */
132693 +enum qm_memory {
132694 + qm_memory_fqd,
132695 + qm_memory_pfdr
132696 +};
132697 +
132698 +/* Used by all error interrupt registers except 'inhibit' */
132699 +#define QM_EIRQ_CIDE 0x20000000 /* Corenet Initiator Data Error */
132700 +#define QM_EIRQ_CTDE 0x10000000 /* Corenet Target Data Error */
132701 +#define QM_EIRQ_CITT 0x08000000 /* Corenet Invalid Target Transaction */
132702 +#define QM_EIRQ_PLWI 0x04000000 /* PFDR Low Watermark */
132703 +#define QM_EIRQ_MBEI 0x02000000 /* Multi-bit ECC Error */
132704 +#define QM_EIRQ_SBEI 0x01000000 /* Single-bit ECC Error */
132705 +#define QM_EIRQ_PEBI 0x00800000 /* PFDR Enqueues Blocked Interrupt */
132706 +#define QM_EIRQ_IFSI 0x00020000 /* Invalid FQ Flow Control State */
132707 +#define QM_EIRQ_ICVI 0x00010000 /* Invalid Command Verb */
132708 +#define QM_EIRQ_IDDI 0x00000800 /* Invalid Dequeue (Direct-connect) */
132709 +#define QM_EIRQ_IDFI 0x00000400 /* Invalid Dequeue FQ */
132710 +#define QM_EIRQ_IDSI 0x00000200 /* Invalid Dequeue Source */
132711 +#define QM_EIRQ_IDQI 0x00000100 /* Invalid Dequeue Queue */
132712 +#define QM_EIRQ_IECE 0x00000010 /* Invalid Enqueue Configuration */
132713 +#define QM_EIRQ_IEOI 0x00000008 /* Invalid Enqueue Overflow */
132714 +#define QM_EIRQ_IESI 0x00000004 /* Invalid Enqueue State */
132715 +#define QM_EIRQ_IECI 0x00000002 /* Invalid Enqueue Channel */
132716 +#define QM_EIRQ_IEQI 0x00000001 /* Invalid Enqueue Queue */
132717 +
132718 +/* QMAN_ECIR valid error bit */
132719 +#define PORTAL_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IESI | QM_EIRQ_IEOI | \
132720 + QM_EIRQ_IDQI | QM_EIRQ_IDSI | QM_EIRQ_IDFI | \
132721 + QM_EIRQ_IDDI | QM_EIRQ_ICVI | QM_EIRQ_IFSI)
132722 +#define FQID_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IECI | QM_EIRQ_IESI | \
132723 + QM_EIRQ_IEOI | QM_EIRQ_IDQI | QM_EIRQ_IDFI | \
132724 + QM_EIRQ_IFSI)
132725 +
132726 +union qman_ecir {
132727 + u32 ecir_raw;
132728 + struct {
132729 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132730 + u32 __reserved:2;
132731 + u32 portal_type:1;
132732 + u32 portal_num:5;
132733 + u32 fqid:24;
132734 +#else
132735 + u32 fqid:24;
132736 + u32 portal_num:5;
132737 + u32 portal_type:1;
132738 + u32 __reserved:2;
132739 +#endif
132740 + } __packed info;
132741 +};
132742 +
132743 +union qman_ecir2 {
132744 + u32 ecir2_raw;
132745 + struct {
132746 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132747 + u32 portal_type:1;
132748 + u32 __reserved:21;
132749 + u32 portal_num:10;
132750 +#else
132751 + u32 portal_num:10;
132752 + u32 __reserved:21;
132753 + u32 portal_type:1;
132754 +#endif
132755 + } __packed info;
132756 +};
132757 +
132758 +union qman_eadr {
132759 + u32 eadr_raw;
132760 + struct {
132761 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132762 + u32 __reserved1:4;
132763 + u32 memid:4;
132764 + u32 __reserved2:12;
132765 + u32 eadr:12;
132766 +#else
132767 + u32 eadr:12;
132768 + u32 __reserved2:12;
132769 + u32 memid:4;
132770 + u32 __reserved1:4;
132771 +#endif
132772 + } __packed info;
132773 + struct {
132774 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132775 + u32 __reserved1:3;
132776 + u32 memid:5;
132777 + u32 __reserved:8;
132778 + u32 eadr:16;
132779 +#else
132780 + u32 eadr:16;
132781 + u32 __reserved:8;
132782 + u32 memid:5;
132783 + u32 __reserved1:3;
132784 +#endif
132785 + } __packed info_rev3;
132786 +};
132787 +
132788 +struct qman_hwerr_txt {
132789 + u32 mask;
132790 + const char *txt;
132791 +};
132792 +
132793 +#define QMAN_HWE_TXT(a, b) { .mask = QM_EIRQ_##a, .txt = b }
132794 +
132795 +static const struct qman_hwerr_txt qman_hwerr_txts[] = {
132796 + QMAN_HWE_TXT(CIDE, "Corenet Initiator Data Error"),
132797 + QMAN_HWE_TXT(CTDE, "Corenet Target Data Error"),
132798 + QMAN_HWE_TXT(CITT, "Corenet Invalid Target Transaction"),
132799 + QMAN_HWE_TXT(PLWI, "PFDR Low Watermark"),
132800 + QMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
132801 + QMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
132802 + QMAN_HWE_TXT(PEBI, "PFDR Enqueues Blocked Interrupt"),
132803 + QMAN_HWE_TXT(ICVI, "Invalid Command Verb"),
132804 + QMAN_HWE_TXT(IFSI, "Invalid Flow Control State"),
132805 + QMAN_HWE_TXT(IDDI, "Invalid Dequeue (Direct-connect)"),
132806 + QMAN_HWE_TXT(IDFI, "Invalid Dequeue FQ"),
132807 + QMAN_HWE_TXT(IDSI, "Invalid Dequeue Source"),
132808 + QMAN_HWE_TXT(IDQI, "Invalid Dequeue Queue"),
132809 + QMAN_HWE_TXT(IECE, "Invalid Enqueue Configuration"),
132810 + QMAN_HWE_TXT(IEOI, "Invalid Enqueue Overflow"),
132811 + QMAN_HWE_TXT(IESI, "Invalid Enqueue State"),
132812 + QMAN_HWE_TXT(IECI, "Invalid Enqueue Channel"),
132813 + QMAN_HWE_TXT(IEQI, "Invalid Enqueue Queue")
132814 +};
132815 +#define QMAN_HWE_COUNT (sizeof(qman_hwerr_txts)/sizeof(struct qman_hwerr_txt))
132816 +
132817 +struct qman_error_info_mdata {
132818 + u16 addr_mask;
132819 + u16 bits;
132820 + const char *txt;
132821 +};
132822 +
132823 +#define QMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
132824 +static const struct qman_error_info_mdata error_mdata[] = {
132825 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 0"),
132826 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 1"),
132827 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 2"),
132828 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 3"),
132829 + QMAN_ERR_MDATA(0x0FFF, 512, "FQD cache memory"),
132830 + QMAN_ERR_MDATA(0x07FF, 128, "SFDR memory"),
132831 + QMAN_ERR_MDATA(0x01FF, 72, "WQ context memory"),
132832 + QMAN_ERR_MDATA(0x00FF, 240, "CGR memory"),
132833 + QMAN_ERR_MDATA(0x00FF, 302, "Internal Order Restoration List memory"),
132834 + QMAN_ERR_MDATA(0x01FF, 256, "SW portal ring memory"),
132835 + QMAN_ERR_MDATA(0x07FF, 181, "CEETM class queue descriptor memory"),
132836 + QMAN_ERR_MDATA(0x0FFF, 140, "CEETM extended SFDR memory"),
132837 + QMAN_ERR_MDATA(0x0FFF, 25, "CEETM logical FQ mapping memory"),
132838 + QMAN_ERR_MDATA(0x0FFF, 96, "CEETM dequeue context memory"),
132839 + QMAN_ERR_MDATA(0x07FF, 396, "CEETM ccgr memory"),
132840 + QMAN_ERR_MDATA(0x00FF, 146, "CEETM CQ channel shaping memory"),
132841 + QMAN_ERR_MDATA(0x007F, 256, "CEETM CQ channel scheduling memory"),
132842 + QMAN_ERR_MDATA(0x01FF, 88, "CEETM dequeue statistics memory"),
132843 +};
132844 +#define QMAN_ERR_MDATA_COUNT \
132845 + (sizeof(error_mdata)/sizeof(struct qman_error_info_mdata))
132846 +
132847 +/* Add this in Kconfig */
132848 +#define QMAN_ERRS_TO_UNENABLE (QM_EIRQ_PLWI | QM_EIRQ_PEBI)
132849 +
132850 +/**
132851 + * qm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
132852 + * @v: for accessors that write values, this is the 32-bit value
132853 + *
132854 + * Manipulates QMAN_ERR_ISR, QMAN_ERR_IER, QMAN_ERR_ISDR, QMAN_ERR_IIR. All
132855 + * manipulations except qm_err_isr_[un]inhibit() use 32-bit masks composed of
132856 + * the QM_EIRQ_*** definitions. Note that "qm_err_isr_enable_write" means
132857 + * "write the enable register" rather than "enable the write register"!
132858 + */
132859 +#define qm_err_isr_status_read(qm) \
132860 + __qm_err_isr_read(qm, qm_isr_status)
132861 +#define qm_err_isr_status_clear(qm, m) \
132862 + __qm_err_isr_write(qm, qm_isr_status, m)
132863 +#define qm_err_isr_enable_read(qm) \
132864 + __qm_err_isr_read(qm, qm_isr_enable)
132865 +#define qm_err_isr_enable_write(qm, v) \
132866 + __qm_err_isr_write(qm, qm_isr_enable, v)
132867 +#define qm_err_isr_disable_read(qm) \
132868 + __qm_err_isr_read(qm, qm_isr_disable)
132869 +#define qm_err_isr_disable_write(qm, v) \
132870 + __qm_err_isr_write(qm, qm_isr_disable, v)
132871 +#define qm_err_isr_inhibit(qm) \
132872 + __qm_err_isr_write(qm, qm_isr_inhibit, 1)
132873 +#define qm_err_isr_uninhibit(qm) \
132874 + __qm_err_isr_write(qm, qm_isr_inhibit, 0)
132875 +
132876 +/*
132877 + * TODO: unimplemented registers
132878 + *
132879 + * Keeping a list here of Qman registers I have not yet covered;
132880 + * QCSP_DD_IHRSR, QCSP_DD_IHRFR, QCSP_DD_HASR,
132881 + * DCP_DD_IHRSR, DCP_DD_IHRFR, DCP_DD_HASR, CM_CFG,
132882 + * QMAN_EECC, QMAN_SBET, QMAN_EINJ, QMAN_SBEC0-12
132883 + */
132884 +
132885 +/* Encapsulate "struct qman *" as a cast of the register space address. */
132886 +
132887 +static struct qman *qm_create(void *regs)
132888 +{
132889 + return (struct qman *)regs;
132890 +}
132891 +
132892 +static inline u32 __qm_in(struct qman *qm, u32 offset)
132893 +{
132894 + return in_be32((void *)qm + offset);
132895 +}
132896 +static inline void __qm_out(struct qman *qm, u32 offset, u32 val)
132897 +{
132898 + out_be32((void *)qm + offset, val);
132899 +}
132900 +#define qm_in(reg) __qm_in(qm, REG_##reg)
132901 +#define qm_out(reg, val) __qm_out(qm, REG_##reg, val)
132902 +
132903 +static u32 __qm_err_isr_read(struct qman *qm, enum qm_isr_reg n)
132904 +{
132905 + return __qm_in(qm, REG_ERR_ISR + (n << 2));
132906 +}
132907 +
132908 +static void __qm_err_isr_write(struct qman *qm, enum qm_isr_reg n, u32 val)
132909 +{
132910 + __qm_out(qm, REG_ERR_ISR + (n << 2), val);
132911 +}
132912 +
132913 +static void qm_set_dc(struct qman *qm, enum qm_dc_portal portal,
132914 + int ed, u8 sernd)
132915 +{
132916 + DPA_ASSERT(!ed || (portal == qm_dc_portal_fman0) ||
132917 + (portal == qm_dc_portal_fman1));
132918 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132919 + qm_out(DCP_CFG(portal), (ed ? 0x1000 : 0) | (sernd & 0x3ff));
132920 + else
132921 + qm_out(DCP_CFG(portal), (ed ? 0x100 : 0) | (sernd & 0x1f));
132922 +}
132923 +
132924 +static void qm_set_wq_scheduling(struct qman *qm, enum qm_wq_class wq_class,
132925 + u8 cs_elev, u8 csw2, u8 csw3, u8 csw4, u8 csw5,
132926 + u8 csw6, u8 csw7)
132927 +{
132928 + qm_out(WQ_CS_CFG(wq_class), ((cs_elev & 0xff) << 24) |
132929 + ((csw2 & 0x7) << 20) | ((csw3 & 0x7) << 16) |
132930 + ((csw4 & 0x7) << 12) | ((csw5 & 0x7) << 8) |
132931 + ((csw6 & 0x7) << 4) | (csw7 & 0x7));
132932 +}
132933 +
132934 +static void qm_set_hid(struct qman *qm)
132935 +{
132936 + qm_out(HID_CFG, 0);
132937 +}
132938 +
132939 +static void qm_set_corenet_initiator(struct qman *qm)
132940 +{
132941 + qm_out(CI_SCHED_CFG,
132942 + 0x80000000 | /* write srcciv enable */
132943 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRCCIV << 24) |
132944 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRQ_W << 8) |
132945 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_RW_W << 4) |
132946 + CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W);
132947 +}
132948 +
132949 +static void qm_get_version(struct qman *qm, u16 *id, u8 *major, u8 *minor,
132950 + u8 *cfg)
132951 +{
132952 + u32 v = qm_in(IP_REV_1);
132953 + u32 v2 = qm_in(IP_REV_2);
132954 + *id = (v >> 16);
132955 + *major = (v >> 8) & 0xff;
132956 + *minor = v & 0xff;
132957 + *cfg = v2 & 0xff;
132958 +}
132959 +
132960 +static void qm_set_memory(struct qman *qm, enum qm_memory memory, u64 ba,
132961 + int enable, int prio, int stash, u32 size)
132962 +{
132963 + u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE;
132964 + u32 exp = ilog2(size);
132965 + /* choke if size isn't within range */
132966 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
132967 + is_power_of_2(size));
132968 + /* choke if 'ba' has lower-alignment than 'size' */
132969 + DPA_ASSERT(!(ba & (size - 1)));
132970 + __qm_out(qm, offset, upper_32_bits(ba));
132971 + __qm_out(qm, offset + REG_offset_BAR, lower_32_bits(ba));
132972 + __qm_out(qm, offset + REG_offset_AR,
132973 + (enable ? 0x80000000 : 0) |
132974 + (prio ? 0x40000000 : 0) |
132975 + (stash ? 0x20000000 : 0) |
132976 + (exp - 1));
132977 +}
132978 +
132979 +static void qm_set_pfdr_threshold(struct qman *qm, u32 th, u8 k)
132980 +{
132981 + qm_out(PFDR_FP_LWIT, th & 0xffffff);
132982 + qm_out(PFDR_CFG, k);
132983 +}
132984 +
132985 +static void qm_set_sfdr_threshold(struct qman *qm, u16 th)
132986 +{
132987 + qm_out(SFDR_CFG, th & 0x3ff);
132988 +}
132989 +
132990 +static int qm_init_pfdr(struct qman *qm, u32 pfdr_start, u32 num)
132991 +{
132992 + u8 rslt = MCR_get_rslt(qm_in(MCR));
132993 +
132994 + DPA_ASSERT(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num);
132995 + /* Make sure the command interface is 'idle' */
132996 + if (!MCR_rslt_idle(rslt))
132997 + panic("QMAN_MCR isn't idle");
132998 +
132999 + /* Write the MCR command params then the verb */
133000 + qm_out(MCP(0), pfdr_start);
133001 + /* TODO: remove this - it's a workaround for a model bug that is
133002 + * corrected in more recent versions. We use the workaround until
133003 + * everyone has upgraded. */
133004 + qm_out(MCP(1), (pfdr_start + num - 16));
133005 + lwsync();
133006 + qm_out(MCR, MCR_INIT_PFDR);
133007 + /* Poll for the result */
133008 + do {
133009 + rslt = MCR_get_rslt(qm_in(MCR));
133010 + } while (!MCR_rslt_idle(rslt));
133011 + if (MCR_rslt_ok(rslt))
133012 + return 0;
133013 + if (MCR_rslt_eaccess(rslt))
133014 + return -EACCES;
133015 + if (MCR_rslt_inval(rslt))
133016 + return -EINVAL;
133017 + pr_crit("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt);
133018 + return -ENOSYS;
133019 +}
133020 +
133021 +/*****************/
133022 +/* Config driver */
133023 +/*****************/
133024 +
133025 +#define DEFAULT_FQD_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ)
133026 +#define DEFAULT_PFDR_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_PFDR_SZ)
133027 +
133028 +/* We support only one of these */
133029 +static struct qman *qm;
133030 +static struct device_node *qm_node;
133031 +
133032 +/* And this state belongs to 'qm'. It is set during fsl_qman_init(), but used
133033 + * during qman_init_ccsr(). */
133034 +static dma_addr_t fqd_a, pfdr_a;
133035 +static size_t fqd_sz = DEFAULT_FQD_SZ, pfdr_sz = DEFAULT_PFDR_SZ;
133036 +
133037 +static int qman_fqd(struct reserved_mem *rmem)
133038 +{
133039 + fqd_a = rmem->base;
133040 + fqd_sz = rmem->size;
133041 +
133042 + WARN_ON(!(fqd_a && fqd_sz));
133043 +
133044 + return 0;
133045 +}
133046 +RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd);
133047 +
133048 +static int qman_pfdr(struct reserved_mem *rmem)
133049 +{
133050 + pfdr_a = rmem->base;
133051 + pfdr_sz = rmem->size;
133052 +
133053 + WARN_ON(!(pfdr_a && pfdr_sz));
133054 +
133055 + return 0;
133056 +}
133057 +RESERVEDMEM_OF_DECLARE(qman_fbpr, "fsl,qman-pfdr", qman_pfdr);
133058 +
133059 +size_t get_qman_fqd_size()
133060 +{
133061 + return fqd_sz;
133062 +}
133063 +
133064 +/* Parse the <name> property to extract the memory location and size and
133065 + * memblock_reserve() it. If it isn't supplied, memblock_alloc() the default
133066 + * size. Also flush this memory range from data cache so that QMAN originated
133067 + * transactions for this memory region could be marked non-coherent.
133068 + */
133069 +static __init int parse_mem_property(struct device_node *node, const char *name,
133070 + dma_addr_t *addr, size_t *sz, int zero)
133071 +{
133072 + int ret;
133073 +
133074 + /* If using a "zero-pma", don't try to zero it, even if you asked */
133075 + if (zero && of_find_property(node, "zero-pma", &ret)) {
133076 + pr_info(" it's a 'zero-pma', not zeroing from s/w\n");
133077 + zero = 0;
133078 + }
133079 +
133080 + if (zero) {
133081 + /* map as cacheable, non-guarded */
133082 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
133083 + void __iomem *tmpp = ioremap_cache(*addr, *sz);
133084 +#else
133085 + void __iomem *tmpp = ioremap(*addr, *sz);
133086 +#endif
133087 +
133088 + if (!tmpp)
133089 + return -ENOMEM;
133090 + memset_io(tmpp, 0, *sz);
133091 + flush_dcache_range((unsigned long)tmpp,
133092 + (unsigned long)tmpp + *sz);
133093 + iounmap(tmpp);
133094 + }
133095 +
133096 + return 0;
133097 +}
133098 +
133099 +/* TODO:
133100 + * - there is obviously no handling of errors,
133101 + * - the calls to qm_set_memory() hard-code the priority and CPC-stashing for
133102 + * both memory resources to zero.
133103 + */
133104 +static int __init fsl_qman_init(struct device_node *node)
133105 +{
133106 + struct resource res;
133107 + resource_size_t len;
133108 + u32 __iomem *regs;
133109 + const char *s;
133110 + int ret, standby = 0;
133111 + u16 id;
133112 + u8 major, minor, cfg;
133113 + ret = of_address_to_resource(node, 0, &res);
133114 + if (ret) {
133115 + pr_err("Can't get %s property '%s'\n", node->full_name, "reg");
133116 + return ret;
133117 + }
133118 + s = of_get_property(node, "fsl,hv-claimable", &ret);
133119 + if (s && !strcmp(s, "standby"))
133120 + standby = 1;
133121 + if (!standby) {
133122 + ret = parse_mem_property(node, "fsl,qman-fqd",
133123 + &fqd_a, &fqd_sz, 1);
133124 + pr_info("qman-fqd addr %pad size 0x%zx\n", &fqd_a, fqd_sz);
133125 + BUG_ON(ret);
133126 + ret = parse_mem_property(node, "fsl,qman-pfdr",
133127 + &pfdr_a, &pfdr_sz, 0);
133128 + pr_info("qman-pfdr addr %pad size 0x%zx\n", &pfdr_a, pfdr_sz);
133129 + BUG_ON(ret);
133130 + }
133131 + /* Global configuration */
133132 + len = resource_size(&res);
133133 + if (len != (unsigned long)len)
133134 + return -EINVAL;
133135 + regs = ioremap(res.start, (unsigned long)len);
133136 + qm = qm_create(regs);
133137 + qm_node = node;
133138 + qm_get_version(qm, &id, &major, &minor, &cfg);
133139 + pr_info("Qman ver:%04x,%02x,%02x,%02x\n", id, major, minor, cfg);
133140 + if (!qman_ip_rev) {
133141 + if ((major == 1) && (minor == 0)) {
133142 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
133143 + iounmap(regs);
133144 + return -ENODEV;
133145 + } else if ((major == 1) && (minor == 1))
133146 + qman_ip_rev = QMAN_REV11;
133147 + else if ((major == 1) && (minor == 2))
133148 + qman_ip_rev = QMAN_REV12;
133149 + else if ((major == 2) && (minor == 0))
133150 + qman_ip_rev = QMAN_REV20;
133151 + else if ((major == 3) && (minor == 0))
133152 + qman_ip_rev = QMAN_REV30;
133153 + else if ((major == 3) && (minor == 1))
133154 + qman_ip_rev = QMAN_REV31;
133155 + else if ((major == 3) && (minor == 2))
133156 + qman_ip_rev = QMAN_REV32;
133157 + else {
133158 + pr_warn("unknown Qman version, default to rev1.1\n");
133159 + qman_ip_rev = QMAN_REV11;
133160 + }
133161 + qman_ip_cfg = cfg;
133162 + }
133163 +
133164 + if (standby) {
133165 + pr_info(" -> in standby mode\n");
133166 + return 0;
133167 + }
133168 + return 0;
133169 +}
133170 +
133171 +int qman_have_ccsr(void)
133172 +{
133173 + return qm ? 1 : 0;
133174 +}
133175 +
133176 +__init int qman_init_early(void)
133177 +{
133178 + struct device_node *dn;
133179 + int ret;
133180 +
133181 + for_each_compatible_node(dn, NULL, "fsl,qman") {
133182 + if (qm)
133183 + pr_err("%s: only one 'fsl,qman' allowed\n",
133184 + dn->full_name);
133185 + else {
133186 + if (!of_device_is_available(dn))
133187 + continue;
133188 +
133189 + ret = fsl_qman_init(dn);
133190 + BUG_ON(ret);
133191 + }
133192 + }
133193 + return 0;
133194 +}
133195 +postcore_initcall_sync(qman_init_early);
133196 +
133197 +static void log_edata_bits(u32 bit_count)
133198 +{
133199 + u32 i, j, mask = 0xffffffff;
133200 +
133201 + pr_warn("Qman ErrInt, EDATA:\n");
133202 + i = bit_count/32;
133203 + if (bit_count%32) {
133204 + i++;
133205 + mask = ~(mask << bit_count%32);
133206 + }
133207 + j = 16-i;
133208 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)) & mask);
133209 + j++;
133210 + for (; j < 16; j++)
133211 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)));
133212 +}
133213 +
133214 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
133215 +{
133216 + union qman_ecir ecir_val;
133217 + union qman_eadr eadr_val;
133218 +
133219 + ecir_val.ecir_raw = qm_in(ECIR);
133220 + /* Is portal info valid */
133221 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
133222 + union qman_ecir2 ecir2_val;
133223 + ecir2_val.ecir2_raw = qm_in(ECIR2);
133224 + if (ecsr_val & PORTAL_ECSR_ERR) {
133225 + pr_warn("Qman ErrInt: %s id %d\n",
133226 + (ecir2_val.info.portal_type) ?
133227 + "DCP" : "SWP", ecir2_val.info.portal_num);
133228 + }
133229 + if (ecsr_val & (FQID_ECSR_ERR | QM_EIRQ_IECE)) {
133230 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
133231 + ecir_val.info.fqid);
133232 + }
133233 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
133234 + eadr_val.eadr_raw = qm_in(EADR);
133235 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
133236 + error_mdata[eadr_val.info_rev3.memid].txt,
133237 + error_mdata[eadr_val.info_rev3.memid].addr_mask
133238 + & eadr_val.info_rev3.eadr);
133239 + log_edata_bits(
133240 + error_mdata[eadr_val.info_rev3.memid].bits);
133241 + }
133242 + } else {
133243 + if (ecsr_val & PORTAL_ECSR_ERR) {
133244 + pr_warn("Qman ErrInt: %s id %d\n",
133245 + (ecir_val.info.portal_type) ?
133246 + "DCP" : "SWP", ecir_val.info.portal_num);
133247 + }
133248 + if (ecsr_val & FQID_ECSR_ERR) {
133249 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
133250 + ecir_val.info.fqid);
133251 + }
133252 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
133253 + eadr_val.eadr_raw = qm_in(EADR);
133254 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
133255 + error_mdata[eadr_val.info.memid].txt,
133256 + error_mdata[eadr_val.info.memid].addr_mask
133257 + & eadr_val.info.eadr);
133258 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
133259 + }
133260 + }
133261 +}
133262 +
133263 +/* Qman interrupt handler */
133264 +static irqreturn_t qman_isr(int irq, void *ptr)
133265 +{
133266 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
133267 +
133268 + ier_val = qm_err_isr_enable_read(qm);
133269 + isr_val = qm_err_isr_status_read(qm);
133270 + ecsr_val = qm_in(ECSR);
133271 + isr_mask = isr_val & ier_val;
133272 +
133273 + if (!isr_mask)
133274 + return IRQ_NONE;
133275 + for (i = 0; i < QMAN_HWE_COUNT; i++) {
133276 + if (qman_hwerr_txts[i].mask & isr_mask) {
133277 + pr_warn("Qman ErrInt: %s\n", qman_hwerr_txts[i].txt);
133278 + if (qman_hwerr_txts[i].mask & ecsr_val) {
133279 + log_additional_error_info(isr_mask, ecsr_val);
133280 + /* Re-arm error capture registers */
133281 + qm_out(ECSR, ecsr_val);
133282 + }
133283 + if (qman_hwerr_txts[i].mask & QMAN_ERRS_TO_UNENABLE) {
133284 + pr_devel("Qman un-enabling error 0x%x\n",
133285 + qman_hwerr_txts[i].mask);
133286 + ier_val &= ~qman_hwerr_txts[i].mask;
133287 + qm_err_isr_enable_write(qm, ier_val);
133288 + }
133289 + }
133290 + }
133291 + qm_err_isr_status_clear(qm, isr_val);
133292 + return IRQ_HANDLED;
133293 +}
133294 +
133295 +static int __bind_irq(void)
133296 +{
133297 + int ret, err_irq;
133298 +
133299 + err_irq = of_irq_to_resource(qm_node, 0, NULL);
133300 + if (err_irq == 0) {
133301 + pr_info("Can't get %s property '%s'\n", qm_node->full_name,
133302 + "interrupts");
133303 + return -ENODEV;
133304 + }
133305 + ret = request_irq(err_irq, qman_isr, IRQF_SHARED, "qman-err", qm_node);
133306 + if (ret) {
133307 + pr_err("request_irq() failed %d for '%s'\n", ret,
133308 + qm_node->full_name);
133309 + return -ENODEV;
133310 + }
133311 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
133312 + * to resource allocation during driver init). */
133313 + qm_err_isr_status_clear(qm, 0xffffffff);
133314 + /* Enable Error Interrupts */
133315 + qm_err_isr_enable_write(qm, 0xffffffff);
133316 + return 0;
133317 +}
133318 +
133319 +int qman_init_ccsr(struct device_node *node)
133320 +{
133321 + int ret;
133322 + if (!qman_have_ccsr())
133323 + return 0;
133324 + if (node != qm_node)
133325 + return -EINVAL;
133326 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
133327 + /* TEMP for LS1043 : should be done in uboot */
133328 + qm_out(QCSP_BARE, 0x5);
133329 + qm_out(QCSP_BAR, 0x0);
133330 +#endif
133331 + /* FQD memory */
133332 + qm_set_memory(qm, qm_memory_fqd, fqd_a, 1, 0, 0, fqd_sz);
133333 + /* PFDR memory */
133334 + qm_set_memory(qm, qm_memory_pfdr, pfdr_a, 1, 0, 0, pfdr_sz);
133335 + qm_init_pfdr(qm, 8, pfdr_sz / 64 - 8);
133336 + /* thresholds */
133337 + qm_set_pfdr_threshold(qm, 512, 64);
133338 + qm_set_sfdr_threshold(qm, 128);
133339 + /* clear stale PEBI bit from interrupt status register */
133340 + qm_err_isr_status_clear(qm, QM_EIRQ_PEBI);
133341 + /* corenet initiator settings */
133342 + qm_set_corenet_initiator(qm);
133343 + /* HID settings */
133344 + qm_set_hid(qm);
133345 + /* Set scheduling weights to defaults */
133346 + for (ret = qm_wq_first; ret <= qm_wq_last; ret++)
133347 + qm_set_wq_scheduling(qm, ret, 0, 0, 0, 0, 0, 0, 0);
133348 + /* We are not prepared to accept ERNs for hardware enqueues */
133349 + qm_set_dc(qm, qm_dc_portal_fman0, 1, 0);
133350 + qm_set_dc(qm, qm_dc_portal_fman1, 1, 0);
133351 + /* Initialise Error Interrupt Handler */
133352 + ret = __bind_irq();
133353 + if (ret)
133354 + return ret;
133355 + return 0;
133356 +}
133357 +
133358 +#define LIO_CFG_LIODN_MASK 0x0fff0000
133359 +void qman_liodn_fixup(u16 channel)
133360 +{
133361 + static int done;
133362 + static u32 liodn_offset;
133363 + u32 before, after;
133364 + int idx = channel - QM_CHANNEL_SWPORTAL0;
133365 +
133366 + if (!qman_have_ccsr())
133367 + return;
133368 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
133369 + before = qm_in(REV3_QCSP_LIO_CFG(idx));
133370 + else
133371 + before = qm_in(QCSP_LIO_CFG(idx));
133372 + if (!done) {
133373 + liodn_offset = before & LIO_CFG_LIODN_MASK;
133374 + done = 1;
133375 + return;
133376 + }
133377 + after = (before & (~LIO_CFG_LIODN_MASK)) | liodn_offset;
133378 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
133379 + qm_out(REV3_QCSP_LIO_CFG(idx), after);
133380 + else
133381 + qm_out(QCSP_LIO_CFG(idx), after);
133382 +}
133383 +
133384 +#define IO_CFG_SDEST_MASK 0x00ff0000
133385 +int qman_set_sdest(u16 channel, unsigned int cpu_idx)
133386 +{
133387 + int idx = channel - QM_CHANNEL_SWPORTAL0;
133388 + u32 before, after;
133389 +
133390 + if (!qman_have_ccsr())
133391 + return -ENODEV;
133392 + if ((qman_ip_rev & 0xFF00) == QMAN_REV31) {
133393 + /* LS1043A - only one L2 cache */
133394 + cpu_idx = 0;
133395 + }
133396 +
133397 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
133398 + before = qm_in(REV3_QCSP_IO_CFG(idx));
133399 + /* Each pair of vcpu share the same SRQ(SDEST) */
133400 + cpu_idx /= 2;
133401 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
133402 + qm_out(REV3_QCSP_IO_CFG(idx), after);
133403 + } else {
133404 + before = qm_in(QCSP_IO_CFG(idx));
133405 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
133406 + qm_out(QCSP_IO_CFG(idx), after);
133407 + }
133408 + return 0;
133409 +}
133410 +
133411 +#define MISC_CFG_WPM_MASK 0x00000002
133412 +int qm_set_wpm(int wpm)
133413 +{
133414 + u32 before;
133415 + u32 after;
133416 +
133417 + if (!qman_have_ccsr())
133418 + return -ENODEV;
133419 +
133420 + before = qm_in(MISC_CFG);
133421 + after = (before & (~MISC_CFG_WPM_MASK)) | (wpm << 1);
133422 + qm_out(MISC_CFG, after);
133423 + return 0;
133424 +}
133425 +
133426 +int qm_get_wpm(int *wpm)
133427 +{
133428 + u32 before;
133429 +
133430 + if (!qman_have_ccsr())
133431 + return -ENODEV;
133432 +
133433 + before = qm_in(MISC_CFG);
133434 + *wpm = (before & MISC_CFG_WPM_MASK) >> 1;
133435 + return 0;
133436 +}
133437 +
133438 +/* CEETM_CFG_PRES register has PRES field which is calculated by:
133439 + * PRES = (2^22 / credit update reference period) * QMan clock period
133440 + * = (2^22 * 10^9)/ CONFIG_QMAN_CEETM_UPDATE_PERIOD) / qman_clk
133441 + */
133442 +
133443 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal)
133444 +{
133445 + u64 temp;
133446 + u16 pres;
133447 +
133448 + if (!qman_have_ccsr())
133449 + return -ENODEV;
133450 +
133451 + temp = 0x400000 * 100;
133452 + do_div(temp, CONFIG_QMAN_CEETM_UPDATE_PERIOD);
133453 + temp *= 10000000;
133454 + do_div(temp, qman_clk);
133455 + pres = (u16) temp;
133456 + qm_out(CEETM_CFG_IDX, portal);
133457 + qm_out(CEETM_CFG_PRES, pres);
133458 + return 0;
133459 +}
133460 +
133461 +int qman_ceetm_get_prescaler(u16 *pres)
133462 +{
133463 + if (!qman_have_ccsr())
133464 + return -ENODEV;
133465 + *pres = (u16)qm_in(CEETM_CFG_PRES);
133466 + return 0;
133467 +}
133468 +
133469 +#define DCP_CFG_CEETME_MASK 0xFFFF0000
133470 +#define QM_SP_ENABLE_CEETM(n) (0x80000000 >> (n))
133471 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
133472 +{
133473 + u32 dcp_cfg;
133474 +
133475 + if (!qman_have_ccsr())
133476 + return -ENODEV;
133477 +
133478 + dcp_cfg = qm_in(DCP_CFG(portal));
133479 + dcp_cfg |= QM_SP_ENABLE_CEETM(sub_portal);
133480 + qm_out(DCP_CFG(portal), dcp_cfg);
133481 + return 0;
133482 +}
133483 +
133484 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
133485 +{
133486 + u32 dcp_cfg;
133487 +
133488 + if (!qman_have_ccsr())
133489 + return -ENODEV;
133490 + dcp_cfg = qm_in(DCP_CFG(portal));
133491 + dcp_cfg &= ~(QM_SP_ENABLE_CEETM(sub_portal));
133492 + qm_out(DCP_CFG(portal), dcp_cfg);
133493 + return 0;
133494 +}
133495 +
133496 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num)
133497 +{
133498 + if (!qman_have_ccsr())
133499 + return -ENODEV;
133500 + *num = qm_in(CEETM_XSFDR_IN_USE);
133501 + return 0;
133502 +}
133503 +EXPORT_SYMBOL(qman_ceetm_get_xsfdr);
133504 +
133505 +#ifdef CONFIG_SYSFS
133506 +
133507 +#define DRV_NAME "fsl-qman"
133508 +#define DCP_MAX_ID 3
133509 +#define DCP_MIN_ID 0
133510 +
133511 +static ssize_t show_pfdr_fpc(struct device *dev,
133512 + struct device_attribute *dev_attr, char *buf)
133513 +{
133514 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_FPC));
133515 +};
133516 +
133517 +static ssize_t show_dlm_avg(struct device *dev,
133518 + struct device_attribute *dev_attr, char *buf)
133519 +{
133520 + u32 data;
133521 + int i;
133522 +
133523 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
133524 + return -EINVAL;
133525 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
133526 + return -EINVAL;
133527 + data = qm_in(DCP_DLM_AVG(i));
133528 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
133529 + (data & 0x000000ff)*390625);
133530 +};
133531 +
133532 +static ssize_t set_dlm_avg(struct device *dev,
133533 + struct device_attribute *dev_attr, const char *buf, size_t count)
133534 +{
133535 + unsigned long val;
133536 + int i;
133537 +
133538 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
133539 + return -EINVAL;
133540 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
133541 + return -EINVAL;
133542 + if (kstrtoul(buf, 0, &val)) {
133543 + dev_dbg(dev, "invalid input %s\n", buf);
133544 + return -EINVAL;
133545 + }
133546 + qm_out(DCP_DLM_AVG(i), val);
133547 + return count;
133548 +};
133549 +
133550 +static ssize_t show_pfdr_cfg(struct device *dev,
133551 + struct device_attribute *dev_attr, char *buf)
133552 +{
133553 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_CFG));
133554 +};
133555 +
133556 +static ssize_t set_pfdr_cfg(struct device *dev,
133557 + struct device_attribute *dev_attr, const char *buf, size_t count)
133558 +{
133559 + unsigned long val;
133560 +
133561 + if (kstrtoul(buf, 0, &val)) {
133562 + dev_dbg(dev, "invalid input %s\n", buf);
133563 + return -EINVAL;
133564 + }
133565 + qm_out(PFDR_CFG, val);
133566 + return count;
133567 +};
133568 +
133569 +static ssize_t show_sfdr_in_use(struct device *dev,
133570 + struct device_attribute *dev_attr, char *buf)
133571 +{
133572 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SFDR_IN_USE));
133573 +};
133574 +
133575 +static ssize_t show_idle_stat(struct device *dev,
133576 + struct device_attribute *dev_attr, char *buf)
133577 +{
133578 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(IDLE_STAT));
133579 +};
133580 +
133581 +static ssize_t show_ci_rlm_avg(struct device *dev,
133582 + struct device_attribute *dev_attr, char *buf)
133583 +{
133584 + u32 data = qm_in(CI_RLM_AVG);
133585 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
133586 + (data & 0x000000ff)*390625);
133587 +};
133588 +
133589 +static ssize_t set_ci_rlm_avg(struct device *dev,
133590 + struct device_attribute *dev_attr, const char *buf, size_t count)
133591 +{
133592 + unsigned long val;
133593 +
133594 + if (kstrtoul(buf, 0, &val)) {
133595 + dev_dbg(dev, "invalid input %s\n", buf);
133596 + return -EINVAL;
133597 + }
133598 + qm_out(CI_RLM_AVG, val);
133599 + return count;
133600 +};
133601 +
133602 +static ssize_t show_err_isr(struct device *dev,
133603 + struct device_attribute *dev_attr, char *buf)
133604 +{
133605 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", qm_in(ERR_ISR));
133606 +};
133607 +
133608 +#define SBEC_MAX_ID 14
133609 +#define SBEC_MIN_ID 0
133610 +
133611 +static ssize_t show_sbec(struct device *dev,
133612 + struct device_attribute *dev_attr, char *buf)
133613 +{
133614 + int i;
133615 +
133616 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
133617 + return -EINVAL;
133618 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
133619 + return -EINVAL;
133620 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SBEC(i)));
133621 +};
133622 +
133623 +static DEVICE_ATTR(pfdr_fpc, S_IRUSR, show_pfdr_fpc, NULL);
133624 +static DEVICE_ATTR(pfdr_cfg, S_IRUSR, show_pfdr_cfg, set_pfdr_cfg);
133625 +static DEVICE_ATTR(idle_stat, S_IRUSR, show_idle_stat, NULL);
133626 +static DEVICE_ATTR(ci_rlm_avg, (S_IRUSR|S_IWUSR),
133627 + show_ci_rlm_avg, set_ci_rlm_avg);
133628 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
133629 +static DEVICE_ATTR(sfdr_in_use, S_IRUSR, show_sfdr_in_use, NULL);
133630 +
133631 +static DEVICE_ATTR(dcp0_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133632 +static DEVICE_ATTR(dcp1_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133633 +static DEVICE_ATTR(dcp2_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133634 +static DEVICE_ATTR(dcp3_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133635 +
133636 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
133637 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
133638 +static DEVICE_ATTR(sbec_2, S_IRUSR, show_sbec, NULL);
133639 +static DEVICE_ATTR(sbec_3, S_IRUSR, show_sbec, NULL);
133640 +static DEVICE_ATTR(sbec_4, S_IRUSR, show_sbec, NULL);
133641 +static DEVICE_ATTR(sbec_5, S_IRUSR, show_sbec, NULL);
133642 +static DEVICE_ATTR(sbec_6, S_IRUSR, show_sbec, NULL);
133643 +static DEVICE_ATTR(sbec_7, S_IRUSR, show_sbec, NULL);
133644 +static DEVICE_ATTR(sbec_8, S_IRUSR, show_sbec, NULL);
133645 +static DEVICE_ATTR(sbec_9, S_IRUSR, show_sbec, NULL);
133646 +static DEVICE_ATTR(sbec_10, S_IRUSR, show_sbec, NULL);
133647 +static DEVICE_ATTR(sbec_11, S_IRUSR, show_sbec, NULL);
133648 +static DEVICE_ATTR(sbec_12, S_IRUSR, show_sbec, NULL);
133649 +static DEVICE_ATTR(sbec_13, S_IRUSR, show_sbec, NULL);
133650 +static DEVICE_ATTR(sbec_14, S_IRUSR, show_sbec, NULL);
133651 +
133652 +static struct attribute *qman_dev_attributes[] = {
133653 + &dev_attr_pfdr_fpc.attr,
133654 + &dev_attr_pfdr_cfg.attr,
133655 + &dev_attr_idle_stat.attr,
133656 + &dev_attr_ci_rlm_avg.attr,
133657 + &dev_attr_err_isr.attr,
133658 + &dev_attr_dcp0_dlm_avg.attr,
133659 + &dev_attr_dcp1_dlm_avg.attr,
133660 + &dev_attr_dcp2_dlm_avg.attr,
133661 + &dev_attr_dcp3_dlm_avg.attr,
133662 + /* sfdr_in_use will be added if necessary */
133663 + NULL
133664 +};
133665 +
133666 +static struct attribute *qman_dev_ecr_attributes[] = {
133667 + &dev_attr_sbec_0.attr,
133668 + &dev_attr_sbec_1.attr,
133669 + &dev_attr_sbec_2.attr,
133670 + &dev_attr_sbec_3.attr,
133671 + &dev_attr_sbec_4.attr,
133672 + &dev_attr_sbec_5.attr,
133673 + &dev_attr_sbec_6.attr,
133674 + &dev_attr_sbec_7.attr,
133675 + &dev_attr_sbec_8.attr,
133676 + &dev_attr_sbec_9.attr,
133677 + &dev_attr_sbec_10.attr,
133678 + &dev_attr_sbec_11.attr,
133679 + &dev_attr_sbec_12.attr,
133680 + &dev_attr_sbec_13.attr,
133681 + &dev_attr_sbec_14.attr,
133682 + NULL
133683 +};
133684 +
133685 +/* root level */
133686 +static const struct attribute_group qman_dev_attr_grp = {
133687 + .name = NULL,
133688 + .attrs = qman_dev_attributes
133689 +};
133690 +static const struct attribute_group qman_dev_ecr_grp = {
133691 + .name = "error_capture",
133692 + .attrs = qman_dev_ecr_attributes
133693 +};
133694 +
133695 +static int of_fsl_qman_remove(struct platform_device *ofdev)
133696 +{
133697 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133698 + return 0;
133699 +};
133700 +
133701 +static int of_fsl_qman_probe(struct platform_device *ofdev)
133702 +{
133703 + int ret;
133704 +
133705 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133706 + if (ret)
133707 + goto done;
133708 + ret = sysfs_add_file_to_group(&ofdev->dev.kobj,
133709 + &dev_attr_sfdr_in_use.attr, qman_dev_attr_grp.name);
133710 + if (ret)
133711 + goto del_group_0;
133712 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_ecr_grp);
133713 + if (ret)
133714 + goto del_group_0;
133715 +
133716 + goto done;
133717 +
133718 +del_group_0:
133719 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133720 +done:
133721 + if (ret)
133722 + dev_err(&ofdev->dev,
133723 + "Cannot create dev attributes ret=%d\n", ret);
133724 + return ret;
133725 +};
133726 +
133727 +static struct of_device_id of_fsl_qman_ids[] = {
133728 + {
133729 + .compatible = "fsl,qman",
133730 + },
133731 + {}
133732 +};
133733 +MODULE_DEVICE_TABLE(of, of_fsl_qman_ids);
133734 +
133735 +#ifdef CONFIG_SUSPEND
133736 +
133737 +static u32 saved_isdr;
133738 +static int qman_pm_suspend_noirq(struct device *dev)
133739 +{
133740 + uint32_t idle_state;
133741 +
133742 + suspend_unused_qportal();
133743 + /* save isdr, disable all, clear isr */
133744 + saved_isdr = qm_err_isr_disable_read(qm);
133745 + qm_err_isr_disable_write(qm, 0xffffffff);
133746 + qm_err_isr_status_clear(qm, 0xffffffff);
133747 + idle_state = qm_in(IDLE_STAT);
133748 + if (!(idle_state & 0x1)) {
133749 + pr_err("Qman not idle 0x%x aborting\n", idle_state);
133750 + qm_err_isr_disable_write(qm, saved_isdr);
133751 + resume_unused_qportal();
133752 + return -EBUSY;
133753 + }
133754 +#ifdef CONFIG_PM_DEBUG
133755 + pr_info("Qman suspend code, IDLE_STAT = 0x%x\n", idle_state);
133756 +#endif
133757 + return 0;
133758 +}
133759 +
133760 +static int qman_pm_resume_noirq(struct device *dev)
133761 +{
133762 + /* restore isdr */
133763 + qm_err_isr_disable_write(qm, saved_isdr);
133764 + resume_unused_qportal();
133765 + return 0;
133766 +}
133767 +#else
133768 +#define qman_pm_suspend_noirq NULL
133769 +#define qman_pm_resume_noirq NULL
133770 +#endif
133771 +
133772 +static const struct dev_pm_ops qman_pm_ops = {
133773 + .suspend_noirq = qman_pm_suspend_noirq,
133774 + .resume_noirq = qman_pm_resume_noirq,
133775 +};
133776 +
133777 +static struct platform_driver of_fsl_qman_driver = {
133778 + .driver = {
133779 + .owner = THIS_MODULE,
133780 + .name = DRV_NAME,
133781 + .of_match_table = of_fsl_qman_ids,
133782 + .pm = &qman_pm_ops,
133783 + },
133784 + .probe = of_fsl_qman_probe,
133785 + .remove = of_fsl_qman_remove,
133786 +};
133787 +
133788 +static int qman_ctrl_init(void)
133789 +{
133790 + return platform_driver_register(&of_fsl_qman_driver);
133791 +}
133792 +
133793 +static void qman_ctrl_exit(void)
133794 +{
133795 + platform_driver_unregister(&of_fsl_qman_driver);
133796 +}
133797 +
133798 +module_init(qman_ctrl_init);
133799 +module_exit(qman_ctrl_exit);
133800 +
133801 +#endif /* CONFIG_SYSFS */
133802 diff --git a/drivers/staging/fsl_qbman/qman_debugfs.c b/drivers/staging/fsl_qbman/qman_debugfs.c
133803 new file mode 100644
133804 index 00000000..fb8ecba1
133805 --- /dev/null
133806 +++ b/drivers/staging/fsl_qbman/qman_debugfs.c
133807 @@ -0,0 +1,1594 @@
133808 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
133809 + *
133810 + * Redistribution and use in source and binary forms, with or without
133811 + * modification, are permitted provided that the following conditions are met:
133812 + * * Redistributions of source code must retain the above copyright
133813 + * notice, this list of conditions and the following disclaimer.
133814 + * * Redistributions in binary form must reproduce the above copyright
133815 + * notice, this list of conditions and the following disclaimer in the
133816 + * documentation and/or other materials provided with the distribution.
133817 + * * Neither the name of Freescale Semiconductor nor the
133818 + * names of its contributors may be used to endorse or promote products
133819 + * derived from this software without specific prior written permission.
133820 + *
133821 + *
133822 + * ALTERNATIVELY, this software may be distributed under the terms of the
133823 + * GNU General Public License ("GPL") as published by the Free Software
133824 + * Foundation, either version 2 of that License or (at your option) any
133825 + * later version.
133826 + *
133827 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133828 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133829 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133830 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133831 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133832 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133833 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133834 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133835 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133836 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133837 + */
133838 +#include "qman_private.h"
133839 +
133840 +#define MAX_FQID (0x00ffffff)
133841 +#define QM_FQD_BLOCK_SIZE 64
133842 +#define QM_FQD_AR (0xC10)
133843 +
133844 +static u32 fqid_max;
133845 +static u64 qman_ccsr_start;
133846 +static u64 qman_ccsr_size;
133847 +
133848 +static const char * const state_txt[] = {
133849 + "Out of Service",
133850 + "Retired",
133851 + "Tentatively Scheduled",
133852 + "Truly Scheduled",
133853 + "Parked",
133854 + "Active, Active Held or Held Suspended",
133855 + "Unknown State 6",
133856 + "Unknown State 7",
133857 + NULL,
133858 +};
133859 +
133860 +static const u8 fqd_states[] = {
133861 + QM_MCR_NP_STATE_OOS, QM_MCR_NP_STATE_RETIRED, QM_MCR_NP_STATE_TEN_SCHED,
133862 + QM_MCR_NP_STATE_TRU_SCHED, QM_MCR_NP_STATE_PARKED,
133863 + QM_MCR_NP_STATE_ACTIVE};
133864 +
133865 +struct mask_to_text {
133866 + u16 mask;
133867 + const char *txt;
133868 +};
133869 +
133870 +struct mask_filter_s {
133871 + u16 mask;
133872 + u8 filter;
133873 +};
133874 +
133875 +static const struct mask_filter_s mask_filter[] = {
133876 + {QM_FQCTRL_PREFERINCACHE, 0},
133877 + {QM_FQCTRL_PREFERINCACHE, 1},
133878 + {QM_FQCTRL_HOLDACTIVE, 0},
133879 + {QM_FQCTRL_HOLDACTIVE, 1},
133880 + {QM_FQCTRL_AVOIDBLOCK, 0},
133881 + {QM_FQCTRL_AVOIDBLOCK, 1},
133882 + {QM_FQCTRL_FORCESFDR, 0},
133883 + {QM_FQCTRL_FORCESFDR, 1},
133884 + {QM_FQCTRL_CPCSTASH, 0},
133885 + {QM_FQCTRL_CPCSTASH, 1},
133886 + {QM_FQCTRL_CTXASTASHING, 0},
133887 + {QM_FQCTRL_CTXASTASHING, 1},
133888 + {QM_FQCTRL_ORP, 0},
133889 + {QM_FQCTRL_ORP, 1},
133890 + {QM_FQCTRL_TDE, 0},
133891 + {QM_FQCTRL_TDE, 1},
133892 + {QM_FQCTRL_CGE, 0},
133893 + {QM_FQCTRL_CGE, 1}
133894 +};
133895 +
133896 +static const struct mask_to_text fq_ctrl_text_list[] = {
133897 + {
133898 + .mask = QM_FQCTRL_PREFERINCACHE,
133899 + .txt = "Prefer in cache",
133900 + },
133901 + {
133902 + .mask = QM_FQCTRL_HOLDACTIVE,
133903 + .txt = "Hold active in portal",
133904 + },
133905 + {
133906 + .mask = QM_FQCTRL_AVOIDBLOCK,
133907 + .txt = "Avoid Blocking",
133908 + },
133909 + {
133910 + .mask = QM_FQCTRL_FORCESFDR,
133911 + .txt = "High-priority SFDRs",
133912 + },
133913 + {
133914 + .mask = QM_FQCTRL_CPCSTASH,
133915 + .txt = "CPC Stash Enable",
133916 + },
133917 + {
133918 + .mask = QM_FQCTRL_CTXASTASHING,
133919 + .txt = "Context-A stashing",
133920 + },
133921 + {
133922 + .mask = QM_FQCTRL_ORP,
133923 + .txt = "ORP Enable",
133924 + },
133925 + {
133926 + .mask = QM_FQCTRL_TDE,
133927 + .txt = "Tail-Drop Enable",
133928 + },
133929 + {
133930 + .mask = QM_FQCTRL_CGE,
133931 + .txt = "Congestion Group Enable",
133932 + },
133933 + {
133934 + .mask = 0,
133935 + .txt = NULL,
133936 + }
133937 +};
133938 +
133939 +static const char *get_fqd_ctrl_text(u16 mask)
133940 +{
133941 + int i = 0;
133942 +
133943 + while (fq_ctrl_text_list[i].txt != NULL) {
133944 + if (fq_ctrl_text_list[i].mask == mask)
133945 + return fq_ctrl_text_list[i].txt;
133946 + i++;
133947 + }
133948 + return NULL;
133949 +}
133950 +
133951 +static const struct mask_to_text stashing_text_list[] = {
133952 + {
133953 + .mask = QM_STASHING_EXCL_CTX,
133954 + .txt = "FQ Ctx Stash"
133955 + },
133956 + {
133957 + .mask = QM_STASHING_EXCL_DATA,
133958 + .txt = "Frame Data Stash",
133959 + },
133960 + {
133961 + .mask = QM_STASHING_EXCL_ANNOTATION,
133962 + .txt = "Frame Annotation Stash",
133963 + },
133964 + {
133965 + .mask = 0,
133966 + .txt = NULL,
133967 + },
133968 +};
133969 +
133970 +static int user_input_convert(const char __user *user_buf, size_t count,
133971 + unsigned long *val)
133972 +{
133973 + char buf[12];
133974 +
133975 + if (count > sizeof(buf) - 1)
133976 + return -EINVAL;
133977 + if (copy_from_user(buf, user_buf, count))
133978 + return -EFAULT;
133979 + buf[count] = '\0';
133980 + if (kstrtoul(buf, 0, val))
133981 + return -EINVAL;
133982 + return 0;
133983 +}
133984 +
133985 +struct line_buffer_fq {
133986 + u32 buf[8];
133987 + u32 buf_cnt;
133988 + int line_cnt;
133989 +};
133990 +
133991 +static void add_to_line_buffer(struct line_buffer_fq *line_buf, u32 fqid,
133992 + struct seq_file *file)
133993 +{
133994 + line_buf->buf[line_buf->buf_cnt] = fqid;
133995 + line_buf->buf_cnt++;
133996 + if (line_buf->buf_cnt == 8) {
133997 + /* Buffer is full, flush it */
133998 + if (line_buf->line_cnt != 0)
133999 + seq_puts(file, ",\n");
134000 + seq_printf(file, "0x%06x,0x%06x,0x%06x,0x%06x,0x%06x,"
134001 + "0x%06x,0x%06x,0x%06x",
134002 + line_buf->buf[0], line_buf->buf[1], line_buf->buf[2],
134003 + line_buf->buf[3], line_buf->buf[4], line_buf->buf[5],
134004 + line_buf->buf[6], line_buf->buf[7]);
134005 + line_buf->buf_cnt = 0;
134006 + line_buf->line_cnt++;
134007 + }
134008 +}
134009 +
134010 +static void flush_line_buffer(struct line_buffer_fq *line_buf,
134011 + struct seq_file *file)
134012 +{
134013 + if (line_buf->buf_cnt) {
134014 + int y = 0;
134015 + if (line_buf->line_cnt != 0)
134016 + seq_puts(file, ",\n");
134017 + while (y != line_buf->buf_cnt) {
134018 + if (y+1 == line_buf->buf_cnt)
134019 + seq_printf(file, "0x%06x", line_buf->buf[y]);
134020 + else
134021 + seq_printf(file, "0x%06x,", line_buf->buf[y]);
134022 + y++;
134023 + }
134024 + line_buf->line_cnt++;
134025 + }
134026 + if (line_buf->line_cnt)
134027 + seq_putc(file, '\n');
134028 +}
134029 +
134030 +static struct dentry *dfs_root; /* debugfs root directory */
134031 +
134032 +/*******************************************************************************
134033 + * Query Frame Queue Non Programmable Fields
134034 + ******************************************************************************/
134035 +struct query_fq_np_fields_data_s {
134036 + u32 fqid;
134037 +};
134038 +static struct query_fq_np_fields_data_s query_fq_np_fields_data = {
134039 + .fqid = 1,
134040 +};
134041 +
134042 +static int query_fq_np_fields_show(struct seq_file *file, void *offset)
134043 +{
134044 + int ret;
134045 + struct qm_mcr_queryfq_np np;
134046 + struct qman_fq fq;
134047 +
134048 + fq.fqid = query_fq_np_fields_data.fqid;
134049 + ret = qman_query_fq_np(&fq, &np);
134050 + if (ret)
134051 + return ret;
134052 + /* Print state */
134053 + seq_printf(file, "Query FQ Non Programmable Fields Result fqid 0x%x\n",
134054 + fq.fqid);
134055 + seq_printf(file, " force eligible pending: %s\n",
134056 + (np.state & QM_MCR_NP_STATE_FE) ? "yes" : "no");
134057 + seq_printf(file, " retirement pending: %s\n",
134058 + (np.state & QM_MCR_NP_STATE_R) ? "yes" : "no");
134059 + seq_printf(file, " state: %s\n",
134060 + state_txt[np.state & QM_MCR_NP_STATE_MASK]);
134061 + seq_printf(file, " fq_link: 0x%x\n", np.fqd_link);
134062 + seq_printf(file, " odp_seq: %u\n", np.odp_seq);
134063 + seq_printf(file, " orp_nesn: %u\n", np.orp_nesn);
134064 + seq_printf(file, " orp_ea_hseq: %u\n", np.orp_ea_hseq);
134065 + seq_printf(file, " orp_ea_tseq: %u\n", np.orp_ea_tseq);
134066 + seq_printf(file, " orp_ea_hptr: 0x%x\n", np.orp_ea_hptr);
134067 + seq_printf(file, " orp_ea_tptr: 0x%x\n", np.orp_ea_tptr);
134068 + seq_printf(file, " pfdr_hptr: 0x%x\n", np.pfdr_hptr);
134069 + seq_printf(file, " pfdr_tptr: 0x%x\n", np.pfdr_tptr);
134070 + seq_printf(file, " is: ics_surp contains a %s\n",
134071 + (np.is) ? "deficit" : "surplus");
134072 + seq_printf(file, " ics_surp: %u\n", np.ics_surp);
134073 + seq_printf(file, " byte_cnt: %u\n", np.byte_cnt);
134074 + seq_printf(file, " frm_cnt: %u\n", np.frm_cnt);
134075 + seq_printf(file, " ra1_sfdr: 0x%x\n", np.ra1_sfdr);
134076 + seq_printf(file, " ra2_sfdr: 0x%x\n", np.ra2_sfdr);
134077 + seq_printf(file, " od1_sfdr: 0x%x\n", np.od1_sfdr);
134078 + seq_printf(file, " od2_sfdr: 0x%x\n", np.od2_sfdr);
134079 + seq_printf(file, " od3_sfdr: 0x%x\n", np.od3_sfdr);
134080 + return 0;
134081 +}
134082 +
134083 +static int query_fq_np_fields_open(struct inode *inode,
134084 + struct file *file)
134085 +{
134086 + return single_open(file, query_fq_np_fields_show, NULL);
134087 +}
134088 +
134089 +static ssize_t query_fq_np_fields_write(struct file *f,
134090 + const char __user *buf, size_t count, loff_t *off)
134091 +{
134092 + int ret;
134093 + unsigned long val;
134094 +
134095 + ret = user_input_convert(buf, count, &val);
134096 + if (ret)
134097 + return ret;
134098 + if (val > MAX_FQID)
134099 + return -EINVAL;
134100 + query_fq_np_fields_data.fqid = (u32)val;
134101 + return count;
134102 +}
134103 +
134104 +static const struct file_operations query_fq_np_fields_fops = {
134105 + .owner = THIS_MODULE,
134106 + .open = query_fq_np_fields_open,
134107 + .read = seq_read,
134108 + .write = query_fq_np_fields_write,
134109 + .release = single_release,
134110 +};
134111 +
134112 +/*******************************************************************************
134113 + * Frame Queue Programmable Fields
134114 + ******************************************************************************/
134115 +struct query_fq_fields_data_s {
134116 + u32 fqid;
134117 +};
134118 +
134119 +static struct query_fq_fields_data_s query_fq_fields_data = {
134120 + .fqid = 1,
134121 +};
134122 +
134123 +static int query_fq_fields_show(struct seq_file *file, void *offset)
134124 +{
134125 + int ret;
134126 + struct qm_fqd fqd;
134127 + struct qman_fq fq;
134128 + int i = 0;
134129 +
134130 + memset(&fqd, 0, sizeof(struct qm_fqd));
134131 + fq.fqid = query_fq_fields_data.fqid;
134132 + ret = qman_query_fq(&fq, &fqd);
134133 + if (ret)
134134 + return ret;
134135 + seq_printf(file, "Query FQ Programmable Fields Result fqid 0x%x\n",
134136 + fq.fqid);
134137 + seq_printf(file, " orprws: %u\n", fqd.orprws);
134138 + seq_printf(file, " oa: %u\n", fqd.oa);
134139 + seq_printf(file, " olws: %u\n", fqd.olws);
134140 +
134141 + seq_printf(file, " cgid: %u\n", fqd.cgid);
134142 +
134143 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) == 0)
134144 + seq_puts(file, " fq_ctrl: None\n");
134145 + else {
134146 + i = 0;
134147 + seq_puts(file, " fq_ctrl:\n");
134148 + while (fq_ctrl_text_list[i].txt != NULL) {
134149 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
134150 + fq_ctrl_text_list[i].mask)
134151 + seq_printf(file, " %s\n",
134152 + fq_ctrl_text_list[i].txt);
134153 + i++;
134154 + }
134155 + }
134156 + seq_printf(file, " dest_channel: %u\n", fqd.dest.channel);
134157 + seq_printf(file, " dest_wq: %u\n", fqd.dest.wq);
134158 + seq_printf(file, " ics_cred: %u\n", fqd.ics_cred);
134159 + seq_printf(file, " td_mant: %u\n", fqd.td.mant);
134160 + seq_printf(file, " td_exp: %u\n", fqd.td.exp);
134161 +
134162 + seq_printf(file, " ctx_b: 0x%x\n", fqd.context_b);
134163 +
134164 + seq_printf(file, " ctx_a: 0x%llx\n", qm_fqd_stashing_get64(&fqd));
134165 + /* Any stashing configured */
134166 + if ((fqd.context_a.stashing.exclusive & 0x7) == 0)
134167 + seq_puts(file, " ctx_a_stash_exclusive: None\n");
134168 + else {
134169 + seq_puts(file, " ctx_a_stash_exclusive:\n");
134170 + i = 0;
134171 + while (stashing_text_list[i].txt != NULL) {
134172 + if ((fqd.fq_ctrl & 0x7) & stashing_text_list[i].mask)
134173 + seq_printf(file, " %s\n",
134174 + stashing_text_list[i].txt);
134175 + i++;
134176 + }
134177 + }
134178 + seq_printf(file, " ctx_a_stash_annotation_cl: %u\n",
134179 + fqd.context_a.stashing.annotation_cl);
134180 + seq_printf(file, " ctx_a_stash_data_cl: %u\n",
134181 + fqd.context_a.stashing.data_cl);
134182 + seq_printf(file, " ctx_a_stash_context_cl: %u\n",
134183 + fqd.context_a.stashing.context_cl);
134184 + return 0;
134185 +}
134186 +
134187 +static int query_fq_fields_open(struct inode *inode,
134188 + struct file *file)
134189 +{
134190 + return single_open(file, query_fq_fields_show, NULL);
134191 +}
134192 +
134193 +static ssize_t query_fq_fields_write(struct file *f,
134194 + const char __user *buf, size_t count, loff_t *off)
134195 +{
134196 + int ret;
134197 + unsigned long val;
134198 +
134199 + ret = user_input_convert(buf, count, &val);
134200 + if (ret)
134201 + return ret;
134202 + if (val > MAX_FQID)
134203 + return -EINVAL;
134204 + query_fq_fields_data.fqid = (u32)val;
134205 + return count;
134206 +}
134207 +
134208 +static const struct file_operations query_fq_fields_fops = {
134209 + .owner = THIS_MODULE,
134210 + .open = query_fq_fields_open,
134211 + .read = seq_read,
134212 + .write = query_fq_fields_write,
134213 + .release = single_release,
134214 +};
134215 +
134216 +/*******************************************************************************
134217 + * Query WQ lengths
134218 + ******************************************************************************/
134219 +struct query_wq_lengths_data_s {
134220 + union {
134221 + u16 channel_wq; /* ignores wq (3 lsbits) */
134222 + struct {
134223 + u16 id:13; /* qm_channel */
134224 + u16 __reserved:3;
134225 + } __packed channel;
134226 + };
134227 +};
134228 +static struct query_wq_lengths_data_s query_wq_lengths_data;
134229 +static int query_wq_lengths_show(struct seq_file *file, void *offset)
134230 +{
134231 + int ret;
134232 + struct qm_mcr_querywq wq;
134233 + int i;
134234 +
134235 + memset(&wq, 0, sizeof(struct qm_mcr_querywq));
134236 + wq.channel.id = query_wq_lengths_data.channel.id;
134237 + ret = qman_query_wq(0, &wq);
134238 + if (ret)
134239 + return ret;
134240 + seq_printf(file, "Query Result For Channel: 0x%x\n", wq.channel.id);
134241 + for (i = 0; i < 8; i++)
134242 + /* mask out upper 4 bits since they are not part of length */
134243 + seq_printf(file, " wq%d_len : %u\n", i, wq.wq_len[i] & 0x0fff);
134244 + return 0;
134245 +}
134246 +
134247 +static int query_wq_lengths_open(struct inode *inode,
134248 + struct file *file)
134249 +{
134250 + return single_open(file, query_wq_lengths_show, NULL);
134251 +}
134252 +
134253 +static ssize_t query_wq_lengths_write(struct file *f,
134254 + const char __user *buf, size_t count, loff_t *off)
134255 +{
134256 + int ret;
134257 + unsigned long val;
134258 +
134259 + ret = user_input_convert(buf, count, &val);
134260 + if (ret)
134261 + return ret;
134262 + if (val > 0xfff8)
134263 + return -EINVAL;
134264 + query_wq_lengths_data.channel.id = (u16)val;
134265 + return count;
134266 +}
134267 +
134268 +static const struct file_operations query_wq_lengths_fops = {
134269 + .owner = THIS_MODULE,
134270 + .open = query_wq_lengths_open,
134271 + .read = seq_read,
134272 + .write = query_wq_lengths_write,
134273 + .release = single_release,
134274 +};
134275 +
134276 +/*******************************************************************************
134277 + * Query CGR
134278 + ******************************************************************************/
134279 +struct query_cgr_s {
134280 + u8 cgid;
134281 +};
134282 +static struct query_cgr_s query_cgr_data;
134283 +
134284 +static int query_cgr_show(struct seq_file *file, void *offset)
134285 +{
134286 + int ret;
134287 + struct qm_mcr_querycgr cgrd;
134288 + struct qman_cgr cgr;
134289 + int i, j;
134290 + u32 mask;
134291 +
134292 + memset(&cgr, 0, sizeof(cgr));
134293 + memset(&cgrd, 0, sizeof(cgrd));
134294 + cgr.cgrid = query_cgr_data.cgid;
134295 + ret = qman_query_cgr(&cgr, &cgrd);
134296 + if (ret)
134297 + return ret;
134298 + seq_printf(file, "Query CGR id 0x%x\n", cgr.cgrid);
134299 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134300 + cgrd.cgr.wr_parm_g.MA, cgrd.cgr.wr_parm_g.Mn,
134301 + cgrd.cgr.wr_parm_g.SA, cgrd.cgr.wr_parm_g.Sn,
134302 + cgrd.cgr.wr_parm_g.Pn);
134303 +
134304 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134305 + cgrd.cgr.wr_parm_y.MA, cgrd.cgr.wr_parm_y.Mn,
134306 + cgrd.cgr.wr_parm_y.SA, cgrd.cgr.wr_parm_y.Sn,
134307 + cgrd.cgr.wr_parm_y.Pn);
134308 +
134309 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134310 + cgrd.cgr.wr_parm_r.MA, cgrd.cgr.wr_parm_r.Mn,
134311 + cgrd.cgr.wr_parm_r.SA, cgrd.cgr.wr_parm_r.Sn,
134312 + cgrd.cgr.wr_parm_r.Pn);
134313 +
134314 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
134315 + cgrd.cgr.wr_en_g, cgrd.cgr.wr_en_y, cgrd.cgr.wr_en_r);
134316 +
134317 + seq_printf(file, " cscn_en: %u\n", cgrd.cgr.cscn_en);
134318 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
134319 + seq_puts(file, " cscn_targ_dcp:\n");
134320 + mask = 0x80000000;
134321 + for (i = 0; i < 32; i++) {
134322 + if (cgrd.cgr.cscn_targ & mask)
134323 + seq_printf(file, " send CSCN to dcp %u\n",
134324 + (31 - i));
134325 + mask >>= 1;
134326 + }
134327 +
134328 + seq_puts(file, " cscn_targ_swp:\n");
134329 + for (i = 0; i < 4; i++) {
134330 + mask = 0x80000000;
134331 + for (j = 0; j < 32; j++) {
134332 + if (cgrd.cscn_targ_swp[i] & mask)
134333 + seq_printf(file, " send CSCN to swp"
134334 + " %u\n", (127 - (i * 32) - j));
134335 + mask >>= 1;
134336 + }
134337 + }
134338 + } else {
134339 + seq_printf(file, " cscn_targ: %u\n", cgrd.cgr.cscn_targ);
134340 + }
134341 + seq_printf(file, " cstd_en: %u\n", cgrd.cgr.cstd_en);
134342 + seq_printf(file, " cs: %u\n", cgrd.cgr.cs);
134343 +
134344 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
134345 + cgrd.cgr.cs_thres.TA, cgrd.cgr.cs_thres.Tn);
134346 +
134347 + seq_printf(file, " mode: %s\n",
134348 + (cgrd.cgr.mode & QMAN_CGR_MODE_FRAME) ?
134349 + "frame count" : "byte count");
134350 + seq_printf(file, " i_bcnt: %llu\n", qm_mcr_querycgr_i_get64(&cgrd));
134351 + seq_printf(file, " a_bcnt: %llu\n", qm_mcr_querycgr_a_get64(&cgrd));
134352 +
134353 + return 0;
134354 +}
134355 +
134356 +static int query_cgr_open(struct inode *inode, struct file *file)
134357 +{
134358 + return single_open(file, query_cgr_show, NULL);
134359 +}
134360 +
134361 +static ssize_t query_cgr_write(struct file *f, const char __user *buf,
134362 + size_t count, loff_t *off)
134363 +{
134364 + int ret;
134365 + unsigned long val;
134366 +
134367 + ret = user_input_convert(buf, count, &val);
134368 + if (ret)
134369 + return ret;
134370 + if (val > 0xff)
134371 + return -EINVAL;
134372 + query_cgr_data.cgid = (u8)val;
134373 + return count;
134374 +}
134375 +
134376 +static const struct file_operations query_cgr_fops = {
134377 + .owner = THIS_MODULE,
134378 + .open = query_cgr_open,
134379 + .read = seq_read,
134380 + .write = query_cgr_write,
134381 + .release = single_release,
134382 +};
134383 +
134384 +/*******************************************************************************
134385 + * Test Write CGR
134386 + ******************************************************************************/
134387 +struct test_write_cgr_s {
134388 + u64 i_bcnt;
134389 + u8 cgid;
134390 +};
134391 +static struct test_write_cgr_s test_write_cgr_data;
134392 +
134393 +static int testwrite_cgr_show(struct seq_file *file, void *offset)
134394 +{
134395 + int ret;
134396 + struct qm_mcr_cgrtestwrite result;
134397 + struct qman_cgr cgr;
134398 + u64 i_bcnt;
134399 +
134400 + memset(&cgr, 0, sizeof(struct qman_cgr));
134401 + memset(&result, 0, sizeof(struct qm_mcr_cgrtestwrite));
134402 + cgr.cgrid = test_write_cgr_data.cgid;
134403 + i_bcnt = test_write_cgr_data.i_bcnt;
134404 + ret = qman_testwrite_cgr(&cgr, i_bcnt, &result);
134405 + if (ret)
134406 + return ret;
134407 + seq_printf(file, "CGR Test Write CGR id 0x%x\n", cgr.cgrid);
134408 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134409 + result.cgr.wr_parm_g.MA, result.cgr.wr_parm_g.Mn,
134410 + result.cgr.wr_parm_g.SA, result.cgr.wr_parm_g.Sn,
134411 + result.cgr.wr_parm_g.Pn);
134412 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134413 + result.cgr.wr_parm_y.MA, result.cgr.wr_parm_y.Mn,
134414 + result.cgr.wr_parm_y.SA, result.cgr.wr_parm_y.Sn,
134415 + result.cgr.wr_parm_y.Pn);
134416 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134417 + result.cgr.wr_parm_r.MA, result.cgr.wr_parm_r.Mn,
134418 + result.cgr.wr_parm_r.SA, result.cgr.wr_parm_r.Sn,
134419 + result.cgr.wr_parm_r.Pn);
134420 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
134421 + result.cgr.wr_en_g, result.cgr.wr_en_y, result.cgr.wr_en_r);
134422 + seq_printf(file, " cscn_en: %u\n", result.cgr.cscn_en);
134423 + seq_printf(file, " cscn_targ: %u\n", result.cgr.cscn_targ);
134424 + seq_printf(file, " cstd_en: %u\n", result.cgr.cstd_en);
134425 + seq_printf(file, " cs: %u\n", result.cgr.cs);
134426 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
134427 + result.cgr.cs_thres.TA, result.cgr.cs_thres.Tn);
134428 +
134429 + /* Add Mode for Si 2 */
134430 + seq_printf(file, " mode: %s\n",
134431 + (result.cgr.mode & QMAN_CGR_MODE_FRAME) ?
134432 + "frame count" : "byte count");
134433 +
134434 + seq_printf(file, " i_bcnt: %llu\n",
134435 + qm_mcr_cgrtestwrite_i_get64(&result));
134436 + seq_printf(file, " a_bcnt: %llu\n",
134437 + qm_mcr_cgrtestwrite_a_get64(&result));
134438 + seq_printf(file, " wr_prob_g: %u\n", result.wr_prob_g);
134439 + seq_printf(file, " wr_prob_y: %u\n", result.wr_prob_y);
134440 + seq_printf(file, " wr_prob_r: %u\n", result.wr_prob_r);
134441 + return 0;
134442 +}
134443 +
134444 +static int testwrite_cgr_open(struct inode *inode, struct file *file)
134445 +{
134446 + return single_open(file, testwrite_cgr_show, NULL);
134447 +}
134448 +
134449 +static const struct file_operations testwrite_cgr_fops = {
134450 + .owner = THIS_MODULE,
134451 + .open = testwrite_cgr_open,
134452 + .read = seq_read,
134453 + .release = single_release,
134454 +};
134455 +
134456 +
134457 +static int testwrite_cgr_ibcnt_show(struct seq_file *file, void *offset)
134458 +{
134459 + seq_printf(file, "i_bcnt: %llu\n", test_write_cgr_data.i_bcnt);
134460 + return 0;
134461 +}
134462 +static int testwrite_cgr_ibcnt_open(struct inode *inode, struct file *file)
134463 +{
134464 + return single_open(file, testwrite_cgr_ibcnt_show, NULL);
134465 +}
134466 +
134467 +static ssize_t testwrite_cgr_ibcnt_write(struct file *f, const char __user *buf,
134468 + size_t count, loff_t *off)
134469 +{
134470 + int ret;
134471 + unsigned long val;
134472 +
134473 + ret = user_input_convert(buf, count, &val);
134474 + if (ret)
134475 + return ret;
134476 + test_write_cgr_data.i_bcnt = val;
134477 + return count;
134478 +}
134479 +
134480 +static const struct file_operations teswrite_cgr_ibcnt_fops = {
134481 + .owner = THIS_MODULE,
134482 + .open = testwrite_cgr_ibcnt_open,
134483 + .read = seq_read,
134484 + .write = testwrite_cgr_ibcnt_write,
134485 + .release = single_release,
134486 +};
134487 +
134488 +static int testwrite_cgr_cgrid_show(struct seq_file *file, void *offset)
134489 +{
134490 + seq_printf(file, "cgrid: %u\n", (u32)test_write_cgr_data.cgid);
134491 + return 0;
134492 +}
134493 +static int testwrite_cgr_cgrid_open(struct inode *inode, struct file *file)
134494 +{
134495 + return single_open(file, testwrite_cgr_cgrid_show, NULL);
134496 +}
134497 +
134498 +static ssize_t testwrite_cgr_cgrid_write(struct file *f, const char __user *buf,
134499 + size_t count, loff_t *off)
134500 +{
134501 + int ret;
134502 + unsigned long val;
134503 +
134504 + ret = user_input_convert(buf, count, &val);
134505 + if (ret)
134506 + return ret;
134507 + if (val > 0xff)
134508 + return -EINVAL;
134509 + test_write_cgr_data.cgid = (u8)val;
134510 + return count;
134511 +}
134512 +
134513 +static const struct file_operations teswrite_cgr_cgrid_fops = {
134514 + .owner = THIS_MODULE,
134515 + .open = testwrite_cgr_cgrid_open,
134516 + .read = seq_read,
134517 + .write = testwrite_cgr_cgrid_write,
134518 + .release = single_release,
134519 +};
134520 +
134521 +/*******************************************************************************
134522 + * Query Congestion State
134523 + ******************************************************************************/
134524 +static int query_congestion_show(struct seq_file *file, void *offset)
134525 +{
134526 + int ret;
134527 + struct qm_mcr_querycongestion cs;
134528 + int i, j, in_cong = 0;
134529 + u32 mask;
134530 +
134531 + memset(&cs, 0, sizeof(struct qm_mcr_querycongestion));
134532 + ret = qman_query_congestion(&cs);
134533 + if (ret)
134534 + return ret;
134535 + seq_puts(file, "Query Congestion Result\n");
134536 + for (i = 0; i < 8; i++) {
134537 + mask = 0x80000000;
134538 + for (j = 0; j < 32; j++) {
134539 + if (cs.state.__state[i] & mask) {
134540 + in_cong = 1;
134541 + seq_printf(file, " cg %u: %s\n", (i*32)+j,
134542 + "in congestion");
134543 + }
134544 + mask >>= 1;
134545 + }
134546 + }
134547 + if (!in_cong)
134548 + seq_puts(file, " All congestion groups not congested.\n");
134549 + return 0;
134550 +}
134551 +
134552 +static int query_congestion_open(struct inode *inode, struct file *file)
134553 +{
134554 + return single_open(file, query_congestion_show, NULL);
134555 +}
134556 +
134557 +static const struct file_operations query_congestion_fops = {
134558 + .owner = THIS_MODULE,
134559 + .open = query_congestion_open,
134560 + .read = seq_read,
134561 + .release = single_release,
134562 +};
134563 +
134564 +/*******************************************************************************
134565 + * Query CCGR
134566 + ******************************************************************************/
134567 +struct query_ccgr_s {
134568 + u32 ccgid;
134569 +};
134570 +static struct query_ccgr_s query_ccgr_data;
134571 +
134572 +static int query_ccgr_show(struct seq_file *file, void *offset)
134573 +{
134574 + int ret;
134575 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
134576 + struct qm_mcc_ceetm_ccgr_query query_opts;
134577 + int i, j;
134578 + u32 mask;
134579 +
134580 + memset(&ccgr_query, 0, sizeof(struct qm_mcr_ceetm_ccgr_query));
134581 + memset(&query_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_query));
134582 +
134583 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
134584 + return -EINVAL;
134585 +
134586 + seq_printf(file, "Query CCGID %x\n", query_ccgr_data.ccgid);
134587 + query_opts.dcpid = ((query_ccgr_data.ccgid & 0xFF000000) >> 24);
134588 + query_opts.ccgrid = query_ccgr_data.ccgid & 0x000001FF;
134589 + ret = qman_ceetm_query_ccgr(&query_opts, &ccgr_query);
134590 + if (ret)
134591 + return ret;
134592 + seq_printf(file, "Query CCGR id %x in DCP %d\n", query_opts.ccgrid,
134593 + query_opts.dcpid);
134594 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134595 + ccgr_query.cm_query.wr_parm_g.MA,
134596 + ccgr_query.cm_query.wr_parm_g.Mn,
134597 + ccgr_query.cm_query.wr_parm_g.SA,
134598 + ccgr_query.cm_query.wr_parm_g.Sn,
134599 + ccgr_query.cm_query.wr_parm_g.Pn);
134600 +
134601 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134602 + ccgr_query.cm_query.wr_parm_y.MA,
134603 + ccgr_query.cm_query.wr_parm_y.Mn,
134604 + ccgr_query.cm_query.wr_parm_y.SA,
134605 + ccgr_query.cm_query.wr_parm_y.Sn,
134606 + ccgr_query.cm_query.wr_parm_y.Pn);
134607 +
134608 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134609 + ccgr_query.cm_query.wr_parm_r.MA,
134610 + ccgr_query.cm_query.wr_parm_r.Mn,
134611 + ccgr_query.cm_query.wr_parm_r.SA,
134612 + ccgr_query.cm_query.wr_parm_r.Sn,
134613 + ccgr_query.cm_query.wr_parm_r.Pn);
134614 +
134615 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
134616 + ccgr_query.cm_query.ctl_wr_en_g,
134617 + ccgr_query.cm_query.ctl_wr_en_y,
134618 + ccgr_query.cm_query.ctl_wr_en_r);
134619 +
134620 + seq_printf(file, " cscn_en: %u\n", ccgr_query.cm_query.ctl_cscn_en);
134621 + seq_puts(file, " cscn_targ_dcp:\n");
134622 + mask = 0x80000000;
134623 + for (i = 0; i < 32; i++) {
134624 + if (ccgr_query.cm_query.cscn_targ_dcp & mask)
134625 + seq_printf(file, " send CSCN to dcp %u\n", (31 - i));
134626 + mask >>= 1;
134627 + }
134628 +
134629 + seq_puts(file, " cscn_targ_swp:\n");
134630 + for (i = 0; i < 4; i++) {
134631 + mask = 0x80000000;
134632 + for (j = 0; j < 32; j++) {
134633 + if (ccgr_query.cm_query.cscn_targ_swp[i] & mask)
134634 + seq_printf(file, " send CSCN to swp"
134635 + "%u\n", (127 - (i * 32) - j));
134636 + mask >>= 1;
134637 + }
134638 + }
134639 +
134640 + seq_printf(file, " td_en: %u\n", ccgr_query.cm_query.ctl_td_en);
134641 +
134642 + seq_printf(file, " cs_thresh_in_TA: %u, cs_thresh_in_Tn: %u\n",
134643 + ccgr_query.cm_query.cs_thres.TA,
134644 + ccgr_query.cm_query.cs_thres.Tn);
134645 +
134646 + seq_printf(file, " cs_thresh_out_TA: %u, cs_thresh_out_Tn: %u\n",
134647 + ccgr_query.cm_query.cs_thres_x.TA,
134648 + ccgr_query.cm_query.cs_thres_x.Tn);
134649 +
134650 + seq_printf(file, " td_thresh_TA: %u, td_thresh_Tn: %u\n",
134651 + ccgr_query.cm_query.td_thres.TA,
134652 + ccgr_query.cm_query.td_thres.Tn);
134653 +
134654 + seq_printf(file, " mode: %s\n",
134655 + (ccgr_query.cm_query.ctl_mode &
134656 + QMAN_CGR_MODE_FRAME) ?
134657 + "frame count" : "byte count");
134658 + seq_printf(file, " i_cnt: %llu\n", (u64)ccgr_query.cm_query.i_cnt);
134659 + seq_printf(file, " a_cnt: %llu\n", (u64)ccgr_query.cm_query.a_cnt);
134660 +
134661 + return 0;
134662 +}
134663 +
134664 +static int query_ccgr_open(struct inode *inode, struct file *file)
134665 +{
134666 + return single_open(file, query_ccgr_show, NULL);
134667 +}
134668 +
134669 +static ssize_t query_ccgr_write(struct file *f, const char __user *buf,
134670 + size_t count, loff_t *off)
134671 +{
134672 + int ret;
134673 + unsigned long val;
134674 +
134675 + ret = user_input_convert(buf, count, &val);
134676 + if (ret)
134677 + return ret;
134678 + query_ccgr_data.ccgid = val;
134679 + return count;
134680 +}
134681 +
134682 +static const struct file_operations query_ccgr_fops = {
134683 + .owner = THIS_MODULE,
134684 + .open = query_ccgr_open,
134685 + .read = seq_read,
134686 + .write = query_ccgr_write,
134687 + .release = single_release,
134688 +};
134689 +/*******************************************************************************
134690 + * QMan register
134691 + ******************************************************************************/
134692 +struct qman_register_s {
134693 + u32 val;
134694 +};
134695 +static struct qman_register_s qman_register_data;
134696 +
134697 +static void init_ccsrmempeek(void)
134698 +{
134699 + struct device_node *dn;
134700 + const u32 *regaddr_p;
134701 +
134702 + dn = of_find_compatible_node(NULL, NULL, "fsl,qman");
134703 + if (!dn) {
134704 + pr_info("No fsl,qman node\n");
134705 + return;
134706 + }
134707 + regaddr_p = of_get_address(dn, 0, &qman_ccsr_size, NULL);
134708 + if (!regaddr_p) {
134709 + of_node_put(dn);
134710 + return;
134711 + }
134712 + qman_ccsr_start = of_translate_address(dn, regaddr_p);
134713 + of_node_put(dn);
134714 +}
134715 +/* This function provides access to QMan ccsr memory map */
134716 +static int qman_ccsrmempeek(u32 *val, u32 offset)
134717 +{
134718 + void __iomem *addr;
134719 + u64 phys_addr;
134720 +
134721 + if (!qman_ccsr_start)
134722 + return -EINVAL;
134723 +
134724 + if (offset > (qman_ccsr_size - sizeof(u32)))
134725 + return -EINVAL;
134726 +
134727 + phys_addr = qman_ccsr_start + offset;
134728 + addr = ioremap(phys_addr, sizeof(u32));
134729 + if (!addr) {
134730 + pr_err("ccsrmempeek, ioremap failed\n");
134731 + return -EINVAL;
134732 + }
134733 + *val = in_be32(addr);
134734 + iounmap(addr);
134735 + return 0;
134736 +}
134737 +
134738 +static int qman_ccsrmempeek_show(struct seq_file *file, void *offset)
134739 +{
134740 + u32 b;
134741 +
134742 + qman_ccsrmempeek(&b, qman_register_data.val);
134743 + seq_printf(file, "QMan register offset = 0x%x\n",
134744 + qman_register_data.val);
134745 + seq_printf(file, "value = 0x%08x\n", b);
134746 +
134747 + return 0;
134748 +}
134749 +
134750 +static int qman_ccsrmempeek_open(struct inode *inode, struct file *file)
134751 +{
134752 + return single_open(file, qman_ccsrmempeek_show, NULL);
134753 +}
134754 +
134755 +static ssize_t qman_ccsrmempeek_write(struct file *f, const char __user *buf,
134756 + size_t count, loff_t *off)
134757 +{
134758 + int ret;
134759 + unsigned long val;
134760 +
134761 + ret = user_input_convert(buf, count, &val);
134762 + if (ret)
134763 + return ret;
134764 + /* multiple of 4 */
134765 + if (val > (qman_ccsr_size - sizeof(u32))) {
134766 + pr_info("Input 0x%lx > 0x%llx\n",
134767 + val, (qman_ccsr_size - sizeof(u32)));
134768 + return -EINVAL;
134769 + }
134770 + if (val & 0x3) {
134771 + pr_info("Input 0x%lx not multiple of 4\n", val);
134772 + return -EINVAL;
134773 + }
134774 + qman_register_data.val = val;
134775 + return count;
134776 +}
134777 +
134778 +static const struct file_operations qman_ccsrmempeek_fops = {
134779 + .owner = THIS_MODULE,
134780 + .open = qman_ccsrmempeek_open,
134781 + .read = seq_read,
134782 + .write = qman_ccsrmempeek_write,
134783 +};
134784 +
134785 +/*******************************************************************************
134786 + * QMan state
134787 + ******************************************************************************/
134788 +static int qman_fqd_state_show(struct seq_file *file, void *offset)
134789 +{
134790 + struct qm_mcr_queryfq_np np;
134791 + struct qman_fq fq;
134792 + struct line_buffer_fq line_buf;
134793 + int ret, i;
134794 + u8 *state = file->private;
134795 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
134796 +
134797 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
134798 + memset(&line_buf, 0, sizeof(line_buf));
134799 +
134800 + seq_printf(file, "List of fq ids in state: %s\n", state_txt[*state]);
134801 +
134802 + for (i = 1; i < fqid_max; i++) {
134803 + fq.fqid = i;
134804 + ret = qman_query_fq_np(&fq, &np);
134805 + if (ret)
134806 + return ret;
134807 + if (*state == (np.state & QM_MCR_NP_STATE_MASK))
134808 + add_to_line_buffer(&line_buf, fq.fqid, file);
134809 + /* Keep a summary count of all states */
134810 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134811 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134812 + }
134813 + flush_line_buffer(&line_buf, file);
134814 +
134815 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134816 + seq_printf(file, "%s count = %u\n", state_txt[i],
134817 + qm_fq_state_cnt[i]);
134818 + }
134819 + return 0;
134820 +}
134821 +
134822 +static int qman_fqd_state_open(struct inode *inode, struct file *file)
134823 +{
134824 + return single_open(file, qman_fqd_state_show, inode->i_private);
134825 +}
134826 +
134827 +static const struct file_operations qman_fqd_state_fops = {
134828 + .owner = THIS_MODULE,
134829 + .open = qman_fqd_state_open,
134830 + .read = seq_read,
134831 +};
134832 +
134833 +static int qman_fqd_ctrl_show(struct seq_file *file, void *offset)
134834 +{
134835 + struct qm_fqd fqd;
134836 + struct qman_fq fq;
134837 + u32 fq_en_cnt = 0, fq_di_cnt = 0;
134838 + int ret, i;
134839 + struct mask_filter_s *data = file->private;
134840 + const char *ctrl_txt = get_fqd_ctrl_text(data->mask);
134841 + struct line_buffer_fq line_buf;
134842 +
134843 + memset(&line_buf, 0, sizeof(line_buf));
134844 + seq_printf(file, "List of fq ids with: %s :%s\n",
134845 + ctrl_txt, (data->filter) ? "enabled" : "disabled");
134846 + for (i = 1; i < fqid_max; i++) {
134847 + fq.fqid = i;
134848 + memset(&fqd, 0, sizeof(struct qm_fqd));
134849 + ret = qman_query_fq(&fq, &fqd);
134850 + if (ret)
134851 + return ret;
134852 + if (data->filter) {
134853 + if (fqd.fq_ctrl & data->mask)
134854 + add_to_line_buffer(&line_buf, fq.fqid, file);
134855 + } else {
134856 + if (!(fqd.fq_ctrl & data->mask))
134857 + add_to_line_buffer(&line_buf, fq.fqid, file);
134858 + }
134859 + if (fqd.fq_ctrl & data->mask)
134860 + fq_en_cnt++;
134861 + else
134862 + fq_di_cnt++;
134863 + }
134864 + flush_line_buffer(&line_buf, file);
134865 +
134866 + seq_printf(file, "Total FQD with: %s : enabled = %u\n",
134867 + ctrl_txt, fq_en_cnt);
134868 + seq_printf(file, "Total FQD with: %s : disabled = %u\n",
134869 + ctrl_txt, fq_di_cnt);
134870 + return 0;
134871 +}
134872 +
134873 +/*******************************************************************************
134874 + * QMan ctrl CGE, TDE, ORP, CTX, CPC, SFDR, BLOCK, HOLD, CACHE
134875 + ******************************************************************************/
134876 +static int qman_fqd_ctrl_open(struct inode *inode, struct file *file)
134877 +{
134878 + return single_open(file, qman_fqd_ctrl_show, inode->i_private);
134879 +}
134880 +
134881 +static const struct file_operations qman_fqd_ctrl_fops = {
134882 + .owner = THIS_MODULE,
134883 + .open = qman_fqd_ctrl_open,
134884 + .read = seq_read,
134885 +};
134886 +
134887 +/*******************************************************************************
134888 + * QMan ctrl summary
134889 + ******************************************************************************/
134890 +/*******************************************************************************
134891 + * QMan summary state
134892 + ******************************************************************************/
134893 +static int qman_fqd_non_prog_summary_show(struct seq_file *file, void *offset)
134894 +{
134895 + struct qm_mcr_queryfq_np np;
134896 + struct qman_fq fq;
134897 + int ret, i;
134898 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
134899 +
134900 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
134901 +
134902 + for (i = 1; i < fqid_max; i++) {
134903 + fq.fqid = i;
134904 + ret = qman_query_fq_np(&fq, &np);
134905 + if (ret)
134906 + return ret;
134907 + /* Keep a summary count of all states */
134908 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134909 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134910 + }
134911 +
134912 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134913 + seq_printf(file, "%s count = %u\n", state_txt[i],
134914 + qm_fq_state_cnt[i]);
134915 + }
134916 + return 0;
134917 +}
134918 +
134919 +static int qman_fqd_prog_summary_show(struct seq_file *file, void *offset)
134920 +{
134921 + struct qm_fqd fqd;
134922 + struct qman_fq fq;
134923 + int ret, i , j;
134924 + u32 qm_prog_cnt[ARRAY_SIZE(mask_filter)/2];
134925 +
134926 + memset(qm_prog_cnt, 0, sizeof(qm_prog_cnt));
134927 +
134928 + for (i = 1; i < fqid_max; i++) {
134929 + memset(&fqd, 0, sizeof(struct qm_fqd));
134930 + fq.fqid = i;
134931 + ret = qman_query_fq(&fq, &fqd);
134932 + if (ret)
134933 + return ret;
134934 + /* Keep a summary count of all states */
134935 + for (j = 0; j < ARRAY_SIZE(mask_filter); j += 2)
134936 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
134937 + mask_filter[j].mask)
134938 + qm_prog_cnt[j/2]++;
134939 + }
134940 + for (i = 0; i < ARRAY_SIZE(mask_filter) / 2; i++) {
134941 + seq_printf(file, "%s count = %u\n",
134942 + get_fqd_ctrl_text(mask_filter[i*2].mask),
134943 + qm_prog_cnt[i]);
134944 + }
134945 + return 0;
134946 +}
134947 +
134948 +static int qman_fqd_summary_show(struct seq_file *file, void *offset)
134949 +{
134950 + int ret;
134951 +
134952 + /* Display summary of non programmable fields */
134953 + ret = qman_fqd_non_prog_summary_show(file, offset);
134954 + if (ret)
134955 + return ret;
134956 + seq_puts(file, "-----------------------------------------\n");
134957 + /* Display programmable fields */
134958 + ret = qman_fqd_prog_summary_show(file, offset);
134959 + if (ret)
134960 + return ret;
134961 + return 0;
134962 +}
134963 +
134964 +static int qman_fqd_summary_open(struct inode *inode, struct file *file)
134965 +{
134966 + return single_open(file, qman_fqd_summary_show, NULL);
134967 +}
134968 +
134969 +static const struct file_operations qman_fqd_summary_fops = {
134970 + .owner = THIS_MODULE,
134971 + .open = qman_fqd_summary_open,
134972 + .read = seq_read,
134973 +};
134974 +
134975 +/*******************************************************************************
134976 + * QMan destination work queue
134977 + ******************************************************************************/
134978 +struct qman_dest_wq_s {
134979 + u16 wq_id;
134980 +};
134981 +static struct qman_dest_wq_s qman_dest_wq_data = {
134982 + .wq_id = 0,
134983 +};
134984 +
134985 +static int qman_fqd_dest_wq_show(struct seq_file *file, void *offset)
134986 +{
134987 + struct qm_fqd fqd;
134988 + struct qman_fq fq;
134989 + int ret, i;
134990 + u16 *wq, wq_id = qman_dest_wq_data.wq_id;
134991 + struct line_buffer_fq line_buf;
134992 +
134993 + memset(&line_buf, 0, sizeof(line_buf));
134994 + /* use vmalloc : need to allocate large memory region and don't
134995 + * require the memory to be physically contiguous. */
134996 + wq = vzalloc(sizeof(u16) * (0xFFFF+1));
134997 + if (!wq)
134998 + return -ENOMEM;
134999 +
135000 + seq_printf(file, "List of fq ids with destination work queue id"
135001 + " = 0x%x\n", wq_id);
135002 +
135003 + for (i = 1; i < fqid_max; i++) {
135004 + fq.fqid = i;
135005 + memset(&fqd, 0, sizeof(struct qm_fqd));
135006 + ret = qman_query_fq(&fq, &fqd);
135007 + if (ret) {
135008 + vfree(wq);
135009 + return ret;
135010 + }
135011 + if (wq_id == fqd.dest_wq)
135012 + add_to_line_buffer(&line_buf, fq.fqid, file);
135013 + wq[fqd.dest_wq]++;
135014 + }
135015 + flush_line_buffer(&line_buf, file);
135016 +
135017 + seq_puts(file, "Summary of all FQD destination work queue values\n");
135018 + for (i = 0; i < 0xFFFF; i++) {
135019 + if (wq[i])
135020 + seq_printf(file, "Channel: 0x%x WQ: 0x%x WQ_ID: 0x%x, "
135021 + "count = %u\n", i >> 3, i & 0x3, i, wq[i]);
135022 + }
135023 + vfree(wq);
135024 + return 0;
135025 +}
135026 +
135027 +static ssize_t qman_fqd_dest_wq_write(struct file *f, const char __user *buf,
135028 + size_t count, loff_t *off)
135029 +{
135030 + int ret;
135031 + unsigned long val;
135032 +
135033 + ret = user_input_convert(buf, count, &val);
135034 + if (ret)
135035 + return ret;
135036 + if (val > 0xFFFF)
135037 + return -EINVAL;
135038 + qman_dest_wq_data.wq_id = val;
135039 + return count;
135040 +}
135041 +
135042 +static int qman_fqd_dest_wq_open(struct inode *inode, struct file *file)
135043 +{
135044 + return single_open(file, qman_fqd_dest_wq_show, NULL);
135045 +}
135046 +
135047 +static const struct file_operations qman_fqd_dest_wq_fops = {
135048 + .owner = THIS_MODULE,
135049 + .open = qman_fqd_dest_wq_open,
135050 + .read = seq_read,
135051 + .write = qman_fqd_dest_wq_write,
135052 +};
135053 +
135054 +/*******************************************************************************
135055 + * QMan Intra-Class Scheduling Credit
135056 + ******************************************************************************/
135057 +static int qman_fqd_cred_show(struct seq_file *file, void *offset)
135058 +{
135059 + struct qm_fqd fqd;
135060 + struct qman_fq fq;
135061 + int ret, i;
135062 + u32 fq_cnt = 0;
135063 + struct line_buffer_fq line_buf;
135064 +
135065 + memset(&line_buf, 0, sizeof(line_buf));
135066 + seq_puts(file, "List of fq ids with Intra-Class Scheduling Credit > 0"
135067 + "\n");
135068 +
135069 + for (i = 1; i < fqid_max; i++) {
135070 + fq.fqid = i;
135071 + memset(&fqd, 0, sizeof(struct qm_fqd));
135072 + ret = qman_query_fq(&fq, &fqd);
135073 + if (ret)
135074 + return ret;
135075 + if (fqd.ics_cred > 0) {
135076 + add_to_line_buffer(&line_buf, fq.fqid, file);
135077 + fq_cnt++;
135078 + }
135079 + }
135080 + flush_line_buffer(&line_buf, file);
135081 +
135082 + seq_printf(file, "Total FQD with ics_cred > 0 = %d\n", fq_cnt);
135083 + return 0;
135084 +}
135085 +
135086 +static int qman_fqd_cred_open(struct inode *inode, struct file *file)
135087 +{
135088 + return single_open(file, qman_fqd_cred_show, NULL);
135089 +}
135090 +
135091 +static const struct file_operations qman_fqd_cred_fops = {
135092 + .owner = THIS_MODULE,
135093 + .open = qman_fqd_cred_open,
135094 + .read = seq_read,
135095 +};
135096 +
135097 +/*******************************************************************************
135098 + * Class Queue Fields
135099 + ******************************************************************************/
135100 +struct query_cq_fields_data_s {
135101 + u32 cqid;
135102 +};
135103 +
135104 +static struct query_cq_fields_data_s query_cq_fields_data = {
135105 + .cqid = 1,
135106 +};
135107 +
135108 +static int query_cq_fields_show(struct seq_file *file, void *offset)
135109 +{
135110 + int ret;
135111 + struct qm_mcr_ceetm_cq_query query_result;
135112 + unsigned int cqid;
135113 + unsigned int portal;
135114 +
135115 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
135116 + return -EINVAL;
135117 +
135118 + cqid = query_cq_fields_data.cqid & 0x00FFFFFF;
135119 + portal = query_cq_fields_data.cqid >> 24;
135120 + if (portal > qm_dc_portal_fman1)
135121 + return -EINVAL;
135122 +
135123 + ret = qman_ceetm_query_cq(cqid, portal, &query_result);
135124 + if (ret)
135125 + return ret;
135126 + seq_printf(file, "Query CQ Fields Result cqid 0x%x on DCP %d\n",
135127 + cqid, portal);
135128 + seq_printf(file, " ccgid: %u\n", query_result.ccgid);
135129 + seq_printf(file, " state: %u\n", query_result.state);
135130 + seq_printf(file, " pfdr_hptr: %u\n", query_result.pfdr_hptr);
135131 + seq_printf(file, " pfdr_tptr: %u\n", query_result.pfdr_tptr);
135132 + seq_printf(file, " od1_xsfdr: %u\n", query_result.od1_xsfdr);
135133 + seq_printf(file, " od2_xsfdr: %u\n", query_result.od2_xsfdr);
135134 + seq_printf(file, " od3_xsfdr: %u\n", query_result.od3_xsfdr);
135135 + seq_printf(file, " od4_xsfdr: %u\n", query_result.od4_xsfdr);
135136 + seq_printf(file, " od5_xsfdr: %u\n", query_result.od5_xsfdr);
135137 + seq_printf(file, " od6_xsfdr: %u\n", query_result.od6_xsfdr);
135138 + seq_printf(file, " ra1_xsfdr: %u\n", query_result.ra1_xsfdr);
135139 + seq_printf(file, " ra2_xsfdr: %u\n", query_result.ra2_xsfdr);
135140 + seq_printf(file, " frame_count: %u\n", query_result.frm_cnt);
135141 +
135142 + return 0;
135143 +}
135144 +
135145 +static int query_cq_fields_open(struct inode *inode,
135146 + struct file *file)
135147 +{
135148 + return single_open(file, query_cq_fields_show, NULL);
135149 +}
135150 +
135151 +static ssize_t query_cq_fields_write(struct file *f,
135152 + const char __user *buf, size_t count, loff_t *off)
135153 +{
135154 + int ret;
135155 + unsigned long val;
135156 +
135157 + ret = user_input_convert(buf, count, &val);
135158 + if (ret)
135159 + return ret;
135160 + query_cq_fields_data.cqid = (u32)val;
135161 + return count;
135162 +}
135163 +
135164 +static const struct file_operations query_cq_fields_fops = {
135165 + .owner = THIS_MODULE,
135166 + .open = query_cq_fields_open,
135167 + .read = seq_read,
135168 + .write = query_cq_fields_write,
135169 + .release = single_release,
135170 +};
135171 +
135172 +/*******************************************************************************
135173 + * READ CEETM_XSFDR_IN_USE
135174 + ******************************************************************************/
135175 +struct query_ceetm_xsfdr_data_s {
135176 + enum qm_dc_portal dcp_portal;
135177 +};
135178 +
135179 +static struct query_ceetm_xsfdr_data_s query_ceetm_xsfdr_data;
135180 +
135181 +static int query_ceetm_xsfdr_show(struct seq_file *file, void *offset)
135182 +{
135183 + int ret;
135184 + unsigned int xsfdr_in_use;
135185 + enum qm_dc_portal portal;
135186 +
135187 +
135188 + if (qman_ip_rev < QMAN_REV31)
135189 + return -EINVAL;
135190 +
135191 + portal = query_ceetm_xsfdr_data.dcp_portal;
135192 + ret = qman_ceetm_get_xsfdr(portal, &xsfdr_in_use);
135193 + if (ret) {
135194 + seq_printf(file, "Read CEETM_XSFDR_IN_USE on DCP %d failed\n",
135195 + portal);
135196 + return ret;
135197 + }
135198 +
135199 + seq_printf(file, "DCP%d: CEETM_XSFDR_IN_USE number is %u\n", portal,
135200 + (xsfdr_in_use & 0x1FFF));
135201 + return 0;
135202 +}
135203 +
135204 +static int query_ceetm_xsfdr_open(struct inode *inode,
135205 + struct file *file)
135206 +{
135207 + return single_open(file, query_ceetm_xsfdr_show, NULL);
135208 +}
135209 +
135210 +static ssize_t query_ceetm_xsfdr_write(struct file *f,
135211 + const char __user *buf, size_t count, loff_t *off)
135212 +{
135213 + int ret;
135214 + unsigned long val;
135215 +
135216 + ret = user_input_convert(buf, count, &val);
135217 + if (ret)
135218 + return ret;
135219 + if (val > qm_dc_portal_fman1)
135220 + return -EINVAL;
135221 + query_ceetm_xsfdr_data.dcp_portal = (u32)val;
135222 + return count;
135223 +}
135224 +
135225 +static const struct file_operations query_ceetm_xsfdr_fops = {
135226 + .owner = THIS_MODULE,
135227 + .open = query_ceetm_xsfdr_open,
135228 + .read = seq_read,
135229 + .write = query_ceetm_xsfdr_write,
135230 + .release = single_release,
135231 +};
135232 +
135233 +/* helper macros used in qman_debugfs_module_init */
135234 +#define QMAN_DBGFS_ENTRY(name, mode, parent, data, fops) \
135235 + do { \
135236 + d = debugfs_create_file(name, \
135237 + mode, parent, \
135238 + data, \
135239 + fops); \
135240 + if (d == NULL) { \
135241 + ret = -ENOMEM; \
135242 + goto _return; \
135243 + } \
135244 + } while (0)
135245 +
135246 +/* dfs_root as parent */
135247 +#define QMAN_DBGFS_ENTRY_ROOT(name, mode, data, fops) \
135248 + QMAN_DBGFS_ENTRY(name, mode, dfs_root, data, fops)
135249 +
135250 +/* fqd_root as parent */
135251 +#define QMAN_DBGFS_ENTRY_FQDROOT(name, mode, data, fops) \
135252 + QMAN_DBGFS_ENTRY(name, mode, fqd_root, data, fops)
135253 +
135254 +/* fqd state */
135255 +#define QMAN_DBGFS_ENTRY_FQDSTATE(name, index) \
135256 + QMAN_DBGFS_ENTRY_FQDROOT(name, S_IRUGO, \
135257 + (void *)&mask_filter[index], &qman_fqd_ctrl_fops)
135258 +
135259 +static int __init qman_debugfs_module_init(void)
135260 +{
135261 + int ret = 0;
135262 + struct dentry *d, *fqd_root;
135263 + u32 reg;
135264 +
135265 + fqid_max = 0;
135266 + init_ccsrmempeek();
135267 + if (qman_ccsr_start) {
135268 + if (!qman_ccsrmempeek(&reg, QM_FQD_AR)) {
135269 + /* extract the size of the FQD window */
135270 + reg = reg & 0x3f;
135271 + /* calculate valid frame queue descriptor range */
135272 + fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE;
135273 + }
135274 + }
135275 + dfs_root = debugfs_create_dir("qman", NULL);
135276 + fqd_root = debugfs_create_dir("fqd", dfs_root);
135277 + if (dfs_root == NULL || fqd_root == NULL) {
135278 + ret = -ENOMEM;
135279 + pr_err("Cannot create qman/fqd debugfs dir\n");
135280 + goto _return;
135281 + }
135282 + if (fqid_max) {
135283 + QMAN_DBGFS_ENTRY_ROOT("ccsrmempeek", S_IRUGO | S_IWUGO,
135284 + NULL, &qman_ccsrmempeek_fops);
135285 + }
135286 + QMAN_DBGFS_ENTRY_ROOT("query_fq_np_fields", S_IRUGO | S_IWUGO,
135287 + &query_fq_np_fields_data, &query_fq_np_fields_fops);
135288 +
135289 + QMAN_DBGFS_ENTRY_ROOT("query_fq_fields", S_IRUGO | S_IWUGO,
135290 + &query_fq_fields_data, &query_fq_fields_fops);
135291 +
135292 + QMAN_DBGFS_ENTRY_ROOT("query_wq_lengths", S_IRUGO | S_IWUGO,
135293 + &query_wq_lengths_data, &query_wq_lengths_fops);
135294 +
135295 + QMAN_DBGFS_ENTRY_ROOT("query_cgr", S_IRUGO | S_IWUGO,
135296 + &query_cgr_data, &query_cgr_fops);
135297 +
135298 + QMAN_DBGFS_ENTRY_ROOT("query_congestion", S_IRUGO,
135299 + NULL, &query_congestion_fops);
135300 +
135301 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr", S_IRUGO,
135302 + NULL, &testwrite_cgr_fops);
135303 +
135304 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_cgrid", S_IRUGO | S_IWUGO,
135305 + NULL, &teswrite_cgr_cgrid_fops);
135306 +
135307 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_ibcnt", S_IRUGO | S_IWUGO,
135308 + NULL, &teswrite_cgr_ibcnt_fops);
135309 +
135310 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_ccgr", S_IRUGO | S_IWUGO,
135311 + &query_ccgr_data, &query_ccgr_fops);
135312 + /* Create files with fqd_root as parent */
135313 +
135314 + QMAN_DBGFS_ENTRY_FQDROOT("stateoos", S_IRUGO,
135315 + (void *)&fqd_states[QM_MCR_NP_STATE_OOS], &qman_fqd_state_fops);
135316 +
135317 + QMAN_DBGFS_ENTRY_FQDROOT("state_retired", S_IRUGO,
135318 + (void *)&fqd_states[QM_MCR_NP_STATE_RETIRED],
135319 + &qman_fqd_state_fops);
135320 +
135321 + QMAN_DBGFS_ENTRY_FQDROOT("state_tentatively_sched", S_IRUGO,
135322 + (void *)&fqd_states[QM_MCR_NP_STATE_TEN_SCHED],
135323 + &qman_fqd_state_fops);
135324 +
135325 + QMAN_DBGFS_ENTRY_FQDROOT("state_truly_sched", S_IRUGO,
135326 + (void *)&fqd_states[QM_MCR_NP_STATE_TRU_SCHED],
135327 + &qman_fqd_state_fops);
135328 +
135329 + QMAN_DBGFS_ENTRY_FQDROOT("state_parked", S_IRUGO,
135330 + (void *)&fqd_states[QM_MCR_NP_STATE_PARKED],
135331 + &qman_fqd_state_fops);
135332 +
135333 + QMAN_DBGFS_ENTRY_FQDROOT("state_active", S_IRUGO,
135334 + (void *)&fqd_states[QM_MCR_NP_STATE_ACTIVE],
135335 + &qman_fqd_state_fops);
135336 + QMAN_DBGFS_ENTRY_ROOT("query_cq_fields", S_IRUGO | S_IWUGO,
135337 + &query_cq_fields_data, &query_cq_fields_fops);
135338 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_xsfdr_in_use", S_IRUGO | S_IWUGO,
135339 + &query_ceetm_xsfdr_data, &query_ceetm_xsfdr_fops);
135340 +
135341 +
135342 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_enable", 17);
135343 +
135344 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_disable", 16);
135345 +
135346 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_enable", 15);
135347 +
135348 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_disable", 14);
135349 +
135350 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_enable", 13);
135351 +
135352 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_disable", 12);
135353 +
135354 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_enable", 11);
135355 +
135356 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_disable", 10);
135357 +
135358 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_enable", 9);
135359 +
135360 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_disable", 8);
135361 +
135362 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_enable", 7);
135363 +
135364 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_disable", 6);
135365 +
135366 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_enable", 5);
135367 +
135368 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_disable", 4);
135369 +
135370 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_enable", 3);
135371 +
135372 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_disable", 2);
135373 +
135374 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_enable", 1);
135375 +
135376 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_disable", 0);
135377 +
135378 + QMAN_DBGFS_ENTRY_FQDROOT("summary", S_IRUGO,
135379 + NULL, &qman_fqd_summary_fops);
135380 +
135381 + QMAN_DBGFS_ENTRY_FQDROOT("wq", S_IRUGO | S_IWUGO,
135382 + NULL, &qman_fqd_dest_wq_fops);
135383 +
135384 + QMAN_DBGFS_ENTRY_FQDROOT("cred", S_IRUGO,
135385 + NULL, &qman_fqd_cred_fops);
135386 +
135387 + return 0;
135388 +
135389 +_return:
135390 + debugfs_remove_recursive(dfs_root);
135391 + return ret;
135392 +}
135393 +
135394 +static void __exit qman_debugfs_module_exit(void)
135395 +{
135396 + debugfs_remove_recursive(dfs_root);
135397 +}
135398 +
135399 +module_init(qman_debugfs_module_init);
135400 +module_exit(qman_debugfs_module_exit);
135401 +MODULE_LICENSE("Dual BSD/GPL");
135402 diff --git a/drivers/staging/fsl_qbman/qman_driver.c b/drivers/staging/fsl_qbman/qman_driver.c
135403 new file mode 100644
135404 index 00000000..857ecd62
135405 --- /dev/null
135406 +++ b/drivers/staging/fsl_qbman/qman_driver.c
135407 @@ -0,0 +1,977 @@
135408 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
135409 + *
135410 + * Redistribution and use in source and binary forms, with or without
135411 + * modification, are permitted provided that the following conditions are met:
135412 + * * Redistributions of source code must retain the above copyright
135413 + * notice, this list of conditions and the following disclaimer.
135414 + * * Redistributions in binary form must reproduce the above copyright
135415 + * notice, this list of conditions and the following disclaimer in the
135416 + * documentation and/or other materials provided with the distribution.
135417 + * * Neither the name of Freescale Semiconductor nor the
135418 + * names of its contributors may be used to endorse or promote products
135419 + * derived from this software without specific prior written permission.
135420 + *
135421 + *
135422 + * ALTERNATIVELY, this software may be distributed under the terms of the
135423 + * GNU General Public License ("GPL") as published by the Free Software
135424 + * Foundation, either version 2 of that License or (at your option) any
135425 + * later version.
135426 + *
135427 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
135428 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
135429 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
135430 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
135431 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
135432 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
135433 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
135434 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
135435 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
135436 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135437 + */
135438 +
135439 +#include "qman_private.h"
135440 +
135441 +#include <asm/smp.h> /* hard_smp_processor_id() if !CONFIG_SMP */
135442 +#ifdef CONFIG_HOTPLUG_CPU
135443 +#include <linux/cpu.h>
135444 +#endif
135445 +
135446 +/* Global variable containing revision id (even on non-control plane systems
135447 + * where CCSR isn't available) */
135448 +u16 qman_ip_rev;
135449 +EXPORT_SYMBOL(qman_ip_rev);
135450 +u8 qman_ip_cfg;
135451 +EXPORT_SYMBOL(qman_ip_cfg);
135452 +u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
135453 +EXPORT_SYMBOL(qm_channel_pool1);
135454 +u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
135455 +EXPORT_SYMBOL(qm_channel_caam);
135456 +u16 qm_channel_pme = QMAN_CHANNEL_PME;
135457 +EXPORT_SYMBOL(qm_channel_pme);
135458 +u16 qm_channel_dce = QMAN_CHANNEL_DCE;
135459 +EXPORT_SYMBOL(qm_channel_dce);
135460 +u16 qman_portal_max;
135461 +EXPORT_SYMBOL(qman_portal_max);
135462 +
135463 +u32 qman_clk;
135464 +struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
135465 +/* the qman ceetm instances on the given SoC */
135466 +u8 num_ceetms;
135467 +
135468 +/* For these variables, and the portal-initialisation logic, the
135469 + * comments in bman_driver.c apply here so won't be repeated. */
135470 +static struct qman_portal *shared_portals[NR_CPUS];
135471 +static int num_shared_portals;
135472 +static int shared_portals_idx;
135473 +static LIST_HEAD(unused_pcfgs);
135474 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
135475 +
135476 +/* A SDQCR mask comprising all the available/visible pool channels */
135477 +static u32 pools_sdqcr;
135478 +
135479 +#define STR_ERR_NOPROP "No '%s' property in node %s\n"
135480 +#define STR_ERR_CELL "'%s' is not a %d-cell range in node %s\n"
135481 +#define STR_FQID_RANGE "fsl,fqid-range"
135482 +#define STR_POOL_CHAN_RANGE "fsl,pool-channel-range"
135483 +#define STR_CGRID_RANGE "fsl,cgrid-range"
135484 +
135485 +/* A "fsl,fqid-range" node; release the given range to the allocator */
135486 +static __init int fsl_fqid_range_init(struct device_node *node)
135487 +{
135488 + int ret;
135489 + const u32 *range = of_get_property(node, STR_FQID_RANGE, &ret);
135490 + if (!range) {
135491 + pr_err(STR_ERR_NOPROP, STR_FQID_RANGE, node->full_name);
135492 + return -EINVAL;
135493 + }
135494 + if (ret != 8) {
135495 + pr_err(STR_ERR_CELL, STR_FQID_RANGE, 2, node->full_name);
135496 + return -EINVAL;
135497 + }
135498 + qman_seed_fqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135499 + pr_info("Qman: FQID allocator includes range %d:%d\n",
135500 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135501 + return 0;
135502 +}
135503 +
135504 +/* A "fsl,pool-channel-range" node; add to the SDQCR mask only */
135505 +static __init int fsl_pool_channel_range_sdqcr(struct device_node *node)
135506 +{
135507 + int ret;
135508 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
135509 + if (!chanid) {
135510 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
135511 + return -EINVAL;
135512 + }
135513 + if (ret != 8) {
135514 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
135515 + return -EINVAL;
135516 + }
135517 + for (ret = 0; ret < be32_to_cpu(chanid[1]); ret++)
135518 + pools_sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(be32_to_cpu(chanid[0]) + ret);
135519 + return 0;
135520 +}
135521 +
135522 +/* A "fsl,pool-channel-range" node; release the given range to the allocator */
135523 +static __init int fsl_pool_channel_range_init(struct device_node *node)
135524 +{
135525 + int ret;
135526 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
135527 + if (!chanid) {
135528 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
135529 + return -EINVAL;
135530 + }
135531 + if (ret != 8) {
135532 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
135533 + return -EINVAL;
135534 + }
135535 + qman_seed_pool_range(be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
135536 + pr_info("Qman: pool channel allocator includes range %d:%d\n",
135537 + be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
135538 + return 0;
135539 +}
135540 +
135541 +/* A "fsl,cgrid-range" node; release the given range to the allocator */
135542 +static __init int fsl_cgrid_range_init(struct device_node *node)
135543 +{
135544 + struct qman_cgr cgr;
135545 + int ret, errors = 0;
135546 + const u32 *range = of_get_property(node, STR_CGRID_RANGE, &ret);
135547 + if (!range) {
135548 + pr_err(STR_ERR_NOPROP, STR_CGRID_RANGE, node->full_name);
135549 + return -EINVAL;
135550 + }
135551 + if (ret != 8) {
135552 + pr_err(STR_ERR_CELL, STR_CGRID_RANGE, 2, node->full_name);
135553 + return -EINVAL;
135554 + }
135555 + qman_seed_cgrid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135556 + pr_info("Qman: CGRID allocator includes range %d:%d\n",
135557 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135558 + for (cgr.cgrid = 0; cgr.cgrid < __CGR_NUM; cgr.cgrid++) {
135559 + ret = qman_modify_cgr(&cgr, QMAN_CGR_FLAG_USE_INIT, NULL);
135560 + if (ret)
135561 + errors++;
135562 + }
135563 + if (errors)
135564 + pr_err("Warning: %d error%s while initialising CGRs %d:%d\n",
135565 + errors, (errors > 1) ? "s" : "", range[0], range[1]);
135566 + return 0;
135567 +}
135568 +
135569 +static __init int fsl_ceetm_init(struct device_node *node)
135570 +{
135571 + enum qm_dc_portal dcp_portal;
135572 + struct qm_ceetm_sp *sp;
135573 + struct qm_ceetm_lni *lni;
135574 + int ret, i;
135575 + const u32 *range;
135576 +
135577 + /* Find LFQID range */
135578 + range = of_get_property(node, "fsl,ceetm-lfqid-range", &ret);
135579 + if (!range) {
135580 + pr_err("No fsl,ceetm-lfqid-range in node %s\n",
135581 + node->full_name);
135582 + return -EINVAL;
135583 + }
135584 + if (ret != 8) {
135585 + pr_err("fsl,ceetm-lfqid-range is not a 2-cell range in node"
135586 + " %s\n", node->full_name);
135587 + return -EINVAL;
135588 + }
135589 +
135590 + dcp_portal = (be32_to_cpu(range[0]) & 0x0F0000) >> 16;
135591 + if (dcp_portal > qm_dc_portal_fman1) {
135592 + pr_err("The DCP portal %d doesn't support CEETM\n", dcp_portal);
135593 + return -EINVAL;
135594 + }
135595 +
135596 + if (dcp_portal == qm_dc_portal_fman0)
135597 + qman_seed_ceetm0_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135598 + if (dcp_portal == qm_dc_portal_fman1)
135599 + qman_seed_ceetm1_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135600 + pr_debug("Qman: The lfqid allocator of CEETM %d includes range"
135601 + " 0x%x:0x%x\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135602 +
135603 + qman_ceetms[dcp_portal].idx = dcp_portal;
135604 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].sub_portals);
135605 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].lnis);
135606 +
135607 + /* Find Sub-portal range */
135608 + range = of_get_property(node, "fsl,ceetm-sp-range", &ret);
135609 + if (!range) {
135610 + pr_err("No fsl,ceetm-sp-range in node %s\n", node->full_name);
135611 + return -EINVAL;
135612 + }
135613 + if (ret != 8) {
135614 + pr_err("fsl,ceetm-sp-range is not a 2-cell range in node %s\n",
135615 + node->full_name);
135616 + return -EINVAL;
135617 + }
135618 +
135619 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
135620 + sp = kzalloc(sizeof(*sp), GFP_KERNEL);
135621 + if (!sp) {
135622 + pr_err("Can't alloc memory for sub-portal %d\n",
135623 + range[0] + i);
135624 + return -ENOMEM;
135625 + }
135626 + sp->idx = be32_to_cpu(range[0]) + i;
135627 + sp->dcp_idx = dcp_portal;
135628 + sp->is_claimed = 0;
135629 + list_add_tail(&sp->node, &qman_ceetms[dcp_portal].sub_portals);
135630 + sp++;
135631 + }
135632 + pr_debug("Qman: Reserve sub-portal %d:%d for CEETM %d\n",
135633 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
135634 + qman_ceetms[dcp_portal].sp_range[0] = be32_to_cpu(range[0]);
135635 + qman_ceetms[dcp_portal].sp_range[1] = be32_to_cpu(range[1]);
135636 +
135637 + /* Find LNI range */
135638 + range = of_get_property(node, "fsl,ceetm-lni-range", &ret);
135639 + if (!range) {
135640 + pr_err("No fsl,ceetm-lni-range in node %s\n", node->full_name);
135641 + return -EINVAL;
135642 + }
135643 + if (ret != 8) {
135644 + pr_err("fsl,ceetm-lni-range is not a 2-cell range in node %s\n",
135645 + node->full_name);
135646 + return -EINVAL;
135647 + }
135648 +
135649 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
135650 + lni = kzalloc(sizeof(*lni), GFP_KERNEL);
135651 + if (!lni) {
135652 + pr_err("Can't alloc memory for LNI %d\n",
135653 + range[0] + i);
135654 + return -ENOMEM;
135655 + }
135656 + lni->idx = be32_to_cpu(range[0]) + i;
135657 + lni->dcp_idx = dcp_portal;
135658 + lni->is_claimed = 0;
135659 + INIT_LIST_HEAD(&lni->channels);
135660 + list_add_tail(&lni->node, &qman_ceetms[dcp_portal].lnis);
135661 + lni++;
135662 + }
135663 + pr_debug("Qman: Reserve LNI %d:%d for CEETM %d\n",
135664 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
135665 + qman_ceetms[dcp_portal].lni_range[0] = be32_to_cpu(range[0]);
135666 + qman_ceetms[dcp_portal].lni_range[1] = be32_to_cpu(range[1]);
135667 +
135668 + /* Find CEETM channel range */
135669 + range = of_get_property(node, "fsl,ceetm-channel-range", &ret);
135670 + if (!range) {
135671 + pr_err("No fsl,ceetm-channel-range in node %s\n",
135672 + node->full_name);
135673 + return -EINVAL;
135674 + }
135675 + if (ret != 8) {
135676 + pr_err("fsl,ceetm-channel-range is not a 2-cell range in node"
135677 + "%s\n", node->full_name);
135678 + return -EINVAL;
135679 + }
135680 +
135681 + if (dcp_portal == qm_dc_portal_fman0)
135682 + qman_seed_ceetm0_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135683 + if (dcp_portal == qm_dc_portal_fman1)
135684 + qman_seed_ceetm1_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135685 + pr_debug("Qman: The channel allocator of CEETM %d includes"
135686 + " range %d:%d\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135687 +
135688 + /* Set CEETM PRES register */
135689 + ret = qman_ceetm_set_prescaler(dcp_portal);
135690 + if (ret)
135691 + return ret;
135692 + return 0;
135693 +}
135694 +
135695 +static void qman_get_ip_revision(struct device_node *dn)
135696 +{
135697 + u16 ip_rev = 0;
135698 + u8 ip_cfg = QMAN_REV_CFG_0;
135699 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
135700 + if (!of_device_is_available(dn))
135701 + continue;
135702 + if (of_device_is_compatible(dn, "fsl,qman-portal-1.0") ||
135703 + of_device_is_compatible(dn, "fsl,qman-portal-1.0.0")) {
135704 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
135705 + BUG_ON(1);
135706 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.1") ||
135707 + of_device_is_compatible(dn, "fsl,qman-portal-1.1.0")) {
135708 + ip_rev = QMAN_REV11;
135709 + qman_portal_max = 10;
135710 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.2") ||
135711 + of_device_is_compatible(dn, "fsl,qman-portal-1.2.0")) {
135712 + ip_rev = QMAN_REV12;
135713 + qman_portal_max = 10;
135714 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-2.0") ||
135715 + of_device_is_compatible(dn, "fsl,qman-portal-2.0.0")) {
135716 + ip_rev = QMAN_REV20;
135717 + qman_portal_max = 3;
135718 + } else if (of_device_is_compatible(dn,
135719 + "fsl,qman-portal-3.0.0")) {
135720 + ip_rev = QMAN_REV30;
135721 + qman_portal_max = 50;
135722 + } else if (of_device_is_compatible(dn,
135723 + "fsl,qman-portal-3.0.1")) {
135724 + ip_rev = QMAN_REV30;
135725 + qman_portal_max = 25;
135726 + ip_cfg = QMAN_REV_CFG_1;
135727 + } else if (of_device_is_compatible(dn,
135728 + "fsl,qman-portal-3.1.0")) {
135729 + ip_rev = QMAN_REV31;
135730 + qman_portal_max = 50;
135731 + } else if (of_device_is_compatible(dn,
135732 + "fsl,qman-portal-3.1.1")) {
135733 + ip_rev = QMAN_REV31;
135734 + qman_portal_max = 25;
135735 + ip_cfg = QMAN_REV_CFG_1;
135736 + } else if (of_device_is_compatible(dn,
135737 + "fsl,qman-portal-3.1.2")) {
135738 + ip_rev = QMAN_REV31;
135739 + qman_portal_max = 18;
135740 + ip_cfg = QMAN_REV_CFG_2;
135741 + } else if (of_device_is_compatible(dn,
135742 + "fsl,qman-portal-3.1.3")) {
135743 + ip_rev = QMAN_REV31;
135744 + qman_portal_max = 10;
135745 + ip_cfg = QMAN_REV_CFG_3;
135746 + } else if (of_device_is_compatible(dn,
135747 + "fsl,qman-portal-3.2.0")) {
135748 + ip_rev = QMAN_REV32;
135749 + qman_portal_max = 10;
135750 + ip_cfg = QMAN_REV_CFG_3; // TODO: Verify for ls1043
135751 + } else if (of_device_is_compatible(dn,
135752 + "fsl,qman-portal-3.2.1")) {
135753 + ip_rev = QMAN_REV32;
135754 + qman_portal_max = 10;
135755 + ip_cfg = QMAN_REV_CFG_3;
135756 + } else {
135757 + pr_warn("unknown QMan version in portal node,"
135758 + "default to rev1.1\n");
135759 + ip_rev = QMAN_REV11;
135760 + qman_portal_max = 10;
135761 + }
135762 +
135763 + if (!qman_ip_rev) {
135764 + if (ip_rev) {
135765 + qman_ip_rev = ip_rev;
135766 + qman_ip_cfg = ip_cfg;
135767 + } else {
135768 + pr_warn("unknown Qman version,"
135769 + " default to rev1.1\n");
135770 + qman_ip_rev = QMAN_REV11;
135771 + qman_ip_cfg = QMAN_REV_CFG_0;
135772 + }
135773 + } else if (ip_rev && (qman_ip_rev != ip_rev))
135774 + pr_warn("Revision=0x%04x, but portal '%s' has"
135775 + " 0x%04x\n",
135776 + qman_ip_rev, dn->full_name, ip_rev);
135777 + if (qman_ip_rev == ip_rev)
135778 + break;
135779 + }
135780 +}
135781 +
135782 +/* Parse a portal node, perform generic mapping duties and return the config. It
135783 + * is not known at this stage for what purpose (or even if) the portal will be
135784 + * used. */
135785 +static struct qm_portal_config * __init parse_pcfg(struct device_node *node)
135786 +{
135787 + struct qm_portal_config *pcfg;
135788 + const u32 *index_p;
135789 + u32 index, channel;
135790 + int irq, ret;
135791 + resource_size_t len;
135792 +
135793 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
135794 + if (!pcfg) {
135795 + pr_err("can't allocate portal config");
135796 + return NULL;
135797 + }
135798 +
135799 + /*
135800 + * This is a *horrible hack*, but the IOMMU/PAMU driver needs a
135801 + * 'struct device' in order to get the PAMU stashing setup and the QMan
135802 + * portal [driver] won't function at all without ring stashing
135803 + *
135804 + * Making the QMan portal driver nice and proper is part of the
135805 + * upstreaming effort
135806 + */
135807 + pcfg->dev.bus = &platform_bus_type;
135808 + pcfg->dev.of_node = node;
135809 +#ifdef CONFIG_FSL_PAMU
135810 + pcfg->dev.archdata.iommu_domain = NULL;
135811 +#endif
135812 +
135813 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
135814 + &pcfg->addr_phys[DPA_PORTAL_CE]);
135815 + if (ret) {
135816 + pr_err("Can't get %s property '%s'\n", node->full_name,
135817 + "reg::CE");
135818 + goto err;
135819 + }
135820 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
135821 + &pcfg->addr_phys[DPA_PORTAL_CI]);
135822 + if (ret) {
135823 + pr_err("Can't get %s property '%s'\n", node->full_name,
135824 + "reg::CI");
135825 + goto err;
135826 + }
135827 + index_p = of_get_property(node, "cell-index", &ret);
135828 + if (!index_p || (ret != 4)) {
135829 + pr_err("Can't get %s property '%s'\n", node->full_name,
135830 + "cell-index");
135831 + goto err;
135832 + }
135833 + index = be32_to_cpu(*index_p);
135834 + if (index >= qman_portal_max) {
135835 + pr_err("QMan portal index %d is beyond max (%d)\n",
135836 + index, qman_portal_max);
135837 + goto err;
135838 + }
135839 +
135840 + channel = index + QM_CHANNEL_SWPORTAL0;
135841 + pcfg->public_cfg.channel = channel;
135842 + pcfg->public_cfg.cpu = -1;
135843 + irq = irq_of_parse_and_map(node, 0);
135844 + if (irq == 0) {
135845 + pr_err("Can't get %s property '%s'\n", node->full_name,
135846 + "interrupts");
135847 + goto err;
135848 + }
135849 + pcfg->public_cfg.irq = irq;
135850 + pcfg->public_cfg.index = index;
135851 +#ifdef CONFIG_FSL_QMAN_CONFIG
135852 + /* We need the same LIODN offset for all portals */
135853 + qman_liodn_fixup(pcfg->public_cfg.channel);
135854 +#endif
135855 +
135856 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
135857 + if (len != (unsigned long)len)
135858 + goto err;
135859 +
135860 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
135861 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
135862 + pcfg->addr_phys[DPA_PORTAL_CE].start,
135863 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
135864 +
135865 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
135866 + pcfg->addr_phys[DPA_PORTAL_CI].start,
135867 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
135868 +#else
135869 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
135870 + pcfg->addr_phys[DPA_PORTAL_CE].start,
135871 + (unsigned long)len,
135872 + 0);
135873 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
135874 + pcfg->addr_phys[DPA_PORTAL_CI].start,
135875 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
135876 + _PAGE_GUARDED | _PAGE_NO_CACHE);
135877 +#endif
135878 + return pcfg;
135879 +err:
135880 + kfree(pcfg);
135881 + return NULL;
135882 +}
135883 +
135884 +static struct qm_portal_config *get_pcfg(struct list_head *list)
135885 +{
135886 + struct qm_portal_config *pcfg;
135887 + if (list_empty(list))
135888 + return NULL;
135889 + pcfg = list_entry(list->prev, struct qm_portal_config, list);
135890 + list_del(&pcfg->list);
135891 + return pcfg;
135892 +}
135893 +
135894 +static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx)
135895 +{
135896 + struct qm_portal_config *pcfg;
135897 + if (list_empty(list))
135898 + return NULL;
135899 + list_for_each_entry(pcfg, list, list) {
135900 + if (pcfg->public_cfg.index == idx) {
135901 + list_del(&pcfg->list);
135902 + return pcfg;
135903 + }
135904 + }
135905 + return NULL;
135906 +}
135907 +
135908 +static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
135909 +{
135910 +#ifdef CONFIG_FSL_PAMU
135911 + int ret;
135912 + int window_count = 1;
135913 + struct iommu_domain_geometry geom_attr;
135914 + struct pamu_stash_attribute stash_attr;
135915 +
135916 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
135917 + if (!pcfg->iommu_domain) {
135918 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
135919 + __func__);
135920 + goto _no_iommu;
135921 + }
135922 + geom_attr.aperture_start = 0;
135923 + geom_attr.aperture_end =
135924 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
135925 + geom_attr.force_aperture = true;
135926 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
135927 + &geom_attr);
135928 + if (ret < 0) {
135929 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135930 + __func__, ret);
135931 + goto _iommu_domain_free;
135932 + }
135933 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
135934 + &window_count);
135935 + if (ret < 0) {
135936 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135937 + __func__, ret);
135938 + goto _iommu_domain_free;
135939 + }
135940 + stash_attr.cpu = cpu;
135941 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135942 + /* set stash information for the window */
135943 + stash_attr.window = 0;
135944 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135945 + DOMAIN_ATTR_FSL_PAMU_STASH,
135946 + &stash_attr);
135947 + if (ret < 0) {
135948 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135949 + __func__, ret);
135950 + goto _iommu_domain_free;
135951 + }
135952 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
135953 + IOMMU_READ | IOMMU_WRITE);
135954 + if (ret < 0) {
135955 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
135956 + __func__, ret);
135957 + goto _iommu_domain_free;
135958 + }
135959 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
135960 + if (ret < 0) {
135961 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
135962 + __func__, ret);
135963 + goto _iommu_domain_free;
135964 + }
135965 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135966 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
135967 + &window_count);
135968 + if (ret < 0) {
135969 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135970 + __func__, ret);
135971 + goto _iommu_detach_device;
135972 + }
135973 +
135974 +_no_iommu:
135975 +#endif
135976 +#ifdef CONFIG_FSL_QMAN_CONFIG
135977 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135978 +#endif
135979 + pr_warn("Failed to set QMan portal's stash request queue\n");
135980 +
135981 + return;
135982 +
135983 +#ifdef CONFIG_FSL_PAMU
135984 +_iommu_detach_device:
135985 + iommu_detach_device(pcfg->iommu_domain, NULL);
135986 +_iommu_domain_free:
135987 + iommu_domain_free(pcfg->iommu_domain);
135988 +#endif
135989 +}
135990 +
135991 +struct qm_portal_config *qm_get_unused_portal_idx(u32 idx)
135992 +{
135993 + struct qm_portal_config *ret;
135994 + spin_lock(&unused_pcfgs_lock);
135995 + if (idx == QBMAN_ANY_PORTAL_IDX)
135996 + ret = get_pcfg(&unused_pcfgs);
135997 + else
135998 + ret = get_pcfg_idx(&unused_pcfgs, idx);
135999 + spin_unlock(&unused_pcfgs_lock);
136000 + /* Bind stashing LIODNs to the CPU we are currently executing on, and
136001 + * set the portal to use the stashing request queue corresonding to the
136002 + * cpu as well. The user-space driver assumption is that the pthread has
136003 + * to already be affine to one cpu only before opening a portal. If that
136004 + * check is circumvented, the only risk is a performance degradation -
136005 + * stashing will go to whatever cpu they happened to be running on when
136006 + * opening the device file, and if that isn't the cpu they subsequently
136007 + * bind to and do their polling on, tough. */
136008 + if (ret)
136009 + portal_set_cpu(ret, hard_smp_processor_id());
136010 + return ret;
136011 +}
136012 +
136013 +struct qm_portal_config *qm_get_unused_portal(void)
136014 +{
136015 + return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
136016 +}
136017 +
136018 +void qm_put_unused_portal(struct qm_portal_config *pcfg)
136019 +{
136020 + spin_lock(&unused_pcfgs_lock);
136021 + list_add(&pcfg->list, &unused_pcfgs);
136022 + spin_unlock(&unused_pcfgs_lock);
136023 +}
136024 +
136025 +static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg)
136026 +{
136027 + struct qman_portal *p;
136028 +
136029 + pcfg->iommu_domain = NULL;
136030 + portal_set_cpu(pcfg, pcfg->public_cfg.cpu);
136031 + p = qman_create_affine_portal(pcfg, NULL);
136032 + if (p) {
136033 + u32 irq_sources = 0;
136034 + /* Determine what should be interrupt-vs-poll driven */
136035 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
136036 + irq_sources |= QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI |
136037 + QM_PIRQ_CSCI | QM_PIRQ_CCSCI;
136038 +#endif
136039 +#ifdef CONFIG_FSL_DPA_PIRQ_FAST
136040 + irq_sources |= QM_PIRQ_DQRI;
136041 +#endif
136042 + qman_p_irqsource_add(p, irq_sources);
136043 + pr_info("Qman portal %sinitialised, cpu %d\n",
136044 + pcfg->public_cfg.is_shared ? "(shared) " : "",
136045 + pcfg->public_cfg.cpu);
136046 + } else
136047 + pr_crit("Qman portal failure on cpu %d\n",
136048 + pcfg->public_cfg.cpu);
136049 + return p;
136050 +}
136051 +
136052 +static void init_slave(int cpu)
136053 +{
136054 + struct qman_portal *p;
136055 + struct cpumask oldmask = current->cpus_allowed;
136056 + set_cpus_allowed_ptr(current, get_cpu_mask(cpu));
136057 + p = qman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
136058 + if (!p)
136059 + pr_err("Qman slave portal failure on cpu %d\n", cpu);
136060 + else
136061 + pr_info("Qman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
136062 + set_cpus_allowed_ptr(current, &oldmask);
136063 + if (shared_portals_idx >= num_shared_portals)
136064 + shared_portals_idx = 0;
136065 +}
136066 +
136067 +static struct cpumask want_unshared __initdata;
136068 +static struct cpumask want_shared __initdata;
136069 +
136070 +static int __init parse_qportals(char *str)
136071 +{
136072 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
136073 + "qportals");
136074 +}
136075 +__setup("qportals=", parse_qportals);
136076 +
136077 +static void qman_portal_update_sdest(const struct qm_portal_config *pcfg,
136078 + unsigned int cpu)
136079 +{
136080 +#ifdef CONFIG_FSL_PAMU
136081 + struct pamu_stash_attribute stash_attr;
136082 + int ret;
136083 +
136084 + if (pcfg->iommu_domain) {
136085 + stash_attr.cpu = cpu;
136086 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
136087 + /* set stash information for the window */
136088 + stash_attr.window = 0;
136089 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
136090 + DOMAIN_ATTR_FSL_PAMU_STASH, &stash_attr);
136091 + if (ret < 0) {
136092 + pr_err("Failed to update pamu stash setting\n");
136093 + return;
136094 + }
136095 + }
136096 +#endif
136097 +#ifdef CONFIG_FSL_QMAN_CONFIG
136098 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
136099 + pr_warn("Failed to update portal's stash request queue\n");
136100 +#endif
136101 +}
136102 +
136103 +static int qman_offline_cpu(unsigned int cpu)
136104 +{
136105 + struct qman_portal *p;
136106 + const struct qm_portal_config *pcfg;
136107 + p = (struct qman_portal *)affine_portals[cpu];
136108 + if (p) {
136109 + pcfg = qman_get_qm_portal_config(p);
136110 + if (pcfg) {
136111 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
136112 + qman_portal_update_sdest(pcfg, 0);
136113 + }
136114 + }
136115 + return 0;
136116 +}
136117 +
136118 +#ifdef CONFIG_HOTPLUG_CPU
136119 +static int qman_online_cpu(unsigned int cpu)
136120 +{
136121 + struct qman_portal *p;
136122 + const struct qm_portal_config *pcfg;
136123 + p = (struct qman_portal *)affine_portals[cpu];
136124 + if (p) {
136125 + pcfg = qman_get_qm_portal_config(p);
136126 + if (pcfg) {
136127 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
136128 + qman_portal_update_sdest(pcfg, cpu);
136129 + }
136130 + }
136131 + return 0;
136132 +}
136133 +
136134 +static int qman_hotplug_cpu_callback(struct notifier_block *nfb,
136135 + unsigned long action, void *hcpu)
136136 +{
136137 + unsigned int cpu = (unsigned long)hcpu;
136138 +
136139 + switch (action) {
136140 + case CPU_ONLINE:
136141 + case CPU_ONLINE_FROZEN:
136142 + qman_online_cpu(cpu);
136143 + break;
136144 + case CPU_DOWN_PREPARE:
136145 + case CPU_DOWN_PREPARE_FROZEN:
136146 + qman_offline_cpu(cpu);
136147 + default:
136148 + break;
136149 + }
136150 + return NOTIFY_OK;
136151 +}
136152 +
136153 +static struct notifier_block qman_hotplug_cpu_notifier = {
136154 + .notifier_call = qman_hotplug_cpu_callback,
136155 +};
136156 +#endif /* CONFIG_HOTPLUG_CPU */
136157 +
136158 +__init int qman_init(void)
136159 +{
136160 + struct cpumask slave_cpus;
136161 + struct cpumask unshared_cpus = *cpu_none_mask;
136162 + struct cpumask shared_cpus = *cpu_none_mask;
136163 + LIST_HEAD(unshared_pcfgs);
136164 + LIST_HEAD(shared_pcfgs);
136165 + struct device_node *dn;
136166 + struct qm_portal_config *pcfg;
136167 + struct qman_portal *p;
136168 + int cpu, ret;
136169 + const u32 *clk;
136170 + struct cpumask offline_cpus;
136171 +
136172 + /* Initialise the Qman (CCSR) device */
136173 + for_each_compatible_node(dn, NULL, "fsl,qman") {
136174 + if (!qman_init_ccsr(dn))
136175 + pr_info("Qman err interrupt handler present\n");
136176 + else
136177 + pr_err("Qman CCSR setup failed\n");
136178 +
136179 + clk = of_get_property(dn, "clock-frequency", NULL);
136180 + if (!clk)
136181 + pr_warn("Can't find Qman clock frequency\n");
136182 + else
136183 + qman_clk = be32_to_cpu(*clk);
136184 + }
136185 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136186 + /* Setup lookup table for FQ demux */
136187 + ret = qman_setup_fq_lookup_table(get_qman_fqd_size()/64);
136188 + if (ret)
136189 + return ret;
136190 +#endif
136191 +
136192 + /* Get qman ip revision */
136193 + qman_get_ip_revision(dn);
136194 + if ((qman_ip_rev & 0xff00) >= QMAN_REV30) {
136195 + qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
136196 + qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
136197 + qm_channel_pme = QMAN_CHANNEL_PME_REV3;
136198 + }
136199 +
136200 + if ((qman_ip_rev == QMAN_REV31) && (qman_ip_cfg == QMAN_REV_CFG_2))
136201 + qm_channel_dce = QMAN_CHANNEL_DCE_QMANREV312;
136202 +
136203 + /*
136204 + * Parse the ceetm node to get how many ceetm instances are supported
136205 + * on the current silicon. num_ceetms must be confirmed before portals
136206 + * are intiailized.
136207 + */
136208 + num_ceetms = 0;
136209 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm")
136210 + num_ceetms++;
136211 +
136212 + /* Parse pool channels into the SDQCR mask. (Must happen before portals
136213 + * are initialised.) */
136214 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
136215 + ret = fsl_pool_channel_range_sdqcr(dn);
136216 + if (ret)
136217 + return ret;
136218 + }
136219 +
136220 + memset(affine_portals, 0, sizeof(void *) * num_possible_cpus());
136221 + /* Initialise portals. See bman_driver.c for comments */
136222 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
136223 + if (!of_device_is_available(dn))
136224 + continue;
136225 + pcfg = parse_pcfg(dn);
136226 + if (pcfg) {
136227 + pcfg->public_cfg.pools = pools_sdqcr;
136228 + list_add_tail(&pcfg->list, &unused_pcfgs);
136229 + }
136230 + }
136231 + for_each_possible_cpu(cpu) {
136232 + if (cpumask_test_cpu(cpu, &want_shared)) {
136233 + pcfg = get_pcfg(&unused_pcfgs);
136234 + if (!pcfg)
136235 + break;
136236 + pcfg->public_cfg.cpu = cpu;
136237 + list_add_tail(&pcfg->list, &shared_pcfgs);
136238 + cpumask_set_cpu(cpu, &shared_cpus);
136239 + }
136240 + if (cpumask_test_cpu(cpu, &want_unshared)) {
136241 + if (cpumask_test_cpu(cpu, &shared_cpus))
136242 + continue;
136243 + pcfg = get_pcfg(&unused_pcfgs);
136244 + if (!pcfg)
136245 + break;
136246 + pcfg->public_cfg.cpu = cpu;
136247 + list_add_tail(&pcfg->list, &unshared_pcfgs);
136248 + cpumask_set_cpu(cpu, &unshared_cpus);
136249 + }
136250 + }
136251 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
136252 + for_each_online_cpu(cpu) {
136253 + pcfg = get_pcfg(&unused_pcfgs);
136254 + if (!pcfg)
136255 + break;
136256 + pcfg->public_cfg.cpu = cpu;
136257 + list_add_tail(&pcfg->list, &unshared_pcfgs);
136258 + cpumask_set_cpu(cpu, &unshared_cpus);
136259 + }
136260 + }
136261 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
136262 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
136263 + if (cpumask_empty(&slave_cpus)) {
136264 + if (!list_empty(&shared_pcfgs)) {
136265 + cpumask_or(&unshared_cpus, &unshared_cpus,
136266 + &shared_cpus);
136267 + cpumask_clear(&shared_cpus);
136268 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
136269 + INIT_LIST_HEAD(&shared_pcfgs);
136270 + }
136271 + } else {
136272 + if (list_empty(&shared_pcfgs)) {
136273 + pcfg = get_pcfg(&unshared_pcfgs);
136274 + if (!pcfg) {
136275 + pr_crit("No QMan portals available!\n");
136276 + return 0;
136277 + }
136278 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
136279 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
136280 + list_add_tail(&pcfg->list, &shared_pcfgs);
136281 + }
136282 + }
136283 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
136284 + pcfg->public_cfg.is_shared = 0;
136285 + p = init_pcfg(pcfg);
136286 + if (!p) {
136287 + pr_crit("Unable to configure portals\n");
136288 + return 0;
136289 + }
136290 + }
136291 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
136292 + pcfg->public_cfg.is_shared = 1;
136293 + p = init_pcfg(pcfg);
136294 + if (p)
136295 + shared_portals[num_shared_portals++] = p;
136296 + }
136297 + if (!cpumask_empty(&slave_cpus))
136298 + for_each_cpu(cpu, &slave_cpus)
136299 + init_slave(cpu);
136300 + pr_info("Qman portals initialised\n");
136301 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
136302 + for_each_cpu(cpu, &offline_cpus)
136303 + qman_offline_cpu(cpu);
136304 +#ifdef CONFIG_HOTPLUG_CPU
136305 + register_hotcpu_notifier(&qman_hotplug_cpu_notifier);
136306 +#endif
136307 + return 0;
136308 +}
136309 +
136310 +__init int qman_resource_init(void)
136311 +{
136312 + struct device_node *dn;
136313 + int ret;
136314 +
136315 + /* Initialise FQID allocation ranges */
136316 + for_each_compatible_node(dn, NULL, "fsl,fqid-range") {
136317 + ret = fsl_fqid_range_init(dn);
136318 + if (ret)
136319 + return ret;
136320 + }
136321 + /* Initialise CGRID allocation ranges */
136322 + for_each_compatible_node(dn, NULL, "fsl,cgrid-range") {
136323 + ret = fsl_cgrid_range_init(dn);
136324 + if (ret)
136325 + return ret;
136326 + }
136327 + /* Parse pool channels into the allocator. (Must happen after portals
136328 + * are initialised.) */
136329 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
136330 + ret = fsl_pool_channel_range_init(dn);
136331 + if (ret)
136332 + return ret;
136333 + }
136334 +
136335 + /* Parse CEETM */
136336 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm") {
136337 + ret = fsl_ceetm_init(dn);
136338 + if (ret)
136339 + return ret;
136340 + }
136341 + return 0;
136342 +}
136343 +
136344 +#ifdef CONFIG_SUSPEND
136345 +void suspend_unused_qportal(void)
136346 +{
136347 + struct qm_portal_config *pcfg;
136348 +
136349 + if (list_empty(&unused_pcfgs))
136350 + return;
136351 +
136352 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
136353 +#ifdef CONFIG_PM_DEBUG
136354 + pr_info("Need to save qportal %d\n", pcfg->public_cfg.index);
136355 +#endif
136356 + /* save isdr, disable all via isdr, clear isr */
136357 + pcfg->saved_isdr =
136358 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
136359 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
136360 + 0xe08);
136361 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
136362 + 0xe00);
136363 + }
136364 + return;
136365 +}
136366 +
136367 +void resume_unused_qportal(void)
136368 +{
136369 + struct qm_portal_config *pcfg;
136370 +
136371 + if (list_empty(&unused_pcfgs))
136372 + return;
136373 +
136374 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
136375 +#ifdef CONFIG_PM_DEBUG
136376 + pr_info("Need to resume qportal %d\n", pcfg->public_cfg.index);
136377 +#endif
136378 + /* restore isdr */
136379 + __raw_writel(pcfg->saved_isdr,
136380 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
136381 + }
136382 + return;
136383 +}
136384 +#endif
136385 diff --git a/drivers/staging/fsl_qbman/qman_high.c b/drivers/staging/fsl_qbman/qman_high.c
136386 new file mode 100644
136387 index 00000000..1651e62c
136388 --- /dev/null
136389 +++ b/drivers/staging/fsl_qbman/qman_high.c
136390 @@ -0,0 +1,5669 @@
136391 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
136392 + *
136393 + * Redistribution and use in source and binary forms, with or without
136394 + * modification, are permitted provided that the following conditions are met:
136395 + * * Redistributions of source code must retain the above copyright
136396 + * notice, this list of conditions and the following disclaimer.
136397 + * * Redistributions in binary form must reproduce the above copyright
136398 + * notice, this list of conditions and the following disclaimer in the
136399 + * documentation and/or other materials provided with the distribution.
136400 + * * Neither the name of Freescale Semiconductor nor the
136401 + * names of its contributors may be used to endorse or promote products
136402 + * derived from this software without specific prior written permission.
136403 + *
136404 + *
136405 + * ALTERNATIVELY, this software may be distributed under the terms of the
136406 + * GNU General Public License ("GPL") as published by the Free Software
136407 + * Foundation, either version 2 of that License or (at your option) any
136408 + * later version.
136409 + *
136410 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
136411 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
136412 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
136413 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
136414 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
136415 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
136416 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
136417 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
136418 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
136419 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
136420 + */
136421 +
136422 +#include "qman_low.h"
136423 +
136424 +/* Compilation constants */
136425 +#define DQRR_MAXFILL 15
136426 +#define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */
136427 +#define IRQNAME "QMan portal %d"
136428 +#define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */
136429 +
136430 +/* Divide 'n' by 'd', rounding down if 'r' is negative, rounding up if it's
136431 + * positive, and rounding to the closest value if it's zero. NB, this macro
136432 + * implicitly upgrades parameters to unsigned 64-bit, so feed it with types
136433 + * that are compatible with this. NB, these arguments should not be expressions
136434 + * unless it is safe for them to be evaluated multiple times. Eg. do not pass
136435 + * in "some_value++" as a parameter to the macro! */
136436 +#define ROUNDING(n, d, r) \
136437 + (((r) < 0) ? div64_u64((n), (d)) : \
136438 + (((r) > 0) ? div64_u64(((n) + (d) - 1), (d)) : \
136439 + div64_u64(((n) + ((d) / 2)), (d))))
136440 +
136441 +/* Lock/unlock frame queues, subject to the "LOCKED" flag. This is about
136442 + * inter-processor locking only. Note, FQLOCK() is always called either under a
136443 + * local_irq_save() or from interrupt context - hence there's no need for irq
136444 + * protection (and indeed, attempting to nest irq-protection doesn't work, as
136445 + * the "irq en/disable" machinery isn't recursive...). */
136446 +#define FQLOCK(fq) \
136447 + do { \
136448 + struct qman_fq *__fq478 = (fq); \
136449 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
136450 + spin_lock(&__fq478->fqlock); \
136451 + } while (0)
136452 +#define FQUNLOCK(fq) \
136453 + do { \
136454 + struct qman_fq *__fq478 = (fq); \
136455 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
136456 + spin_unlock(&__fq478->fqlock); \
136457 + } while (0)
136458 +
136459 +static inline void fq_set(struct qman_fq *fq, u32 mask)
136460 +{
136461 + set_bits(mask, &fq->flags);
136462 +}
136463 +static inline void fq_clear(struct qman_fq *fq, u32 mask)
136464 +{
136465 + clear_bits(mask, &fq->flags);
136466 +}
136467 +static inline int fq_isset(struct qman_fq *fq, u32 mask)
136468 +{
136469 + return fq->flags & mask;
136470 +}
136471 +static inline int fq_isclear(struct qman_fq *fq, u32 mask)
136472 +{
136473 + return !(fq->flags & mask);
136474 +}
136475 +
136476 +struct qman_portal {
136477 + struct qm_portal p;
136478 + unsigned long bits; /* PORTAL_BITS_*** - dynamic, strictly internal */
136479 + unsigned long irq_sources;
136480 + u32 use_eqcr_ci_stashing;
136481 + u32 slowpoll; /* only used when interrupts are off */
136482 + struct qman_fq *vdqcr_owned; /* only 1 volatile dequeue at a time */
136483 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136484 + struct qman_fq *eqci_owned; /* only 1 enqueue WAIT_SYNC at a time */
136485 +#endif
136486 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136487 + raw_spinlock_t sharing_lock; /* only used if is_shared */
136488 + int is_shared;
136489 + struct qman_portal *sharing_redirect;
136490 +#endif
136491 + u32 sdqcr;
136492 + int dqrr_disable_ref;
136493 + /* A portal-specific handler for DCP ERNs. If this is NULL, the global
136494 + * handler is called instead. */
136495 + qman_cb_dc_ern cb_dc_ern;
136496 + /* When the cpu-affine portal is activated, this is non-NULL */
136497 + const struct qm_portal_config *config;
136498 + /* This is needed for providing a non-NULL device to dma_map_***() */
136499 + struct platform_device *pdev;
136500 + struct dpa_rbtree retire_table;
136501 + char irqname[MAX_IRQNAME];
136502 + /* 2-element array. cgrs[0] is mask, cgrs[1] is snapshot. */
136503 + struct qman_cgrs *cgrs;
136504 + /* linked-list of CSCN handlers. */
136505 + struct list_head cgr_cbs;
136506 + /* list lock */
136507 + spinlock_t cgr_lock;
136508 + /* 2-element array. ccgrs[0] is mask, ccgrs[1] is snapshot. */
136509 + struct qman_ccgrs *ccgrs[QMAN_CEETM_MAX];
136510 + /* 256-element array, each is a linked-list of CCSCN handlers. */
136511 + struct list_head ccgr_cbs[QMAN_CEETM_MAX];
136512 + /* list lock */
136513 + spinlock_t ccgr_lock;
136514 + /* track if memory was allocated by the driver */
136515 + u8 alloced;
136516 + /* power management data */
136517 + u32 save_isdr;
136518 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136519 + /* Keep a shadow copy of the DQRR on LE systems as the SW needs to
136520 + * do byte swaps of DQRR read only memory. First entry must be aligned
136521 + * to 2 ** 10 to ensure DQRR index calculations based shadow copy
136522 + * address (6 bits for address shift + 4 bits for the DQRR size).
136523 + */
136524 + struct qm_dqrr_entry shadow_dqrr[QM_DQRR_SIZE] __aligned(1024);
136525 +#endif
136526 +};
136527 +
136528 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136529 +#define PORTAL_IRQ_LOCK(p, irqflags) \
136530 + do { \
136531 + if ((p)->is_shared) \
136532 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
136533 + else \
136534 + local_irq_save(irqflags); \
136535 + } while (0)
136536 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
136537 + do { \
136538 + if ((p)->is_shared) \
136539 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
136540 + irqflags); \
136541 + else \
136542 + local_irq_restore(irqflags); \
136543 + } while (0)
136544 +#else
136545 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
136546 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
136547 +#endif
136548 +
136549 +/* Global handler for DCP ERNs. Used when the portal receiving the message does
136550 + * not have a portal-specific handler. */
136551 +static qman_cb_dc_ern cb_dc_ern;
136552 +
136553 +static cpumask_t affine_mask;
136554 +static DEFINE_SPINLOCK(affine_mask_lock);
136555 +static u16 affine_channels[NR_CPUS];
136556 +static DEFINE_PER_CPU(struct qman_portal, qman_affine_portal);
136557 +void *affine_portals[NR_CPUS];
136558 +
136559 +/* "raw" gets the cpu-local struct whether it's a redirect or not. */
136560 +static inline struct qman_portal *get_raw_affine_portal(void)
136561 +{
136562 + return &get_cpu_var(qman_affine_portal);
136563 +}
136564 +/* For ops that can redirect, this obtains the portal to use */
136565 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136566 +static inline struct qman_portal *get_affine_portal(void)
136567 +{
136568 + struct qman_portal *p = get_raw_affine_portal();
136569 + if (p->sharing_redirect)
136570 + return p->sharing_redirect;
136571 + return p;
136572 +}
136573 +#else
136574 +#define get_affine_portal() get_raw_affine_portal()
136575 +#endif
136576 +/* For every "get", there must be a "put" */
136577 +static inline void put_affine_portal(void)
136578 +{
136579 + put_cpu_var(qman_affine_portal);
136580 +}
136581 +/* Exception: poll functions assume the caller is cpu-affine and in no risk of
136582 + * re-entrance, which are the two reasons we usually use the get/put_cpu_var()
136583 + * semantic - ie. to disable pre-emption. Some use-cases expect the execution
136584 + * context to remain as non-atomic during poll-triggered callbacks as it was
136585 + * when the poll API was first called (eg. NAPI), so we go out of our way in
136586 + * this case to not disable pre-emption. */
136587 +static inline struct qman_portal *get_poll_portal(void)
136588 +{
136589 + return &get_cpu_var(qman_affine_portal);
136590 +}
136591 +#define put_poll_portal()
136592 +
136593 +/* This gives a FQID->FQ lookup to cover the fact that we can't directly demux
136594 + * retirement notifications (the fact they are sometimes h/w-consumed means that
136595 + * contextB isn't always a s/w demux - and as we can't know which case it is
136596 + * when looking at the notification, we have to use the slow lookup for all of
136597 + * them). NB, it's possible to have multiple FQ objects refer to the same FQID
136598 + * (though at most one of them should be the consumer), so this table isn't for
136599 + * all FQs - FQs are added when retirement commands are issued, and removed when
136600 + * they complete, which also massively reduces the size of this table. */
136601 +IMPLEMENT_DPA_RBTREE(fqtree, struct qman_fq, node, fqid);
136602 +
136603 +/* This is what everything can wait on, even if it migrates to a different cpu
136604 + * to the one whose affine portal it is waiting on. */
136605 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
136606 +
136607 +static inline int table_push_fq(struct qman_portal *p, struct qman_fq *fq)
136608 +{
136609 + int ret = fqtree_push(&p->retire_table, fq);
136610 + if (ret)
136611 + pr_err("ERROR: double FQ-retirement %d\n", fq->fqid);
136612 + return ret;
136613 +}
136614 +
136615 +static inline void table_del_fq(struct qman_portal *p, struct qman_fq *fq)
136616 +{
136617 + fqtree_del(&p->retire_table, fq);
136618 +}
136619 +
136620 +static inline struct qman_fq *table_find_fq(struct qman_portal *p, u32 fqid)
136621 +{
136622 + return fqtree_find(&p->retire_table, fqid);
136623 +}
136624 +
136625 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136626 +static void **qman_fq_lookup_table;
136627 +static size_t qman_fq_lookup_table_size;
136628 +
136629 +int qman_setup_fq_lookup_table(size_t num_entries)
136630 +{
136631 + num_entries++;
136632 + /* Allocate 1 more entry since the first entry is not used */
136633 + qman_fq_lookup_table = vzalloc((num_entries * sizeof(void *)));
136634 + if (!qman_fq_lookup_table) {
136635 + pr_err("QMan: Could not allocate fq lookup table\n");
136636 + return -ENOMEM;
136637 + }
136638 + qman_fq_lookup_table_size = num_entries;
136639 + pr_info("QMan: Allocated lookup table at %p, entry count %lu\n",
136640 + qman_fq_lookup_table,
136641 + (unsigned long)qman_fq_lookup_table_size);
136642 + return 0;
136643 +}
136644 +
136645 +/* global structure that maintains fq object mapping */
136646 +static DEFINE_SPINLOCK(fq_hash_table_lock);
136647 +
136648 +static int find_empty_fq_table_entry(u32 *entry, struct qman_fq *fq)
136649 +{
136650 + u32 i;
136651 +
136652 + spin_lock(&fq_hash_table_lock);
136653 + /* Can't use index zero because this has special meaning
136654 + * in context_b field. */
136655 + for (i = 1; i < qman_fq_lookup_table_size; i++) {
136656 + if (qman_fq_lookup_table[i] == NULL) {
136657 + *entry = i;
136658 + qman_fq_lookup_table[i] = fq;
136659 + spin_unlock(&fq_hash_table_lock);
136660 + return 0;
136661 + }
136662 + }
136663 + spin_unlock(&fq_hash_table_lock);
136664 + return -ENOMEM;
136665 +}
136666 +
136667 +static void clear_fq_table_entry(u32 entry)
136668 +{
136669 + spin_lock(&fq_hash_table_lock);
136670 + BUG_ON(entry >= qman_fq_lookup_table_size);
136671 + qman_fq_lookup_table[entry] = NULL;
136672 + spin_unlock(&fq_hash_table_lock);
136673 +}
136674 +
136675 +static inline struct qman_fq *get_fq_table_entry(u32 entry)
136676 +{
136677 + BUG_ON(entry >= qman_fq_lookup_table_size);
136678 + return qman_fq_lookup_table[entry];
136679 +}
136680 +#endif
136681 +
136682 +static inline void cpu_to_hw_fqd(struct qm_fqd *fqd)
136683 +{
136684 + /* Byteswap the FQD to HW format */
136685 + fqd->fq_ctrl = cpu_to_be16(fqd->fq_ctrl);
136686 + fqd->dest_wq = cpu_to_be16(fqd->dest_wq);
136687 + fqd->ics_cred = cpu_to_be16(fqd->ics_cred);
136688 + fqd->context_b = cpu_to_be32(fqd->context_b);
136689 + fqd->context_a.opaque = cpu_to_be64(fqd->context_a.opaque);
136690 +}
136691 +
136692 +static inline void hw_fqd_to_cpu(struct qm_fqd *fqd)
136693 +{
136694 + /* Byteswap the FQD to CPU format */
136695 + fqd->fq_ctrl = be16_to_cpu(fqd->fq_ctrl);
136696 + fqd->dest_wq = be16_to_cpu(fqd->dest_wq);
136697 + fqd->ics_cred = be16_to_cpu(fqd->ics_cred);
136698 + fqd->context_b = be32_to_cpu(fqd->context_b);
136699 + fqd->context_a.opaque = be64_to_cpu(fqd->context_a.opaque);
136700 +}
136701 +
136702 +/* Swap a 40 bit address */
136703 +static inline u64 cpu_to_be40(u64 in)
136704 +{
136705 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136706 + return in;
136707 +#else
136708 + u64 out = 0;
136709 + u8 *p = (u8 *) &out;
136710 + p[0] = in >> 32;
136711 + p[1] = in >> 24;
136712 + p[2] = in >> 16;
136713 + p[3] = in >> 8;
136714 + p[4] = in >> 0;
136715 + return out;
136716 +#endif
136717 +}
136718 +static inline u64 be40_to_cpu(u64 in)
136719 +{
136720 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136721 + return in;
136722 +#else
136723 + u64 out = 0;
136724 + u8 *pout = (u8 *) &out;
136725 + u8 *pin = (u8 *) &in;
136726 + pout[0] = pin[4];
136727 + pout[1] = pin[3];
136728 + pout[2] = pin[2];
136729 + pout[3] = pin[1];
136730 + pout[4] = pin[0];
136731 + return out;
136732 +#endif
136733 +}
136734 +
136735 +/* Swap a 24 bit value */
136736 +static inline u32 cpu_to_be24(u32 in)
136737 +{
136738 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136739 + return in;
136740 +#else
136741 + u32 out = 0;
136742 + u8 *p = (u8 *) &out;
136743 + p[0] = in >> 16;
136744 + p[1] = in >> 8;
136745 + p[2] = in >> 0;
136746 + return out;
136747 +#endif
136748 +}
136749 +
136750 +static inline u32 be24_to_cpu(u32 in)
136751 +{
136752 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136753 + return in;
136754 +#else
136755 + u32 out = 0;
136756 + u8 *pout = (u8 *) &out;
136757 + u8 *pin = (u8 *) &in;
136758 + pout[0] = pin[2];
136759 + pout[1] = pin[1];
136760 + pout[2] = pin[0];
136761 + return out;
136762 +#endif
136763 +}
136764 +
136765 +static inline u64 be48_to_cpu(u64 in)
136766 +{
136767 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136768 + return in;
136769 +#else
136770 + u64 out = 0;
136771 + u8 *pout = (u8 *) &out;
136772 + u8 *pin = (u8 *) &in;
136773 +
136774 + pout[0] = pin[5];
136775 + pout[1] = pin[4];
136776 + pout[2] = pin[3];
136777 + pout[3] = pin[2];
136778 + pout[4] = pin[1];
136779 + pout[5] = pin[0];
136780 + return out;
136781 +#endif
136782 +}
136783 +static inline void cpu_to_hw_fd(struct qm_fd *fd)
136784 +{
136785 + fd->opaque_addr = cpu_to_be64(fd->opaque_addr);
136786 + fd->status = cpu_to_be32(fd->status);
136787 + fd->opaque = cpu_to_be32(fd->opaque);
136788 +}
136789 +
136790 +static inline void hw_fd_to_cpu(struct qm_fd *fd)
136791 +{
136792 + fd->opaque_addr = be64_to_cpu(fd->opaque_addr);
136793 + fd->status = be32_to_cpu(fd->status);
136794 + fd->opaque = be32_to_cpu(fd->opaque);
136795 +}
136796 +
136797 +static inline void hw_cq_query_to_cpu(struct qm_mcr_ceetm_cq_query *cq_query)
136798 +{
136799 + cq_query->ccgid = be16_to_cpu(cq_query->ccgid);
136800 + cq_query->state = be16_to_cpu(cq_query->state);
136801 + cq_query->pfdr_hptr = be24_to_cpu(cq_query->pfdr_hptr);
136802 + cq_query->pfdr_tptr = be24_to_cpu(cq_query->pfdr_tptr);
136803 + cq_query->od1_xsfdr = be16_to_cpu(cq_query->od1_xsfdr);
136804 + cq_query->od2_xsfdr = be16_to_cpu(cq_query->od2_xsfdr);
136805 + cq_query->od3_xsfdr = be16_to_cpu(cq_query->od3_xsfdr);
136806 + cq_query->od4_xsfdr = be16_to_cpu(cq_query->od4_xsfdr);
136807 + cq_query->od5_xsfdr = be16_to_cpu(cq_query->od5_xsfdr);
136808 + cq_query->od6_xsfdr = be16_to_cpu(cq_query->od6_xsfdr);
136809 + cq_query->ra1_xsfdr = be16_to_cpu(cq_query->ra1_xsfdr);
136810 + cq_query->ra2_xsfdr = be16_to_cpu(cq_query->ra2_xsfdr);
136811 + cq_query->frm_cnt = be24_to_cpu(cq_query->frm_cnt);
136812 +}
136813 +
136814 +static inline void hw_ccgr_query_to_cpu(struct qm_mcr_ceetm_ccgr_query *ccgr_q)
136815 +{
136816 + int i;
136817 +
136818 + ccgr_q->cm_query.cs_thres.hword =
136819 + be16_to_cpu(ccgr_q->cm_query.cs_thres.hword);
136820 + ccgr_q->cm_query.cs_thres_x.hword =
136821 + be16_to_cpu(ccgr_q->cm_query.cs_thres_x.hword);
136822 + ccgr_q->cm_query.td_thres.hword =
136823 + be16_to_cpu(ccgr_q->cm_query.td_thres.hword);
136824 + ccgr_q->cm_query.wr_parm_g.word =
136825 + be32_to_cpu(ccgr_q->cm_query.wr_parm_g.word);
136826 + ccgr_q->cm_query.wr_parm_y.word =
136827 + be32_to_cpu(ccgr_q->cm_query.wr_parm_y.word);
136828 + ccgr_q->cm_query.wr_parm_r.word =
136829 + be32_to_cpu(ccgr_q->cm_query.wr_parm_r.word);
136830 + ccgr_q->cm_query.cscn_targ_dcp =
136831 + be16_to_cpu(ccgr_q->cm_query.cscn_targ_dcp);
136832 + ccgr_q->cm_query.i_cnt = be40_to_cpu(ccgr_q->cm_query.i_cnt);
136833 + ccgr_q->cm_query.a_cnt = be40_to_cpu(ccgr_q->cm_query.a_cnt);
136834 + for (i = 0; i < ARRAY_SIZE(ccgr_q->cm_query.cscn_targ_swp); i++)
136835 + ccgr_q->cm_query.cscn_targ_swp[i] =
136836 + be32_to_cpu(ccgr_q->cm_query.cscn_targ_swp[i]);
136837 +}
136838 +
136839 +/* In the case that slow- and fast-path handling are both done by qman_poll()
136840 + * (ie. because there is no interrupt handling), we ought to balance how often
136841 + * we do the fast-path poll versus the slow-path poll. We'll use two decrementer
136842 + * sources, so we call the fast poll 'n' times before calling the slow poll
136843 + * once. The idle decrementer constant is used when the last slow-poll detected
136844 + * no work to do, and the busy decrementer constant when the last slow-poll had
136845 + * work to do. */
136846 +#define SLOW_POLL_IDLE 1000
136847 +#define SLOW_POLL_BUSY 10
136848 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is);
136849 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
136850 + unsigned int poll_limit);
136851 +
136852 +/* Portal interrupt handler */
136853 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
136854 +{
136855 + struct qman_portal *p = ptr;
136856 + /*
136857 + * The CSCI/CCSCI source is cleared inside __poll_portal_slow(), because
136858 + * it could race against a Query Congestion State command also given
136859 + * as part of the handling of this interrupt source. We mustn't
136860 + * clear it a second time in this top-level function.
136861 + */
136862 + u32 clear = QM_DQAVAIL_MASK | (p->irq_sources &
136863 + ~(QM_PIRQ_CSCI | QM_PIRQ_CCSCI));
136864 + u32 is = qm_isr_status_read(&p->p) & p->irq_sources;
136865 + /* DQRR-handling if it's interrupt-driven */
136866 + if (is & QM_PIRQ_DQRI)
136867 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
136868 + /* Handling of anything else that's interrupt-driven */
136869 + clear |= __poll_portal_slow(p, is);
136870 + qm_isr_status_clear(&p->p, clear);
136871 + return IRQ_HANDLED;
136872 +}
136873 +
136874 +/* This inner version is used privately by qman_create_affine_portal(), as well
136875 + * as by the exported qman_stop_dequeues(). */
136876 +static inline void qman_stop_dequeues_ex(struct qman_portal *p)
136877 +{
136878 + unsigned long irqflags __maybe_unused;
136879 + PORTAL_IRQ_LOCK(p, irqflags);
136880 + if (!(p->dqrr_disable_ref++))
136881 + qm_dqrr_set_maxfill(&p->p, 0);
136882 + PORTAL_IRQ_UNLOCK(p, irqflags);
136883 +}
136884 +
136885 +static int drain_mr_fqrni(struct qm_portal *p)
136886 +{
136887 + const struct qm_mr_entry *msg;
136888 +loop:
136889 + msg = qm_mr_current(p);
136890 + if (!msg) {
136891 + /* if MR was full and h/w had other FQRNI entries to produce, we
136892 + * need to allow it time to produce those entries once the
136893 + * existing entries are consumed. A worst-case situation
136894 + * (fully-loaded system) means h/w sequencers may have to do 3-4
136895 + * other things before servicing the portal's MR pump, each of
136896 + * which (if slow) may take ~50 qman cycles (which is ~200
136897 + * processor cycles). So rounding up and then multiplying this
136898 + * worst-case estimate by a factor of 10, just to be
136899 + * ultra-paranoid, goes as high as 10,000 cycles. NB, we consume
136900 + * one entry at a time, so h/w has an opportunity to produce new
136901 + * entries well before the ring has been fully consumed, so
136902 + * we're being *really* paranoid here. */
136903 + u64 now, then = mfatb();
136904 + do {
136905 + now = mfatb();
136906 + } while ((then + 10000) > now);
136907 + msg = qm_mr_current(p);
136908 + if (!msg)
136909 + return 0;
136910 + }
136911 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) != QM_MR_VERB_FQRNI) {
136912 + /* We aren't draining anything but FQRNIs */
136913 + pr_err("QMan found verb 0x%x in MR\n", msg->verb);
136914 + return -1;
136915 + }
136916 + qm_mr_next(p);
136917 + qm_mr_cci_consume(p, 1);
136918 + goto loop;
136919 +}
136920 +
136921 +#ifdef CONFIG_SUSPEND
136922 +static int _qman_portal_suspend_noirq(struct device *dev)
136923 +{
136924 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136925 +#ifdef CONFIG_PM_DEBUG
136926 + struct platform_device *pdev = to_platform_device(dev);
136927 +#endif
136928 +
136929 + p->save_isdr = qm_isr_disable_read(&p->p);
136930 + qm_isr_disable_write(&p->p, 0xffffffff);
136931 + qm_isr_status_clear(&p->p, 0xffffffff);
136932 +#ifdef CONFIG_PM_DEBUG
136933 + pr_info("Suspend for %s\n", pdev->name);
136934 +#endif
136935 + return 0;
136936 +}
136937 +
136938 +static int _qman_portal_resume_noirq(struct device *dev)
136939 +{
136940 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136941 +
136942 + /* restore isdr */
136943 + qm_isr_disable_write(&p->p, p->save_isdr);
136944 + return 0;
136945 +}
136946 +#else
136947 +#define _qman_portal_suspend_noirq NULL
136948 +#define _qman_portal_resume_noirq NULL
136949 +#endif
136950 +
136951 +struct dev_pm_domain qman_portal_device_pm_domain = {
136952 + .ops = {
136953 + USE_PLATFORM_PM_SLEEP_OPS
136954 + .suspend_noirq = _qman_portal_suspend_noirq,
136955 + .resume_noirq = _qman_portal_resume_noirq,
136956 + }
136957 +};
136958 +
136959 +struct qman_portal *qman_create_portal(
136960 + struct qman_portal *portal,
136961 + const struct qm_portal_config *config,
136962 + const struct qman_cgrs *cgrs)
136963 +{
136964 + struct qm_portal *__p;
136965 + char buf[16];
136966 + int ret;
136967 + u32 isdr;
136968 +
136969 + if (!portal) {
136970 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
136971 + if (!portal)
136972 + return portal;
136973 + portal->alloced = 1;
136974 + } else
136975 + portal->alloced = 0;
136976 +
136977 + __p = &portal->p;
136978 +
136979 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && defined CONFIG_FSL_PAMU
136980 + /* PAMU is required for stashing */
136981 + portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ?
136982 + 1 : 0);
136983 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136984 + portal->use_eqcr_ci_stashing = 1;
136985 +#else
136986 + portal->use_eqcr_ci_stashing = 0;
136987 +#endif
136988 +
136989 + /* prep the low-level portal struct with the mapped addresses from the
136990 + * config, everything that follows depends on it and "config" is more
136991 + * for (de)reference... */
136992 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
136993 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
136994 + /*
136995 + * If CI-stashing is used, the current defaults use a threshold of 3,
136996 + * and stash with high-than-DQRR priority.
136997 + */
136998 + if (qm_eqcr_init(__p, qm_eqcr_pvb,
136999 + portal->use_eqcr_ci_stashing ? 3 : 0, 1)) {
137000 + pr_err("Qman EQCR initialisation failed\n");
137001 + goto fail_eqcr;
137002 + }
137003 + if (qm_dqrr_init(__p, config, qm_dqrr_dpush, qm_dqrr_pvb,
137004 + qm_dqrr_cdc, DQRR_MAXFILL)) {
137005 + pr_err("Qman DQRR initialisation failed\n");
137006 + goto fail_dqrr;
137007 + }
137008 + if (qm_mr_init(__p, qm_mr_pvb, qm_mr_cci)) {
137009 + pr_err("Qman MR initialisation failed\n");
137010 + goto fail_mr;
137011 + }
137012 + if (qm_mc_init(__p)) {
137013 + pr_err("Qman MC initialisation failed\n");
137014 + goto fail_mc;
137015 + }
137016 + if (qm_isr_init(__p)) {
137017 + pr_err("Qman ISR initialisation failed\n");
137018 + goto fail_isr;
137019 + }
137020 + /* static interrupt-gating controls */
137021 + qm_dqrr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_DQRR_ITHRESH);
137022 + qm_mr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_MR_ITHRESH);
137023 + qm_isr_set_iperiod(__p, CONFIG_FSL_QMAN_PIRQ_IPERIOD);
137024 + portal->cgrs = kmalloc(2 * sizeof(*cgrs), GFP_KERNEL);
137025 + if (!portal->cgrs)
137026 + goto fail_cgrs;
137027 + /* initial snapshot is no-depletion */
137028 + qman_cgrs_init(&portal->cgrs[1]);
137029 + if (cgrs)
137030 + portal->cgrs[0] = *cgrs;
137031 + else
137032 + /* if the given mask is NULL, assume all CGRs can be seen */
137033 + qman_cgrs_fill(&portal->cgrs[0]);
137034 + INIT_LIST_HEAD(&portal->cgr_cbs);
137035 + spin_lock_init(&portal->cgr_lock);
137036 + if (num_ceetms) {
137037 + for (ret = 0; ret < num_ceetms; ret++) {
137038 + portal->ccgrs[ret] = kmalloc(2 *
137039 + sizeof(struct qman_ccgrs), GFP_KERNEL);
137040 + if (!portal->ccgrs[ret])
137041 + goto fail_ccgrs;
137042 + qman_ccgrs_init(&portal->ccgrs[ret][1]);
137043 + qman_ccgrs_fill(&portal->ccgrs[ret][0]);
137044 + INIT_LIST_HEAD(&portal->ccgr_cbs[ret]);
137045 + }
137046 + }
137047 + spin_lock_init(&portal->ccgr_lock);
137048 + portal->bits = 0;
137049 + portal->slowpoll = 0;
137050 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
137051 + portal->eqci_owned = NULL;
137052 +#endif
137053 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137054 + raw_spin_lock_init(&portal->sharing_lock);
137055 + portal->is_shared = config->public_cfg.is_shared;
137056 + portal->sharing_redirect = NULL;
137057 +#endif
137058 + portal->sdqcr = QM_SDQCR_SOURCE_CHANNELS | QM_SDQCR_COUNT_UPTO3 |
137059 + QM_SDQCR_DEDICATED_PRECEDENCE | QM_SDQCR_TYPE_PRIO_QOS |
137060 + QM_SDQCR_TOKEN_SET(0xab) | QM_SDQCR_CHANNELS_DEDICATED;
137061 + portal->dqrr_disable_ref = 0;
137062 + portal->cb_dc_ern = NULL;
137063 + sprintf(buf, "qportal-%d", config->public_cfg.channel);
137064 + portal->pdev = platform_device_alloc(buf, -1);
137065 + if (!portal->pdev) {
137066 + pr_err("qman_portal - platform_device_alloc() failed\n");
137067 + goto fail_devalloc;
137068 + }
137069 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
137070 + portal->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
137071 + portal->pdev->dev.dma_mask = &portal->pdev->dev.coherent_dma_mask;
137072 +#else
137073 + if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) {
137074 + pr_err("qman_portal - dma_set_mask() failed\n");
137075 + goto fail_devadd;
137076 + }
137077 +#endif
137078 + portal->pdev->dev.pm_domain = &qman_portal_device_pm_domain;
137079 + portal->pdev->dev.platform_data = portal;
137080 + ret = platform_device_add(portal->pdev);
137081 + if (ret) {
137082 + pr_err("qman_portal - platform_device_add() failed\n");
137083 + goto fail_devadd;
137084 + }
137085 + dpa_rbtree_init(&portal->retire_table);
137086 + isdr = 0xffffffff;
137087 + qm_isr_disable_write(__p, isdr);
137088 + portal->irq_sources = 0;
137089 + qm_isr_enable_write(__p, portal->irq_sources);
137090 + qm_isr_status_clear(__p, 0xffffffff);
137091 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
137092 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
137093 + portal)) {
137094 + pr_err("request_irq() failed\n");
137095 + goto fail_irq;
137096 + }
137097 + if ((config->public_cfg.cpu != -1) &&
137098 + irq_can_set_affinity(config->public_cfg.irq) &&
137099 + irq_set_affinity(config->public_cfg.irq,
137100 + cpumask_of(config->public_cfg.cpu))) {
137101 + pr_err("irq_set_affinity() failed\n");
137102 + goto fail_affinity;
137103 + }
137104 +
137105 + /* Need EQCR to be empty before continuing */
137106 + isdr ^= QM_PIRQ_EQCI;
137107 + qm_isr_disable_write(__p, isdr);
137108 + ret = qm_eqcr_get_fill(__p);
137109 + if (ret) {
137110 + pr_err("Qman EQCR unclean\n");
137111 + goto fail_eqcr_empty;
137112 + }
137113 + isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
137114 + qm_isr_disable_write(__p, isdr);
137115 + if (qm_dqrr_current(__p) != NULL) {
137116 + pr_err("Qman DQRR unclean\n");
137117 + qm_dqrr_cdc_consume_n(__p, 0xffff);
137118 + }
137119 + if (qm_mr_current(__p) != NULL) {
137120 + /* special handling, drain just in case it's a few FQRNIs */
137121 + if (drain_mr_fqrni(__p)) {
137122 + const struct qm_mr_entry *e = qm_mr_current(__p);
137123 + /*
137124 + * Message ring cannot be empty no need to check
137125 + * qm_mr_current returned successfully
137126 + */
137127 + pr_err("Qman MR unclean, MR VERB 0x%x, rc 0x%x\n, addr 0x%x",
137128 + e->verb, e->ern.rc, e->ern.fd.addr_lo);
137129 + goto fail_dqrr_mr_empty;
137130 + }
137131 + }
137132 + /* Success */
137133 + portal->config = config;
137134 + qm_isr_disable_write(__p, 0);
137135 + qm_isr_uninhibit(__p);
137136 + /* Write a sane SDQCR */
137137 + qm_dqrr_sdqcr_set(__p, portal->sdqcr);
137138 + return portal;
137139 +fail_dqrr_mr_empty:
137140 +fail_eqcr_empty:
137141 +fail_affinity:
137142 + free_irq(config->public_cfg.irq, portal);
137143 +fail_irq:
137144 + platform_device_del(portal->pdev);
137145 +fail_devadd:
137146 + platform_device_put(portal->pdev);
137147 +fail_devalloc:
137148 + if (num_ceetms)
137149 + for (ret = 0; ret < num_ceetms; ret++)
137150 + kfree(portal->ccgrs[ret]);
137151 +fail_ccgrs:
137152 + kfree(portal->cgrs);
137153 +fail_cgrs:
137154 + qm_isr_finish(__p);
137155 +fail_isr:
137156 + qm_mc_finish(__p);
137157 +fail_mc:
137158 + qm_mr_finish(__p);
137159 +fail_mr:
137160 + qm_dqrr_finish(__p);
137161 +fail_dqrr:
137162 + qm_eqcr_finish(__p);
137163 +fail_eqcr:
137164 + if (portal->alloced)
137165 + kfree(portal);
137166 + return NULL;
137167 +}
137168 +
137169 +struct qman_portal *qman_create_affine_portal(
137170 + const struct qm_portal_config *config,
137171 + const struct qman_cgrs *cgrs)
137172 +{
137173 + struct qman_portal *res;
137174 + struct qman_portal *portal;
137175 +
137176 + portal = &per_cpu(qman_affine_portal, config->public_cfg.cpu);
137177 + res = qman_create_portal(portal, config, cgrs);
137178 + if (res) {
137179 + spin_lock(&affine_mask_lock);
137180 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
137181 + affine_channels[config->public_cfg.cpu] =
137182 + config->public_cfg.channel;
137183 + affine_portals[config->public_cfg.cpu] = portal;
137184 + spin_unlock(&affine_mask_lock);
137185 + }
137186 + return res;
137187 +}
137188 +
137189 +/* These checks are BUG_ON()s because the driver is already supposed to avoid
137190 + * these cases. */
137191 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
137192 + int cpu)
137193 +{
137194 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137195 + struct qman_portal *p;
137196 + p = &per_cpu(qman_affine_portal, cpu);
137197 + /* Check that we don't already have our own portal */
137198 + BUG_ON(p->config);
137199 + /* Check that we aren't already slaving to another portal */
137200 + BUG_ON(p->is_shared);
137201 + /* Check that 'redirect' is prepared to have us */
137202 + BUG_ON(!redirect->config->public_cfg.is_shared);
137203 + /* These are the only elements to initialise when redirecting */
137204 + p->irq_sources = 0;
137205 + p->sharing_redirect = redirect;
137206 + affine_portals[cpu] = p;
137207 + return p;
137208 +#else
137209 + BUG();
137210 + return NULL;
137211 +#endif
137212 +}
137213 +
137214 +void qman_destroy_portal(struct qman_portal *qm)
137215 +{
137216 + const struct qm_portal_config *pcfg;
137217 + int i;
137218 +
137219 + /* Stop dequeues on the portal */
137220 + qm_dqrr_sdqcr_set(&qm->p, 0);
137221 +
137222 + /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or
137223 + * something related to QM_PIRQ_EQCI, this may need fixing.
137224 + * Also, due to the prefetching model used for CI updates in the enqueue
137225 + * path, this update will only invalidate the CI cacheline *after*
137226 + * working on it, so we need to call this twice to ensure a full update
137227 + * irrespective of where the enqueue processing was at when the teardown
137228 + * began. */
137229 + qm_eqcr_cce_update(&qm->p);
137230 + qm_eqcr_cce_update(&qm->p);
137231 + pcfg = qm->config;
137232 +
137233 + free_irq(pcfg->public_cfg.irq, qm);
137234 +
137235 + kfree(qm->cgrs);
137236 + if (num_ceetms)
137237 + for (i = 0; i < num_ceetms; i++)
137238 + kfree(qm->ccgrs[i]);
137239 + qm_isr_finish(&qm->p);
137240 + qm_mc_finish(&qm->p);
137241 + qm_mr_finish(&qm->p);
137242 + qm_dqrr_finish(&qm->p);
137243 + qm_eqcr_finish(&qm->p);
137244 +
137245 + platform_device_del(qm->pdev);
137246 + platform_device_put(qm->pdev);
137247 +
137248 + qm->config = NULL;
137249 + if (qm->alloced)
137250 + kfree(qm);
137251 +}
137252 +
137253 +const struct qm_portal_config *qman_destroy_affine_portal(void)
137254 +{
137255 + /* We don't want to redirect if we're a slave, use "raw" */
137256 + struct qman_portal *qm = get_raw_affine_portal();
137257 + const struct qm_portal_config *pcfg;
137258 + int cpu;
137259 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137260 + if (qm->sharing_redirect) {
137261 + qm->sharing_redirect = NULL;
137262 + put_affine_portal();
137263 + return NULL;
137264 + }
137265 + qm->is_shared = 0;
137266 +#endif
137267 + pcfg = qm->config;
137268 + cpu = pcfg->public_cfg.cpu;
137269 +
137270 + qman_destroy_portal(qm);
137271 +
137272 + spin_lock(&affine_mask_lock);
137273 + cpumask_clear_cpu(cpu, &affine_mask);
137274 + spin_unlock(&affine_mask_lock);
137275 + put_affine_portal();
137276 + return pcfg;
137277 +}
137278 +
137279 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal *p)
137280 +{
137281 + return &p->config->public_cfg;
137282 +}
137283 +EXPORT_SYMBOL(qman_p_get_portal_config);
137284 +
137285 +const struct qman_portal_config *qman_get_portal_config(void)
137286 +{
137287 + struct qman_portal *p = get_affine_portal();
137288 + const struct qman_portal_config *ret = qman_p_get_portal_config(p);
137289 + put_affine_portal();
137290 + return ret;
137291 +}
137292 +EXPORT_SYMBOL(qman_get_portal_config);
137293 +
137294 +/* Inline helper to reduce nesting in __poll_portal_slow() */
137295 +static inline void fq_state_change(struct qman_portal *p, struct qman_fq *fq,
137296 + const struct qm_mr_entry *msg, u8 verb)
137297 +{
137298 + FQLOCK(fq);
137299 + switch (verb) {
137300 + case QM_MR_VERB_FQRL:
137301 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_ORL));
137302 + fq_clear(fq, QMAN_FQ_STATE_ORL);
137303 + table_del_fq(p, fq);
137304 + break;
137305 + case QM_MR_VERB_FQRN:
137306 + DPA_ASSERT((fq->state == qman_fq_state_parked) ||
137307 + (fq->state == qman_fq_state_sched));
137308 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_CHANGING));
137309 + fq_clear(fq, QMAN_FQ_STATE_CHANGING);
137310 + if (msg->fq.fqs & QM_MR_FQS_NOTEMPTY)
137311 + fq_set(fq, QMAN_FQ_STATE_NE);
137312 + if (msg->fq.fqs & QM_MR_FQS_ORLPRESENT)
137313 + fq_set(fq, QMAN_FQ_STATE_ORL);
137314 + else
137315 + table_del_fq(p, fq);
137316 + fq->state = qman_fq_state_retired;
137317 + break;
137318 + case QM_MR_VERB_FQPN:
137319 + DPA_ASSERT(fq->state == qman_fq_state_sched);
137320 + DPA_ASSERT(fq_isclear(fq, QMAN_FQ_STATE_CHANGING));
137321 + fq->state = qman_fq_state_parked;
137322 + }
137323 + FQUNLOCK(fq);
137324 +}
137325 +
137326 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is)
137327 +{
137328 + const struct qm_mr_entry *msg;
137329 + struct qm_mr_entry swapped_msg;
137330 + int k;
137331 +
137332 + if (is & QM_PIRQ_CSCI) {
137333 + struct qman_cgrs rr, c;
137334 + struct qm_mc_result *mcr;
137335 + struct qman_cgr *cgr;
137336 + unsigned long irqflags __maybe_unused;
137337 +
137338 + spin_lock_irqsave(&p->cgr_lock, irqflags);
137339 + /*
137340 + * The CSCI bit must be cleared _before_ issuing the
137341 + * Query Congestion State command, to ensure that a long
137342 + * CGR State Change callback cannot miss an intervening
137343 + * state change.
137344 + */
137345 + qm_isr_status_clear(&p->p, QM_PIRQ_CSCI);
137346 + qm_mc_start(&p->p);
137347 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
137348 + while (!(mcr = qm_mc_result(&p->p)))
137349 + cpu_relax();
137350 + for (k = 0; k < 8; k++)
137351 + mcr->querycongestion.state.__state[k] = be32_to_cpu(
137352 + mcr->querycongestion.state.__state[k]);
137353 + /* mask out the ones I'm not interested in */
137354 + qman_cgrs_and(&rr, (const struct qman_cgrs *)
137355 + &mcr->querycongestion.state, &p->cgrs[0]);
137356 + /* check previous snapshot for delta, enter/exit congestion */
137357 + qman_cgrs_xor(&c, &rr, &p->cgrs[1]);
137358 + /* update snapshot */
137359 + qman_cgrs_cp(&p->cgrs[1], &rr);
137360 + /* Invoke callback */
137361 + list_for_each_entry(cgr, &p->cgr_cbs, node)
137362 + if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
137363 + cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
137364 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
137365 + }
137366 + if (is & QM_PIRQ_CCSCI) {
137367 + struct qman_ccgrs rr, c, congestion_result;
137368 + struct qm_mc_result *mcr;
137369 + struct qm_mc_command *mcc;
137370 + struct qm_ceetm_ccg *ccg;
137371 + unsigned long irqflags __maybe_unused;
137372 + int i, j;
137373 +
137374 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
137375 + /*
137376 + * The CCSCI bit must be cleared _before_ issuing the
137377 + * Query Congestion State command, to ensure that a long
137378 + * CCGR State Change callback cannot miss an intervening
137379 + * state change.
137380 + */
137381 + qm_isr_status_clear(&p->p, QM_PIRQ_CCSCI);
137382 +
137383 + for (i = 0; i < num_ceetms; i++) {
137384 + for (j = 0; j < 2; j++) {
137385 + mcc = qm_mc_start(&p->p);
137386 + mcc->ccgr_query.ccgrid = cpu_to_be16(
137387 + CEETM_QUERY_CONGESTION_STATE | j);
137388 + mcc->ccgr_query.dcpid = i;
137389 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
137390 + while (!(mcr = qm_mc_result(&p->p)))
137391 + cpu_relax();
137392 + for (k = 0; k < 8; k++)
137393 + mcr->ccgr_query.congestion_state.state.
137394 + __state[k] = be32_to_cpu(
137395 + mcr->ccgr_query.
137396 + congestion_state.state.
137397 + __state[k]);
137398 + congestion_result.q[j] =
137399 + mcr->ccgr_query.congestion_state.state;
137400 + }
137401 + /* mask out the ones I'm not interested in */
137402 + qman_ccgrs_and(&rr, &congestion_result,
137403 + &p->ccgrs[i][0]);
137404 + /*
137405 + * check previous snapshot for delta, enter/exit
137406 + * congestion.
137407 + */
137408 + qman_ccgrs_xor(&c, &rr, &p->ccgrs[i][1]);
137409 + /* update snapshot */
137410 + qman_ccgrs_cp(&p->ccgrs[i][1], &rr);
137411 + /* Invoke callback */
137412 + list_for_each_entry(ccg, &p->ccgr_cbs[i], cb_node)
137413 + if (ccg->cb && qman_ccgrs_get(&c,
137414 + (ccg->parent->idx << 4) | ccg->idx))
137415 + ccg->cb(ccg, ccg->cb_ctx,
137416 + qman_ccgrs_get(&rr,
137417 + (ccg->parent->idx << 4)
137418 + | ccg->idx));
137419 + }
137420 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
137421 + }
137422 +
137423 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
137424 + if (is & QM_PIRQ_EQCI) {
137425 + unsigned long irqflags;
137426 + PORTAL_IRQ_LOCK(p, irqflags);
137427 + p->eqci_owned = NULL;
137428 + PORTAL_IRQ_UNLOCK(p, irqflags);
137429 + wake_up(&affine_queue);
137430 + }
137431 +#endif
137432 +
137433 + if (is & QM_PIRQ_EQRI) {
137434 + unsigned long irqflags __maybe_unused;
137435 + PORTAL_IRQ_LOCK(p, irqflags);
137436 + qm_eqcr_cce_update(&p->p);
137437 + qm_eqcr_set_ithresh(&p->p, 0);
137438 + PORTAL_IRQ_UNLOCK(p, irqflags);
137439 + wake_up(&affine_queue);
137440 + }
137441 +
137442 + if (is & QM_PIRQ_MRI) {
137443 + struct qman_fq *fq;
137444 + u8 verb, num = 0;
137445 +mr_loop:
137446 + qm_mr_pvb_update(&p->p);
137447 + msg = qm_mr_current(&p->p);
137448 + if (!msg)
137449 + goto mr_done;
137450 + swapped_msg = *msg;
137451 + hw_fd_to_cpu(&swapped_msg.ern.fd);
137452 + verb = msg->verb & QM_MR_VERB_TYPE_MASK;
137453 + /* The message is a software ERN iff the 0x20 bit is set */
137454 + if (verb & 0x20) {
137455 + switch (verb) {
137456 + case QM_MR_VERB_FQRNI:
137457 + /* nada, we drop FQRNIs on the floor */
137458 + break;
137459 + case QM_MR_VERB_FQRN:
137460 + case QM_MR_VERB_FQRL:
137461 + /* Lookup in the retirement table */
137462 + fq = table_find_fq(p, be32_to_cpu(msg->fq.fqid));
137463 + BUG_ON(!fq);
137464 + fq_state_change(p, fq, &swapped_msg, verb);
137465 + if (fq->cb.fqs)
137466 + fq->cb.fqs(p, fq, &swapped_msg);
137467 + break;
137468 + case QM_MR_VERB_FQPN:
137469 + /* Parked */
137470 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137471 + fq = get_fq_table_entry(
137472 + be32_to_cpu(msg->fq.contextB));
137473 +#else
137474 + fq = (void *)(uintptr_t)
137475 + be32_to_cpu(msg->fq.contextB);
137476 +#endif
137477 + fq_state_change(p, fq, msg, verb);
137478 + if (fq->cb.fqs)
137479 + fq->cb.fqs(p, fq, &swapped_msg);
137480 + break;
137481 + case QM_MR_VERB_DC_ERN:
137482 + /* DCP ERN */
137483 + if (p->cb_dc_ern)
137484 + p->cb_dc_ern(p, msg);
137485 + else if (cb_dc_ern)
137486 + cb_dc_ern(p, msg);
137487 + else {
137488 + static int warn_once;
137489 + if (!warn_once) {
137490 + pr_crit("Leaking DCP ERNs!\n");
137491 + warn_once = 1;
137492 + }
137493 + }
137494 + break;
137495 + default:
137496 + pr_crit("Invalid MR verb 0x%02x\n", verb);
137497 + }
137498 + } else {
137499 + /* Its a software ERN */
137500 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137501 + fq = get_fq_table_entry(be32_to_cpu(msg->ern.tag));
137502 +#else
137503 + fq = (void *)(uintptr_t)be32_to_cpu(msg->ern.tag);
137504 +#endif
137505 + fq->cb.ern(p, fq, &swapped_msg);
137506 + }
137507 + num++;
137508 + qm_mr_next(&p->p);
137509 + goto mr_loop;
137510 +mr_done:
137511 + qm_mr_cci_consume(&p->p, num);
137512 + }
137513 + /*
137514 + * QM_PIRQ_CSCI/CCSCI has already been cleared, as part of its specific
137515 + * processing. If that interrupt source has meanwhile been re-asserted,
137516 + * we mustn't clear it here (or in the top-level interrupt handler).
137517 + */
137518 + return is & (QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI);
137519 +}
137520 +
137521 +/* remove some slowish-path stuff from the "fast path" and make sure it isn't
137522 + * inlined. */
137523 +static noinline void clear_vdqcr(struct qman_portal *p, struct qman_fq *fq)
137524 +{
137525 + p->vdqcr_owned = NULL;
137526 + FQLOCK(fq);
137527 + fq_clear(fq, QMAN_FQ_STATE_VDQCR);
137528 + FQUNLOCK(fq);
137529 + wake_up(&affine_queue);
137530 +}
137531 +
137532 +/* Copy a DQRR entry ensuring reads reach QBMan in order */
137533 +static inline void safe_copy_dqrr(struct qm_dqrr_entry *dst,
137534 + const struct qm_dqrr_entry *src)
137535 +{
137536 + int i = 0;
137537 + const u64 *s64 = (u64*)src;
137538 + u64 *d64 = (u64*)dst;
137539 +
137540 + /* DQRR only has 32 bytes of valid data so only need to
137541 + * copy 4 - 64 bit values */
137542 + *d64 = *s64;
137543 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
137544 + {
137545 + u32 res, zero = 0;
137546 + /* Create a dependancy after copying first bytes ensures no wrap
137547 + transaction generated to QBMan */
137548 + /* Logical AND the value pointed to by s64 with 0x0 and
137549 + store the result in res */
137550 + asm volatile("and %[result], %[in1], %[in2]"
137551 + : [result] "=r" (res)
137552 + : [in1] "r" (zero), [in2] "r" (*s64)
137553 + : "memory");
137554 + /* Add res to s64 - this creates a dependancy on the result of
137555 + reading the value of s64 before the next read. The side
137556 + effect of this is that the core must stall until the first
137557 + aligned read is complete therefore preventing a WRAP
137558 + transaction to be seen by the QBMan */
137559 + asm volatile("add %[result], %[in1], %[in2]"
137560 + : [result] "=r" (s64)
137561 + : [in1] "r" (res), [in2] "r" (s64)
137562 + : "memory");
137563 + }
137564 +#endif
137565 + /* Copy the last 3 64 bit parts */
137566 + d64++; s64++;
137567 + for (;i<3; i++)
137568 + *d64++ = *s64++;
137569 +}
137570 +
137571 +/* Look: no locks, no irq_save()s, no preempt_disable()s! :-) The only states
137572 + * that would conflict with other things if they ran at the same time on the
137573 + * same cpu are;
137574 + *
137575 + * (i) setting/clearing vdqcr_owned, and
137576 + * (ii) clearing the NE (Not Empty) flag.
137577 + *
137578 + * Both are safe. Because;
137579 + *
137580 + * (i) this clearing can only occur after qman_volatile_dequeue() has set the
137581 + * vdqcr_owned field (which it does before setting VDQCR), and
137582 + * qman_volatile_dequeue() blocks interrupts and preemption while this is
137583 + * done so that we can't interfere.
137584 + * (ii) the NE flag is only cleared after qman_retire_fq() has set it, and as
137585 + * with (i) that API prevents us from interfering until it's safe.
137586 + *
137587 + * The good thing is that qman_volatile_dequeue() and qman_retire_fq() run far
137588 + * less frequently (ie. per-FQ) than __poll_portal_fast() does, so the nett
137589 + * advantage comes from this function not having to "lock" anything at all.
137590 + *
137591 + * Note also that the callbacks are invoked at points which are safe against the
137592 + * above potential conflicts, but that this function itself is not re-entrant
137593 + * (this is because the function tracks one end of each FIFO in the portal and
137594 + * we do *not* want to lock that). So the consequence is that it is safe for
137595 + * user callbacks to call into any Qman API *except* qman_poll() (as that's the
137596 + * sole API that could be invoking the callback through this function).
137597 + */
137598 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
137599 + unsigned int poll_limit)
137600 +{
137601 + const struct qm_dqrr_entry *dq;
137602 + struct qman_fq *fq;
137603 + enum qman_cb_dqrr_result res;
137604 + unsigned int limit = 0;
137605 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137606 + struct qm_dqrr_entry *shadow;
137607 + const struct qm_dqrr_entry *orig_dq;
137608 +#endif
137609 +loop:
137610 + qm_dqrr_pvb_update(&p->p);
137611 + dq = qm_dqrr_current(&p->p);
137612 + if (!dq)
137613 + goto done;
137614 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137615 + /* If running on an LE system the fields of the
137616 + dequeue entry must be swapped. Because the
137617 + QMan HW will ignore writes the DQRR entry is
137618 + copied and the index stored within the copy */
137619 + shadow = &p->shadow_dqrr[DQRR_PTR2IDX(dq)];
137620 + /* Use safe copy here to avoid WRAP transaction */
137621 + safe_copy_dqrr(shadow, dq);
137622 + orig_dq = dq;
137623 + dq = shadow;
137624 + shadow->fqid = be32_to_cpu(shadow->fqid);
137625 + shadow->contextB = be32_to_cpu(shadow->contextB);
137626 + shadow->seqnum = be16_to_cpu(shadow->seqnum);
137627 + hw_fd_to_cpu(&shadow->fd);
137628 +#endif
137629 + if (dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
137630 + /* VDQCR: don't trust contextB as the FQ may have been
137631 + * configured for h/w consumption and we're draining it
137632 + * post-retirement. */
137633 + fq = p->vdqcr_owned;
137634 + /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
137635 + * to check for clearing it when doing volatile dequeues. It's
137636 + * one less thing to check in the critical path (SDQCR). */
137637 + if (dq->stat & QM_DQRR_STAT_FQ_EMPTY)
137638 + fq_clear(fq, QMAN_FQ_STATE_NE);
137639 + /* this is duplicated from the SDQCR code, but we have stuff to
137640 + * do before *and* after this callback, and we don't want
137641 + * multiple if()s in the critical path (SDQCR). */
137642 + res = fq->cb.dqrr(p, fq, dq);
137643 + if (res == qman_cb_dqrr_stop)
137644 + goto done;
137645 + /* Check for VDQCR completion */
137646 + if (dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
137647 + clear_vdqcr(p, fq);
137648 + } else {
137649 + /* SDQCR: contextB points to the FQ */
137650 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137651 + fq = get_fq_table_entry(dq->contextB);
137652 +#else
137653 + fq = (void *)(uintptr_t)dq->contextB;
137654 +#endif
137655 + /* Now let the callback do its stuff */
137656 + res = fq->cb.dqrr(p, fq, dq);
137657 +
137658 + /* The callback can request that we exit without consuming this
137659 + * entry nor advancing; */
137660 + if (res == qman_cb_dqrr_stop)
137661 + goto done;
137662 + }
137663 + /* Interpret 'dq' from a driver perspective. */
137664 + /* Parking isn't possible unless HELDACTIVE was set. NB,
137665 + * FORCEELIGIBLE implies HELDACTIVE, so we only need to
137666 + * check for HELDACTIVE to cover both. */
137667 + DPA_ASSERT((dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
137668 + (res != qman_cb_dqrr_park));
137669 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137670 + if (res != qman_cb_dqrr_defer)
137671 + qm_dqrr_cdc_consume_1ptr(&p->p, orig_dq,
137672 + (res == qman_cb_dqrr_park));
137673 +#else
137674 + /* Defer just means "skip it, I'll consume it myself later on" */
137675 + if (res != qman_cb_dqrr_defer)
137676 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, (res == qman_cb_dqrr_park));
137677 +#endif
137678 + /* Move forward */
137679 + qm_dqrr_next(&p->p);
137680 + /* Entry processed and consumed, increment our counter. The callback can
137681 + * request that we exit after consuming the entry, and we also exit if
137682 + * we reach our processing limit, so loop back only if neither of these
137683 + * conditions is met. */
137684 + if ((++limit < poll_limit) && (res != qman_cb_dqrr_consume_stop))
137685 + goto loop;
137686 +done:
137687 + return limit;
137688 +}
137689 +
137690 +u32 qman_irqsource_get(void)
137691 +{
137692 + /* "irqsource" and "poll" APIs mustn't redirect when sharing, they
137693 + * should shut the user out if they are not the primary CPU hosting the
137694 + * portal. That's why we use the "raw" interface. */
137695 + struct qman_portal *p = get_raw_affine_portal();
137696 + u32 ret = p->irq_sources & QM_PIRQ_VISIBLE;
137697 + put_affine_portal();
137698 + return ret;
137699 +}
137700 +EXPORT_SYMBOL(qman_irqsource_get);
137701 +
137702 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits __maybe_unused)
137703 +{
137704 + __maybe_unused unsigned long irqflags;
137705 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137706 + if (p->sharing_redirect)
137707 + return -EINVAL;
137708 + else
137709 +#endif
137710 + {
137711 + bits = bits & QM_PIRQ_VISIBLE;
137712 + PORTAL_IRQ_LOCK(p, irqflags);
137713 +
137714 + /* Clear any previously remaining interrupt conditions in
137715 + * QCSP_ISR. This prevents raising a false interrupt when
137716 + * interrupt conditions are enabled in QCSP_IER.
137717 + */
137718 + qm_isr_status_clear(&p->p, bits);
137719 + set_bits(bits, &p->irq_sources);
137720 + qm_isr_enable_write(&p->p, p->irq_sources);
137721 + PORTAL_IRQ_UNLOCK(p, irqflags);
137722 + }
137723 + return 0;
137724 +}
137725 +EXPORT_SYMBOL(qman_p_irqsource_add);
137726 +
137727 +int qman_irqsource_add(u32 bits __maybe_unused)
137728 +{
137729 + struct qman_portal *p = get_raw_affine_portal();
137730 + int ret;
137731 + ret = qman_p_irqsource_add(p, bits);
137732 + put_affine_portal();
137733 + return ret;
137734 +}
137735 +EXPORT_SYMBOL(qman_irqsource_add);
137736 +
137737 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits)
137738 +{
137739 + __maybe_unused unsigned long irqflags;
137740 + u32 ier;
137741 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137742 + if (p->sharing_redirect) {
137743 + put_affine_portal();
137744 + return -EINVAL;
137745 + }
137746 +#endif
137747 + /* Our interrupt handler only processes+clears status register bits that
137748 + * are in p->irq_sources. As we're trimming that mask, if one of them
137749 + * were to assert in the status register just before we remove it from
137750 + * the enable register, there would be an interrupt-storm when we
137751 + * release the IRQ lock. So we wait for the enable register update to
137752 + * take effect in h/w (by reading it back) and then clear all other bits
137753 + * in the status register. Ie. we clear them from ISR once it's certain
137754 + * IER won't allow them to reassert. */
137755 + PORTAL_IRQ_LOCK(p, irqflags);
137756 + bits &= QM_PIRQ_VISIBLE;
137757 + clear_bits(bits, &p->irq_sources);
137758 + qm_isr_enable_write(&p->p, p->irq_sources);
137759 +
137760 + ier = qm_isr_enable_read(&p->p);
137761 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
137762 + * data-dependency, ie. to protect against re-ordering. */
137763 + qm_isr_status_clear(&p->p, ~ier);
137764 + PORTAL_IRQ_UNLOCK(p, irqflags);
137765 + return 0;
137766 +}
137767 +EXPORT_SYMBOL(qman_p_irqsource_remove);
137768 +
137769 +int qman_irqsource_remove(u32 bits)
137770 +{
137771 + struct qman_portal *p = get_raw_affine_portal();
137772 + int ret;
137773 + ret = qman_p_irqsource_remove(p, bits);
137774 + put_affine_portal();
137775 + return ret;
137776 +}
137777 +EXPORT_SYMBOL(qman_irqsource_remove);
137778 +
137779 +const cpumask_t *qman_affine_cpus(void)
137780 +{
137781 + return &affine_mask;
137782 +}
137783 +EXPORT_SYMBOL(qman_affine_cpus);
137784 +
137785 +u16 qman_affine_channel(int cpu)
137786 +{
137787 + if (cpu < 0) {
137788 + struct qman_portal *portal = get_raw_affine_portal();
137789 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137790 + BUG_ON(portal->sharing_redirect);
137791 +#endif
137792 + cpu = portal->config->public_cfg.cpu;
137793 + put_affine_portal();
137794 + }
137795 + BUG_ON(!cpumask_test_cpu(cpu, &affine_mask));
137796 + return affine_channels[cpu];
137797 +}
137798 +EXPORT_SYMBOL(qman_affine_channel);
137799 +
137800 +void *qman_get_affine_portal(int cpu)
137801 +{
137802 + return affine_portals[cpu];
137803 +}
137804 +EXPORT_SYMBOL(qman_get_affine_portal);
137805 +
137806 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit)
137807 +{
137808 + int ret;
137809 +
137810 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137811 + if (unlikely(p->sharing_redirect))
137812 + ret = -EINVAL;
137813 + else
137814 +#endif
137815 + {
137816 + BUG_ON(p->irq_sources & QM_PIRQ_DQRI);
137817 + ret = __poll_portal_fast(p, limit);
137818 + }
137819 + return ret;
137820 +}
137821 +EXPORT_SYMBOL(qman_p_poll_dqrr);
137822 +
137823 +int qman_poll_dqrr(unsigned int limit)
137824 +{
137825 + struct qman_portal *p = get_poll_portal();
137826 + int ret;
137827 + ret = qman_p_poll_dqrr(p, limit);
137828 + put_poll_portal();
137829 + return ret;
137830 +}
137831 +EXPORT_SYMBOL(qman_poll_dqrr);
137832 +
137833 +u32 qman_p_poll_slow(struct qman_portal *p)
137834 +{
137835 + u32 ret;
137836 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137837 + if (unlikely(p->sharing_redirect))
137838 + ret = (u32)-1;
137839 + else
137840 +#endif
137841 + {
137842 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
137843 + ret = __poll_portal_slow(p, is);
137844 + qm_isr_status_clear(&p->p, ret);
137845 + }
137846 + return ret;
137847 +}
137848 +EXPORT_SYMBOL(qman_p_poll_slow);
137849 +
137850 +u32 qman_poll_slow(void)
137851 +{
137852 + struct qman_portal *p = get_poll_portal();
137853 + u32 ret;
137854 + ret = qman_p_poll_slow(p);
137855 + put_poll_portal();
137856 + return ret;
137857 +}
137858 +EXPORT_SYMBOL(qman_poll_slow);
137859 +
137860 +/* Legacy wrapper */
137861 +void qman_p_poll(struct qman_portal *p)
137862 +{
137863 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137864 + if (unlikely(p->sharing_redirect))
137865 + return;
137866 +#endif
137867 + if ((~p->irq_sources) & QM_PIRQ_SLOW) {
137868 + if (!(p->slowpoll--)) {
137869 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
137870 + u32 active = __poll_portal_slow(p, is);
137871 + if (active) {
137872 + qm_isr_status_clear(&p->p, active);
137873 + p->slowpoll = SLOW_POLL_BUSY;
137874 + } else
137875 + p->slowpoll = SLOW_POLL_IDLE;
137876 + }
137877 + }
137878 + if ((~p->irq_sources) & QM_PIRQ_DQRI)
137879 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
137880 +}
137881 +EXPORT_SYMBOL(qman_p_poll);
137882 +
137883 +void qman_poll(void)
137884 +{
137885 + struct qman_portal *p = get_poll_portal();
137886 + qman_p_poll(p);
137887 + put_poll_portal();
137888 +}
137889 +EXPORT_SYMBOL(qman_poll);
137890 +
137891 +void qman_p_stop_dequeues(struct qman_portal *p)
137892 +{
137893 + qman_stop_dequeues_ex(p);
137894 +}
137895 +EXPORT_SYMBOL(qman_p_stop_dequeues);
137896 +
137897 +void qman_stop_dequeues(void)
137898 +{
137899 + struct qman_portal *p = get_affine_portal();
137900 + qman_p_stop_dequeues(p);
137901 + put_affine_portal();
137902 +}
137903 +EXPORT_SYMBOL(qman_stop_dequeues);
137904 +
137905 +void qman_p_start_dequeues(struct qman_portal *p)
137906 +{
137907 + unsigned long irqflags __maybe_unused;
137908 + PORTAL_IRQ_LOCK(p, irqflags);
137909 + DPA_ASSERT(p->dqrr_disable_ref > 0);
137910 + if (!(--p->dqrr_disable_ref))
137911 + qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL);
137912 + PORTAL_IRQ_UNLOCK(p, irqflags);
137913 +}
137914 +EXPORT_SYMBOL(qman_p_start_dequeues);
137915 +
137916 +void qman_start_dequeues(void)
137917 +{
137918 + struct qman_portal *p = get_affine_portal();
137919 + qman_p_start_dequeues(p);
137920 + put_affine_portal();
137921 +}
137922 +EXPORT_SYMBOL(qman_start_dequeues);
137923 +
137924 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools)
137925 +{
137926 + unsigned long irqflags __maybe_unused;
137927 + PORTAL_IRQ_LOCK(p, irqflags);
137928 + pools &= p->config->public_cfg.pools;
137929 + p->sdqcr |= pools;
137930 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137931 + PORTAL_IRQ_UNLOCK(p, irqflags);
137932 +}
137933 +EXPORT_SYMBOL(qman_p_static_dequeue_add);
137934 +
137935 +void qman_static_dequeue_add(u32 pools)
137936 +{
137937 + struct qman_portal *p = get_affine_portal();
137938 + qman_p_static_dequeue_add(p, pools);
137939 + put_affine_portal();
137940 +}
137941 +EXPORT_SYMBOL(qman_static_dequeue_add);
137942 +
137943 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools)
137944 +{
137945 + unsigned long irqflags __maybe_unused;
137946 + PORTAL_IRQ_LOCK(p, irqflags);
137947 + pools &= p->config->public_cfg.pools;
137948 + p->sdqcr &= ~pools;
137949 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137950 + PORTAL_IRQ_UNLOCK(p, irqflags);
137951 +}
137952 +EXPORT_SYMBOL(qman_p_static_dequeue_del);
137953 +
137954 +void qman_static_dequeue_del(u32 pools)
137955 +{
137956 + struct qman_portal *p = get_affine_portal();
137957 + qman_p_static_dequeue_del(p, pools);
137958 + put_affine_portal();
137959 +}
137960 +EXPORT_SYMBOL(qman_static_dequeue_del);
137961 +
137962 +u32 qman_p_static_dequeue_get(struct qman_portal *p)
137963 +{
137964 + return p->sdqcr;
137965 +}
137966 +EXPORT_SYMBOL(qman_p_static_dequeue_get);
137967 +
137968 +u32 qman_static_dequeue_get(void)
137969 +{
137970 + struct qman_portal *p = get_affine_portal();
137971 + u32 ret = qman_p_static_dequeue_get(p);
137972 + put_affine_portal();
137973 + return ret;
137974 +}
137975 +EXPORT_SYMBOL(qman_static_dequeue_get);
137976 +
137977 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
137978 + int park_request)
137979 +{
137980 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, park_request);
137981 +}
137982 +EXPORT_SYMBOL(qman_p_dca);
137983 +
137984 +void qman_dca(struct qm_dqrr_entry *dq, int park_request)
137985 +{
137986 + struct qman_portal *p = get_affine_portal();
137987 + qman_p_dca(p, dq, park_request);
137988 + put_affine_portal();
137989 +}
137990 +EXPORT_SYMBOL(qman_dca);
137991 +
137992 +/*******************/
137993 +/* Frame queue API */
137994 +/*******************/
137995 +
137996 +static const char *mcr_result_str(u8 result)
137997 +{
137998 + switch (result) {
137999 + case QM_MCR_RESULT_NULL:
138000 + return "QM_MCR_RESULT_NULL";
138001 + case QM_MCR_RESULT_OK:
138002 + return "QM_MCR_RESULT_OK";
138003 + case QM_MCR_RESULT_ERR_FQID:
138004 + return "QM_MCR_RESULT_ERR_FQID";
138005 + case QM_MCR_RESULT_ERR_FQSTATE:
138006 + return "QM_MCR_RESULT_ERR_FQSTATE";
138007 + case QM_MCR_RESULT_ERR_NOTEMPTY:
138008 + return "QM_MCR_RESULT_ERR_NOTEMPTY";
138009 + case QM_MCR_RESULT_PENDING:
138010 + return "QM_MCR_RESULT_PENDING";
138011 + case QM_MCR_RESULT_ERR_BADCOMMAND:
138012 + return "QM_MCR_RESULT_ERR_BADCOMMAND";
138013 + }
138014 + return "<unknown MCR result>";
138015 +}
138016 +
138017 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq)
138018 +{
138019 + struct qm_fqd fqd;
138020 + struct qm_mcr_queryfq_np np;
138021 + struct qm_mc_command *mcc;
138022 + struct qm_mc_result *mcr;
138023 + struct qman_portal *p;
138024 + unsigned long irqflags __maybe_unused;
138025 +
138026 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID) {
138027 + int ret = qman_alloc_fqid(&fqid);
138028 + if (ret)
138029 + return ret;
138030 + }
138031 + spin_lock_init(&fq->fqlock);
138032 + fq->fqid = fqid;
138033 + fq->flags = flags;
138034 + fq->state = qman_fq_state_oos;
138035 + fq->cgr_groupid = 0;
138036 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138037 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
138038 + return -ENOMEM;
138039 +#endif
138040 + if (!(flags & QMAN_FQ_FLAG_AS_IS) || (flags & QMAN_FQ_FLAG_NO_MODIFY))
138041 + return 0;
138042 + /* Everything else is AS_IS support */
138043 + p = get_affine_portal();
138044 + PORTAL_IRQ_LOCK(p, irqflags);
138045 + mcc = qm_mc_start(&p->p);
138046 + mcc->queryfq.fqid = cpu_to_be32(fqid);
138047 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
138048 + while (!(mcr = qm_mc_result(&p->p)))
138049 + cpu_relax();
138050 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ);
138051 + if (mcr->result != QM_MCR_RESULT_OK) {
138052 + pr_err("QUERYFQ failed: %s\n", mcr_result_str(mcr->result));
138053 + goto err;
138054 + }
138055 + fqd = mcr->queryfq.fqd;
138056 + hw_fqd_to_cpu(&fqd);
138057 + mcc = qm_mc_start(&p->p);
138058 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
138059 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
138060 + while (!(mcr = qm_mc_result(&p->p)))
138061 + cpu_relax();
138062 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP);
138063 + if (mcr->result != QM_MCR_RESULT_OK) {
138064 + pr_err("QUERYFQ_NP failed: %s\n", mcr_result_str(mcr->result));
138065 + goto err;
138066 + }
138067 + np = mcr->queryfq_np;
138068 + /* Phew, have queryfq and queryfq_np results, stitch together
138069 + * the FQ object from those. */
138070 + fq->cgr_groupid = fqd.cgid;
138071 + switch (np.state & QM_MCR_NP_STATE_MASK) {
138072 + case QM_MCR_NP_STATE_OOS:
138073 + break;
138074 + case QM_MCR_NP_STATE_RETIRED:
138075 + fq->state = qman_fq_state_retired;
138076 + if (np.frm_cnt)
138077 + fq_set(fq, QMAN_FQ_STATE_NE);
138078 + break;
138079 + case QM_MCR_NP_STATE_TEN_SCHED:
138080 + case QM_MCR_NP_STATE_TRU_SCHED:
138081 + case QM_MCR_NP_STATE_ACTIVE:
138082 + fq->state = qman_fq_state_sched;
138083 + if (np.state & QM_MCR_NP_STATE_R)
138084 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
138085 + break;
138086 + case QM_MCR_NP_STATE_PARKED:
138087 + fq->state = qman_fq_state_parked;
138088 + break;
138089 + default:
138090 + DPA_ASSERT(NULL == "invalid FQ state");
138091 + }
138092 + if (fqd.fq_ctrl & QM_FQCTRL_CGE)
138093 + fq->state |= QMAN_FQ_STATE_CGR_EN;
138094 + PORTAL_IRQ_UNLOCK(p, irqflags);
138095 + put_affine_portal();
138096 + return 0;
138097 +err:
138098 + PORTAL_IRQ_UNLOCK(p, irqflags);
138099 + put_affine_portal();
138100 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID)
138101 + qman_release_fqid(fqid);
138102 + return -EIO;
138103 +}
138104 +EXPORT_SYMBOL(qman_create_fq);
138105 +
138106 +void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused)
138107 +{
138108 +
138109 + /* We don't need to lock the FQ as it is a pre-condition that the FQ be
138110 + * quiesced. Instead, run some checks. */
138111 + switch (fq->state) {
138112 + case qman_fq_state_parked:
138113 + DPA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED);
138114 + case qman_fq_state_oos:
138115 + if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID))
138116 + qman_release_fqid(fq->fqid);
138117 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138118 + clear_fq_table_entry(fq->key);
138119 +#endif
138120 + return;
138121 + default:
138122 + break;
138123 + }
138124 + DPA_ASSERT(NULL == "qman_free_fq() on unquiesced FQ!");
138125 +}
138126 +EXPORT_SYMBOL(qman_destroy_fq);
138127 +
138128 +u32 qman_fq_fqid(struct qman_fq *fq)
138129 +{
138130 + return fq->fqid;
138131 +}
138132 +EXPORT_SYMBOL(qman_fq_fqid);
138133 +
138134 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags)
138135 +{
138136 + if (state)
138137 + *state = fq->state;
138138 + if (flags)
138139 + *flags = fq->flags;
138140 +}
138141 +EXPORT_SYMBOL(qman_fq_state);
138142 +
138143 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts)
138144 +{
138145 + struct qm_mc_command *mcc;
138146 + struct qm_mc_result *mcr;
138147 + struct qman_portal *p;
138148 + unsigned long irqflags __maybe_unused;
138149 + u8 res, myverb = (flags & QMAN_INITFQ_FLAG_SCHED) ?
138150 + QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED;
138151 +
138152 + if ((fq->state != qman_fq_state_oos) &&
138153 + (fq->state != qman_fq_state_parked))
138154 + return -EINVAL;
138155 +#ifdef CONFIG_FSL_DPA_CHECKING
138156 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
138157 + return -EINVAL;
138158 +#endif
138159 + if (opts && (opts->we_mask & QM_INITFQ_WE_OAC)) {
138160 + /* And can't be set at the same time as TDTHRESH */
138161 + if (opts->we_mask & QM_INITFQ_WE_TDTHRESH)
138162 + return -EINVAL;
138163 + }
138164 + /* Issue an INITFQ_[PARKED|SCHED] management command */
138165 + p = get_affine_portal();
138166 + PORTAL_IRQ_LOCK(p, irqflags);
138167 + FQLOCK(fq);
138168 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
138169 + ((fq->state != qman_fq_state_oos) &&
138170 + (fq->state != qman_fq_state_parked)))) {
138171 + FQUNLOCK(fq);
138172 + PORTAL_IRQ_UNLOCK(p, irqflags);
138173 + put_affine_portal();
138174 + return -EBUSY;
138175 + }
138176 + mcc = qm_mc_start(&p->p);
138177 + if (opts)
138178 + mcc->initfq = *opts;
138179 + mcc->initfq.fqid = cpu_to_be32(fq->fqid);
138180 + mcc->initfq.count = 0;
138181 +
138182 + /* If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a
138183 + * demux pointer. Otherwise, the caller-provided value is allowed to
138184 + * stand, don't overwrite it. */
138185 + if (fq_isclear(fq, QMAN_FQ_FLAG_TO_DCPORTAL)) {
138186 + dma_addr_t phys_fq;
138187 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTB;
138188 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138189 + mcc->initfq.fqd.context_b = fq->key;
138190 +#else
138191 + mcc->initfq.fqd.context_b = (u32)(uintptr_t)fq;
138192 +#endif
138193 + /* and the physical address - NB, if the user wasn't trying to
138194 + * set CONTEXTA, clear the stashing settings. */
138195 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_CONTEXTA)) {
138196 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
138197 + memset(&mcc->initfq.fqd.context_a, 0,
138198 + sizeof(mcc->initfq.fqd.context_a));
138199 + } else {
138200 + phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq),
138201 + DMA_TO_DEVICE);
138202 + qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq);
138203 + }
138204 + }
138205 + if (flags & QMAN_INITFQ_FLAG_LOCAL) {
138206 + mcc->initfq.fqd.dest.channel = p->config->public_cfg.channel;
138207 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_DESTWQ)) {
138208 + mcc->initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
138209 + mcc->initfq.fqd.dest.wq = 4;
138210 + }
138211 + }
138212 + mcc->initfq.we_mask = cpu_to_be16(mcc->initfq.we_mask);
138213 + cpu_to_hw_fqd(&mcc->initfq.fqd);
138214 + qm_mc_commit(&p->p, myverb);
138215 + while (!(mcr = qm_mc_result(&p->p)))
138216 + cpu_relax();
138217 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
138218 + res = mcr->result;
138219 + if (res != QM_MCR_RESULT_OK) {
138220 + FQUNLOCK(fq);
138221 + PORTAL_IRQ_UNLOCK(p, irqflags);
138222 + put_affine_portal();
138223 + return -EIO;
138224 + }
138225 + if (opts) {
138226 + if (opts->we_mask & QM_INITFQ_WE_FQCTRL) {
138227 + if (opts->fqd.fq_ctrl & QM_FQCTRL_CGE)
138228 + fq_set(fq, QMAN_FQ_STATE_CGR_EN);
138229 + else
138230 + fq_clear(fq, QMAN_FQ_STATE_CGR_EN);
138231 + }
138232 + if (opts->we_mask & QM_INITFQ_WE_CGID)
138233 + fq->cgr_groupid = opts->fqd.cgid;
138234 + }
138235 + fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ?
138236 + qman_fq_state_sched : qman_fq_state_parked;
138237 + FQUNLOCK(fq);
138238 + PORTAL_IRQ_UNLOCK(p, irqflags);
138239 + put_affine_portal();
138240 + return 0;
138241 +}
138242 +EXPORT_SYMBOL(qman_init_fq);
138243 +
138244 +int qman_schedule_fq(struct qman_fq *fq)
138245 +{
138246 + struct qm_mc_command *mcc;
138247 + struct qm_mc_result *mcr;
138248 + struct qman_portal *p;
138249 + unsigned long irqflags __maybe_unused;
138250 + int ret = 0;
138251 + u8 res;
138252 +
138253 + if (fq->state != qman_fq_state_parked)
138254 + return -EINVAL;
138255 +#ifdef CONFIG_FSL_DPA_CHECKING
138256 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
138257 + return -EINVAL;
138258 +#endif
138259 + /* Issue a ALTERFQ_SCHED management command */
138260 + p = get_affine_portal();
138261 + PORTAL_IRQ_LOCK(p, irqflags);
138262 + FQLOCK(fq);
138263 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
138264 + (fq->state != qman_fq_state_parked))) {
138265 + ret = -EBUSY;
138266 + goto out;
138267 + }
138268 + mcc = qm_mc_start(&p->p);
138269 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
138270 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED);
138271 + while (!(mcr = qm_mc_result(&p->p)))
138272 + cpu_relax();
138273 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED);
138274 + res = mcr->result;
138275 + if (res != QM_MCR_RESULT_OK) {
138276 + ret = -EIO;
138277 + goto out;
138278 + }
138279 + fq->state = qman_fq_state_sched;
138280 +out:
138281 + FQUNLOCK(fq);
138282 + PORTAL_IRQ_UNLOCK(p, irqflags);
138283 + put_affine_portal();
138284 + return ret;
138285 +}
138286 +EXPORT_SYMBOL(qman_schedule_fq);
138287 +
138288 +int qman_retire_fq(struct qman_fq *fq, u32 *flags)
138289 +{
138290 + struct qm_mc_command *mcc;
138291 + struct qm_mc_result *mcr;
138292 + struct qman_portal *p;
138293 + unsigned long irqflags __maybe_unused;
138294 + int rval;
138295 + u8 res;
138296 +
138297 + if ((fq->state != qman_fq_state_parked) &&
138298 + (fq->state != qman_fq_state_sched))
138299 + return -EINVAL;
138300 +#ifdef CONFIG_FSL_DPA_CHECKING
138301 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
138302 + return -EINVAL;
138303 +#endif
138304 + p = get_affine_portal();
138305 + PORTAL_IRQ_LOCK(p, irqflags);
138306 + FQLOCK(fq);
138307 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
138308 + (fq->state == qman_fq_state_retired) ||
138309 + (fq->state == qman_fq_state_oos))) {
138310 + rval = -EBUSY;
138311 + goto out;
138312 + }
138313 + rval = table_push_fq(p, fq);
138314 + if (rval)
138315 + goto out;
138316 + mcc = qm_mc_start(&p->p);
138317 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
138318 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE);
138319 + while (!(mcr = qm_mc_result(&p->p)))
138320 + cpu_relax();
138321 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_RETIRE);
138322 + res = mcr->result;
138323 + /* "Elegant" would be to treat OK/PENDING the same way; set CHANGING,
138324 + * and defer the flags until FQRNI or FQRN (respectively) show up. But
138325 + * "Friendly" is to process OK immediately, and not set CHANGING. We do
138326 + * friendly, otherwise the caller doesn't necessarily have a fully
138327 + * "retired" FQ on return even if the retirement was immediate. However
138328 + * this does mean some code duplication between here and
138329 + * fq_state_change(). */
138330 + if (likely(res == QM_MCR_RESULT_OK)) {
138331 + rval = 0;
138332 + /* Process 'fq' right away, we'll ignore FQRNI */
138333 + if (mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY)
138334 + fq_set(fq, QMAN_FQ_STATE_NE);
138335 + if (mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)
138336 + fq_set(fq, QMAN_FQ_STATE_ORL);
138337 + else
138338 + table_del_fq(p, fq);
138339 + if (flags)
138340 + *flags = fq->flags;
138341 + fq->state = qman_fq_state_retired;
138342 + if (fq->cb.fqs) {
138343 + /* Another issue with supporting "immediate" retirement
138344 + * is that we're forced to drop FQRNIs, because by the
138345 + * time they're seen it may already be "too late" (the
138346 + * fq may have been OOS'd and free()'d already). But if
138347 + * the upper layer wants a callback whether it's
138348 + * immediate or not, we have to fake a "MR" entry to
138349 + * look like an FQRNI... */
138350 + struct qm_mr_entry msg;
138351 + msg.verb = QM_MR_VERB_FQRNI;
138352 + msg.fq.fqs = mcr->alterfq.fqs;
138353 + msg.fq.fqid = fq->fqid;
138354 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138355 + msg.fq.contextB = fq->key;
138356 +#else
138357 + msg.fq.contextB = (u32)(uintptr_t)fq;
138358 +#endif
138359 + fq->cb.fqs(p, fq, &msg);
138360 + }
138361 + } else if (res == QM_MCR_RESULT_PENDING) {
138362 + rval = 1;
138363 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
138364 + } else {
138365 + rval = -EIO;
138366 + table_del_fq(p, fq);
138367 + }
138368 +out:
138369 + FQUNLOCK(fq);
138370 + PORTAL_IRQ_UNLOCK(p, irqflags);
138371 + put_affine_portal();
138372 + return rval;
138373 +}
138374 +EXPORT_SYMBOL(qman_retire_fq);
138375 +
138376 +int qman_oos_fq(struct qman_fq *fq)
138377 +{
138378 + struct qm_mc_command *mcc;
138379 + struct qm_mc_result *mcr;
138380 + struct qman_portal *p;
138381 + unsigned long irqflags __maybe_unused;
138382 + int ret = 0;
138383 + u8 res;
138384 +
138385 + if (fq->state != qman_fq_state_retired)
138386 + return -EINVAL;
138387 +#ifdef CONFIG_FSL_DPA_CHECKING
138388 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
138389 + return -EINVAL;
138390 +#endif
138391 + p = get_affine_portal();
138392 + PORTAL_IRQ_LOCK(p, irqflags);
138393 + FQLOCK(fq);
138394 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_BLOCKOOS)) ||
138395 + (fq->state != qman_fq_state_retired))) {
138396 + ret = -EBUSY;
138397 + goto out;
138398 + }
138399 + mcc = qm_mc_start(&p->p);
138400 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
138401 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS);
138402 + while (!(mcr = qm_mc_result(&p->p)))
138403 + cpu_relax();
138404 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS);
138405 + res = mcr->result;
138406 + if (res != QM_MCR_RESULT_OK) {
138407 + ret = -EIO;
138408 + goto out;
138409 + }
138410 + fq->state = qman_fq_state_oos;
138411 +out:
138412 + FQUNLOCK(fq);
138413 + PORTAL_IRQ_UNLOCK(p, irqflags);
138414 + put_affine_portal();
138415 + return ret;
138416 +}
138417 +EXPORT_SYMBOL(qman_oos_fq);
138418 +
138419 +int qman_fq_flow_control(struct qman_fq *fq, int xon)
138420 +{
138421 + struct qm_mc_command *mcc;
138422 + struct qm_mc_result *mcr;
138423 + struct qman_portal *p;
138424 + unsigned long irqflags __maybe_unused;
138425 + int ret = 0;
138426 + u8 res;
138427 + u8 myverb;
138428 +
138429 + if ((fq->state == qman_fq_state_oos) ||
138430 + (fq->state == qman_fq_state_retired) ||
138431 + (fq->state == qman_fq_state_parked))
138432 + return -EINVAL;
138433 +
138434 +#ifdef CONFIG_FSL_DPA_CHECKING
138435 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
138436 + return -EINVAL;
138437 +#endif
138438 + /* Issue a ALTER_FQXON or ALTER_FQXOFF management command */
138439 + p = get_affine_portal();
138440 + PORTAL_IRQ_LOCK(p, irqflags);
138441 + FQLOCK(fq);
138442 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
138443 + (fq->state == qman_fq_state_parked) ||
138444 + (fq->state == qman_fq_state_oos) ||
138445 + (fq->state == qman_fq_state_retired))) {
138446 + ret = -EBUSY;
138447 + goto out;
138448 + }
138449 + mcc = qm_mc_start(&p->p);
138450 + mcc->alterfq.fqid = fq->fqid;
138451 + mcc->alterfq.count = 0;
138452 + myverb = xon ? QM_MCC_VERB_ALTER_FQXON : QM_MCC_VERB_ALTER_FQXOFF;
138453 +
138454 + qm_mc_commit(&p->p, myverb);
138455 + while (!(mcr = qm_mc_result(&p->p)))
138456 + cpu_relax();
138457 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
138458 +
138459 + res = mcr->result;
138460 + if (res != QM_MCR_RESULT_OK) {
138461 + ret = -EIO;
138462 + goto out;
138463 + }
138464 +out:
138465 + FQUNLOCK(fq);
138466 + PORTAL_IRQ_UNLOCK(p, irqflags);
138467 + put_affine_portal();
138468 + return ret;
138469 +}
138470 +EXPORT_SYMBOL(qman_fq_flow_control);
138471 +
138472 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd)
138473 +{
138474 + struct qm_mc_command *mcc;
138475 + struct qm_mc_result *mcr;
138476 + struct qman_portal *p = get_affine_portal();
138477 + unsigned long irqflags __maybe_unused;
138478 + u8 res;
138479 +
138480 + PORTAL_IRQ_LOCK(p, irqflags);
138481 + mcc = qm_mc_start(&p->p);
138482 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
138483 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
138484 + while (!(mcr = qm_mc_result(&p->p)))
138485 + cpu_relax();
138486 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
138487 + res = mcr->result;
138488 + if (res == QM_MCR_RESULT_OK)
138489 + *fqd = mcr->queryfq.fqd;
138490 + hw_fqd_to_cpu(fqd);
138491 + PORTAL_IRQ_UNLOCK(p, irqflags);
138492 + put_affine_portal();
138493 + if (res != QM_MCR_RESULT_OK)
138494 + return -EIO;
138495 + return 0;
138496 +}
138497 +EXPORT_SYMBOL(qman_query_fq);
138498 +
138499 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np)
138500 +{
138501 + struct qm_mc_command *mcc;
138502 + struct qm_mc_result *mcr;
138503 + struct qman_portal *p = get_affine_portal();
138504 + unsigned long irqflags __maybe_unused;
138505 + u8 res;
138506 +
138507 + PORTAL_IRQ_LOCK(p, irqflags);
138508 + mcc = qm_mc_start(&p->p);
138509 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
138510 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
138511 + while (!(mcr = qm_mc_result(&p->p)))
138512 + cpu_relax();
138513 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
138514 + res = mcr->result;
138515 + if (res == QM_MCR_RESULT_OK) {
138516 + *np = mcr->queryfq_np;
138517 + np->fqd_link = be24_to_cpu(np->fqd_link);
138518 + np->odp_seq = be16_to_cpu(np->odp_seq);
138519 + np->orp_nesn = be16_to_cpu(np->orp_nesn);
138520 + np->orp_ea_hseq = be16_to_cpu(np->orp_ea_hseq);
138521 + np->orp_ea_tseq = be16_to_cpu(np->orp_ea_tseq);
138522 + np->orp_ea_hptr = be24_to_cpu(np->orp_ea_hptr);
138523 + np->orp_ea_tptr = be24_to_cpu(np->orp_ea_tptr);
138524 + np->pfdr_hptr = be24_to_cpu(np->pfdr_hptr);
138525 + np->pfdr_tptr = be24_to_cpu(np->pfdr_tptr);
138526 + np->ics_surp = be16_to_cpu(np->ics_surp);
138527 + np->byte_cnt = be32_to_cpu(np->byte_cnt);
138528 + np->frm_cnt = be24_to_cpu(np->frm_cnt);
138529 + np->ra1_sfdr = be16_to_cpu(np->ra1_sfdr);
138530 + np->ra2_sfdr = be16_to_cpu(np->ra2_sfdr);
138531 + np->od1_sfdr = be16_to_cpu(np->od1_sfdr);
138532 + np->od2_sfdr = be16_to_cpu(np->od2_sfdr);
138533 + np->od3_sfdr = be16_to_cpu(np->od3_sfdr);
138534 + }
138535 + PORTAL_IRQ_UNLOCK(p, irqflags);
138536 + put_affine_portal();
138537 + if (res == QM_MCR_RESULT_ERR_FQID)
138538 + return -ERANGE;
138539 + else if (res != QM_MCR_RESULT_OK)
138540 + return -EIO;
138541 + return 0;
138542 +}
138543 +EXPORT_SYMBOL(qman_query_fq_np);
138544 +
138545 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq)
138546 +{
138547 + struct qm_mc_command *mcc;
138548 + struct qm_mc_result *mcr;
138549 + struct qman_portal *p = get_affine_portal();
138550 + unsigned long irqflags __maybe_unused;
138551 + u8 res, myverb;
138552 +
138553 + PORTAL_IRQ_LOCK(p, irqflags);
138554 + myverb = (query_dedicated) ? QM_MCR_VERB_QUERYWQ_DEDICATED :
138555 + QM_MCR_VERB_QUERYWQ;
138556 + mcc = qm_mc_start(&p->p);
138557 + mcc->querywq.channel.id = cpu_to_be16(wq->channel.id);
138558 + qm_mc_commit(&p->p, myverb);
138559 + while (!(mcr = qm_mc_result(&p->p)))
138560 + cpu_relax();
138561 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
138562 + res = mcr->result;
138563 + if (res == QM_MCR_RESULT_OK) {
138564 + int i, array_len;
138565 + wq->channel.id = be16_to_cpu(mcr->querywq.channel.id);
138566 + array_len = ARRAY_SIZE(mcr->querywq.wq_len);
138567 + for (i = 0; i < array_len; i++)
138568 + wq->wq_len[i] = be32_to_cpu(mcr->querywq.wq_len[i]);
138569 + }
138570 + PORTAL_IRQ_UNLOCK(p, irqflags);
138571 + put_affine_portal();
138572 + if (res != QM_MCR_RESULT_OK) {
138573 + pr_err("QUERYWQ failed: %s\n", mcr_result_str(res));
138574 + return -EIO;
138575 + }
138576 + return 0;
138577 +}
138578 +EXPORT_SYMBOL(qman_query_wq);
138579 +
138580 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
138581 + struct qm_mcr_cgrtestwrite *result)
138582 +{
138583 + struct qm_mc_command *mcc;
138584 + struct qm_mc_result *mcr;
138585 + struct qman_portal *p = get_affine_portal();
138586 + unsigned long irqflags __maybe_unused;
138587 + u8 res;
138588 +
138589 + PORTAL_IRQ_LOCK(p, irqflags);
138590 + mcc = qm_mc_start(&p->p);
138591 + mcc->cgrtestwrite.cgid = cgr->cgrid;
138592 + mcc->cgrtestwrite.i_bcnt_hi = (u8)(i_bcnt >> 32);
138593 + mcc->cgrtestwrite.i_bcnt_lo = (u32)i_bcnt;
138594 + qm_mc_commit(&p->p, QM_MCC_VERB_CGRTESTWRITE);
138595 + while (!(mcr = qm_mc_result(&p->p)))
138596 + cpu_relax();
138597 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_CGRTESTWRITE);
138598 + res = mcr->result;
138599 + if (res == QM_MCR_RESULT_OK)
138600 + *result = mcr->cgrtestwrite;
138601 + PORTAL_IRQ_UNLOCK(p, irqflags);
138602 + put_affine_portal();
138603 + if (res != QM_MCR_RESULT_OK) {
138604 + pr_err("CGR TEST WRITE failed: %s\n", mcr_result_str(res));
138605 + return -EIO;
138606 + }
138607 + return 0;
138608 +}
138609 +EXPORT_SYMBOL(qman_testwrite_cgr);
138610 +
138611 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *cgrd)
138612 +{
138613 + struct qm_mc_command *mcc;
138614 + struct qm_mc_result *mcr;
138615 + struct qman_portal *p = get_affine_portal();
138616 + unsigned long irqflags __maybe_unused;
138617 + u8 res;
138618 + int i;
138619 +
138620 + PORTAL_IRQ_LOCK(p, irqflags);
138621 + mcc = qm_mc_start(&p->p);
138622 + mcc->querycgr.cgid = cgr->cgrid;
138623 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCGR);
138624 + while (!(mcr = qm_mc_result(&p->p)))
138625 + cpu_relax();
138626 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
138627 + res = mcr->result;
138628 + if (res == QM_MCR_RESULT_OK)
138629 + *cgrd = mcr->querycgr;
138630 + PORTAL_IRQ_UNLOCK(p, irqflags);
138631 + put_affine_portal();
138632 + if (res != QM_MCR_RESULT_OK) {
138633 + pr_err("QUERY_CGR failed: %s\n", mcr_result_str(res));
138634 + return -EIO;
138635 + }
138636 + cgrd->cgr.wr_parm_g.word =
138637 + be32_to_cpu(cgrd->cgr.wr_parm_g.word);
138638 + cgrd->cgr.wr_parm_y.word =
138639 + be32_to_cpu(cgrd->cgr.wr_parm_y.word);
138640 + cgrd->cgr.wr_parm_r.word =
138641 + be32_to_cpu(cgrd->cgr.wr_parm_r.word);
138642 + cgrd->cgr.cscn_targ = be32_to_cpu(cgrd->cgr.cscn_targ);
138643 + cgrd->cgr.__cs_thres = be16_to_cpu(cgrd->cgr.__cs_thres);
138644 + for (i = 0; i < ARRAY_SIZE(cgrd->cscn_targ_swp); i++)
138645 + be32_to_cpus(&cgrd->cscn_targ_swp[i]);
138646 + return 0;
138647 +}
138648 +EXPORT_SYMBOL(qman_query_cgr);
138649 +
138650 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion)
138651 +{
138652 + struct qm_mc_result *mcr;
138653 + struct qman_portal *p = get_affine_portal();
138654 + unsigned long irqflags __maybe_unused;
138655 + u8 res;
138656 + int i;
138657 +
138658 + PORTAL_IRQ_LOCK(p, irqflags);
138659 + qm_mc_start(&p->p);
138660 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
138661 + while (!(mcr = qm_mc_result(&p->p)))
138662 + cpu_relax();
138663 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138664 + QM_MCC_VERB_QUERYCONGESTION);
138665 + res = mcr->result;
138666 + if (res == QM_MCR_RESULT_OK)
138667 + memcpy_fromio(congestion, &mcr->querycongestion,
138668 + sizeof(*congestion));
138669 + PORTAL_IRQ_UNLOCK(p, irqflags);
138670 + put_affine_portal();
138671 + if (res != QM_MCR_RESULT_OK) {
138672 + pr_err("QUERY_CONGESTION failed: %s\n", mcr_result_str(res));
138673 + return -EIO;
138674 + }
138675 +
138676 + for (i = 0; i < ARRAY_SIZE(congestion->state.__state); i++)
138677 + be32_to_cpus(&congestion->state.__state[i]);
138678 + return 0;
138679 +}
138680 +EXPORT_SYMBOL(qman_query_congestion);
138681 +
138682 +/* internal function used as a wait_event() expression */
138683 +static int set_p_vdqcr(struct qman_portal *p, struct qman_fq *fq, u32 vdqcr)
138684 +{
138685 + unsigned long irqflags __maybe_unused;
138686 + int ret = -EBUSY;
138687 + PORTAL_IRQ_LOCK(p, irqflags);
138688 + if (!p->vdqcr_owned) {
138689 + FQLOCK(fq);
138690 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138691 + goto escape;
138692 + fq_set(fq, QMAN_FQ_STATE_VDQCR);
138693 + FQUNLOCK(fq);
138694 + p->vdqcr_owned = fq;
138695 + ret = 0;
138696 + }
138697 +escape:
138698 + PORTAL_IRQ_UNLOCK(p, irqflags);
138699 + if (!ret)
138700 + qm_dqrr_vdqcr_set(&p->p, vdqcr);
138701 + return ret;
138702 +}
138703 +
138704 +static int set_vdqcr(struct qman_portal **p, struct qman_fq *fq, u32 vdqcr)
138705 +{
138706 + int ret;
138707 + *p = get_affine_portal();
138708 + ret = set_p_vdqcr(*p, fq, vdqcr);
138709 + put_affine_portal();
138710 + return ret;
138711 +}
138712 +
138713 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138714 +static int wait_p_vdqcr_start(struct qman_portal *p, struct qman_fq *fq,
138715 + u32 vdqcr, u32 flags)
138716 +{
138717 + int ret = 0;
138718 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138719 + ret = wait_event_interruptible(affine_queue,
138720 + !(ret = set_p_vdqcr(p, fq, vdqcr)));
138721 + else
138722 + wait_event(affine_queue, !(ret = set_p_vdqcr(p, fq, vdqcr)));
138723 + return ret;
138724 +}
138725 +
138726 +static int wait_vdqcr_start(struct qman_portal **p, struct qman_fq *fq,
138727 + u32 vdqcr, u32 flags)
138728 +{
138729 + int ret = 0;
138730 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138731 + ret = wait_event_interruptible(affine_queue,
138732 + !(ret = set_vdqcr(p, fq, vdqcr)));
138733 + else
138734 + wait_event(affine_queue, !(ret = set_vdqcr(p, fq, vdqcr)));
138735 + return ret;
138736 +}
138737 +#endif
138738 +
138739 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
138740 + u32 flags __maybe_unused, u32 vdqcr)
138741 +{
138742 + int ret;
138743 +
138744 + if ((fq->state != qman_fq_state_parked) &&
138745 + (fq->state != qman_fq_state_retired))
138746 + return -EINVAL;
138747 + if (vdqcr & QM_VDQCR_FQID_MASK)
138748 + return -EINVAL;
138749 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138750 + return -EBUSY;
138751 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
138752 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138753 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
138754 + ret = wait_p_vdqcr_start(p, fq, vdqcr, flags);
138755 + else
138756 +#endif
138757 + ret = set_p_vdqcr(p, fq, vdqcr);
138758 + if (ret)
138759 + return ret;
138760 + /* VDQCR is set */
138761 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138762 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
138763 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138764 + /* NB: don't propagate any error - the caller wouldn't
138765 + * know whether the VDQCR was issued or not. A signal
138766 + * could arrive after returning anyway, so the caller
138767 + * can check signal_pending() if that's an issue. */
138768 + wait_event_interruptible(affine_queue,
138769 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138770 + else
138771 + wait_event(affine_queue,
138772 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138773 + }
138774 +#endif
138775 + return 0;
138776 +}
138777 +EXPORT_SYMBOL(qman_p_volatile_dequeue);
138778 +
138779 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags __maybe_unused,
138780 + u32 vdqcr)
138781 +{
138782 + struct qman_portal *p;
138783 + int ret;
138784 +
138785 + if ((fq->state != qman_fq_state_parked) &&
138786 + (fq->state != qman_fq_state_retired))
138787 + return -EINVAL;
138788 + if (vdqcr & QM_VDQCR_FQID_MASK)
138789 + return -EINVAL;
138790 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138791 + return -EBUSY;
138792 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
138793 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138794 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
138795 + ret = wait_vdqcr_start(&p, fq, vdqcr, flags);
138796 + else
138797 +#endif
138798 + ret = set_vdqcr(&p, fq, vdqcr);
138799 + if (ret)
138800 + return ret;
138801 + /* VDQCR is set */
138802 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138803 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
138804 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138805 + /* NB: don't propagate any error - the caller wouldn't
138806 + * know whether the VDQCR was issued or not. A signal
138807 + * could arrive after returning anyway, so the caller
138808 + * can check signal_pending() if that's an issue. */
138809 + wait_event_interruptible(affine_queue,
138810 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138811 + else
138812 + wait_event(affine_queue,
138813 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138814 + }
138815 +#endif
138816 + return 0;
138817 +}
138818 +EXPORT_SYMBOL(qman_volatile_dequeue);
138819 +
138820 +static noinline void update_eqcr_ci(struct qman_portal *p, u8 avail)
138821 +{
138822 + if (avail)
138823 + qm_eqcr_cce_prefetch(&p->p);
138824 + else
138825 + qm_eqcr_cce_update(&p->p);
138826 +}
138827 +
138828 +int qman_eqcr_is_empty(void)
138829 +{
138830 + unsigned long irqflags __maybe_unused;
138831 + struct qman_portal *p = get_affine_portal();
138832 + u8 avail;
138833 +
138834 + PORTAL_IRQ_LOCK(p, irqflags);
138835 + update_eqcr_ci(p, 0);
138836 + avail = qm_eqcr_get_fill(&p->p);
138837 + PORTAL_IRQ_UNLOCK(p, irqflags);
138838 + put_affine_portal();
138839 + return avail == 0;
138840 +}
138841 +EXPORT_SYMBOL(qman_eqcr_is_empty);
138842 +
138843 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine)
138844 +{
138845 + if (affine) {
138846 + unsigned long irqflags __maybe_unused;
138847 + struct qman_portal *p = get_affine_portal();
138848 + PORTAL_IRQ_LOCK(p, irqflags);
138849 + p->cb_dc_ern = handler;
138850 + PORTAL_IRQ_UNLOCK(p, irqflags);
138851 + put_affine_portal();
138852 + } else
138853 + cb_dc_ern = handler;
138854 +}
138855 +EXPORT_SYMBOL(qman_set_dc_ern);
138856 +
138857 +static inline struct qm_eqcr_entry *try_p_eq_start(struct qman_portal *p,
138858 + unsigned long *irqflags __maybe_unused,
138859 + struct qman_fq *fq,
138860 + const struct qm_fd *fd,
138861 + u32 flags)
138862 +{
138863 + struct qm_eqcr_entry *eq;
138864 + u8 avail;
138865 + PORTAL_IRQ_LOCK(p, (*irqflags));
138866 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138867 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138868 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138869 + if (p->eqci_owned) {
138870 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
138871 + return NULL;
138872 + }
138873 + p->eqci_owned = fq;
138874 + }
138875 +#endif
138876 + if (p->use_eqcr_ci_stashing) {
138877 + /*
138878 + * The stashing case is easy, only update if we need to in
138879 + * order to try and liberate ring entries.
138880 + */
138881 + eq = qm_eqcr_start_stash(&p->p);
138882 + } else {
138883 + /*
138884 + * The non-stashing case is harder, need to prefetch ahead of
138885 + * time.
138886 + */
138887 + avail = qm_eqcr_get_avail(&p->p);
138888 + if (avail < 2)
138889 + update_eqcr_ci(p, avail);
138890 + eq = qm_eqcr_start_no_stash(&p->p);
138891 + }
138892 +
138893 + if (unlikely(!eq)) {
138894 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138895 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138896 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC)))
138897 + p->eqci_owned = NULL;
138898 +#endif
138899 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
138900 + return NULL;
138901 + }
138902 + if (flags & QMAN_ENQUEUE_FLAG_DCA)
138903 + eq->dca = QM_EQCR_DCA_ENABLE |
138904 + ((flags & QMAN_ENQUEUE_FLAG_DCA_PARK) ?
138905 + QM_EQCR_DCA_PARK : 0) |
138906 + ((flags >> 8) & QM_EQCR_DCA_IDXMASK);
138907 + eq->fqid = cpu_to_be32(fq->fqid);
138908 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138909 + eq->tag = cpu_to_be32(fq->key);
138910 +#else
138911 + eq->tag = cpu_to_be32((u32)(uintptr_t)fq);
138912 +#endif
138913 + eq->fd = *fd;
138914 + cpu_to_hw_fd(&eq->fd);
138915 + return eq;
138916 +}
138917 +
138918 +static inline struct qm_eqcr_entry *try_eq_start(struct qman_portal **p,
138919 + unsigned long *irqflags __maybe_unused,
138920 + struct qman_fq *fq,
138921 + const struct qm_fd *fd,
138922 + u32 flags)
138923 +{
138924 + struct qm_eqcr_entry *eq;
138925 + *p = get_affine_portal();
138926 + eq = try_p_eq_start(*p, irqflags, fq, fd, flags);
138927 + if (!eq)
138928 + put_affine_portal();
138929 + return eq;
138930 +}
138931 +
138932 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138933 +static noinline struct qm_eqcr_entry *__wait_eq_start(struct qman_portal **p,
138934 + unsigned long *irqflags __maybe_unused,
138935 + struct qman_fq *fq,
138936 + const struct qm_fd *fd,
138937 + u32 flags)
138938 +{
138939 + struct qm_eqcr_entry *eq = try_eq_start(p, irqflags, fq, fd, flags);
138940 + if (!eq)
138941 + qm_eqcr_set_ithresh(&(*p)->p, EQCR_ITHRESH);
138942 + return eq;
138943 +}
138944 +static noinline struct qm_eqcr_entry *wait_eq_start(struct qman_portal **p,
138945 + unsigned long *irqflags __maybe_unused,
138946 + struct qman_fq *fq,
138947 + const struct qm_fd *fd,
138948 + u32 flags)
138949 +{
138950 + struct qm_eqcr_entry *eq;
138951 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138952 + /* NB: return NULL if signal occurs before completion. Signal
138953 + * can occur during return. Caller must check for signal */
138954 + wait_event_interruptible(affine_queue,
138955 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138956 + else
138957 + wait_event(affine_queue,
138958 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138959 + return eq;
138960 +}
138961 +static noinline struct qm_eqcr_entry *__wait_p_eq_start(struct qman_portal *p,
138962 + unsigned long *irqflags __maybe_unused,
138963 + struct qman_fq *fq,
138964 + const struct qm_fd *fd,
138965 + u32 flags)
138966 +{
138967 + struct qm_eqcr_entry *eq = try_p_eq_start(p, irqflags, fq, fd, flags);
138968 + if (!eq)
138969 + qm_eqcr_set_ithresh(&p->p, EQCR_ITHRESH);
138970 + return eq;
138971 +}
138972 +static noinline struct qm_eqcr_entry *wait_p_eq_start(struct qman_portal *p,
138973 + unsigned long *irqflags __maybe_unused,
138974 + struct qman_fq *fq,
138975 + const struct qm_fd *fd,
138976 + u32 flags)
138977 +{
138978 + struct qm_eqcr_entry *eq;
138979 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138980 + /* NB: return NULL if signal occurs before completion. Signal
138981 + * can occur during return. Caller must check for signal */
138982 + wait_event_interruptible(affine_queue,
138983 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138984 + else
138985 + wait_event(affine_queue,
138986 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138987 + return eq;
138988 +}
138989 +#endif
138990 +
138991 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
138992 + const struct qm_fd *fd, u32 flags)
138993 +{
138994 + struct qm_eqcr_entry *eq;
138995 + unsigned long irqflags __maybe_unused;
138996 +
138997 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138998 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138999 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
139000 + else
139001 +#endif
139002 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
139003 + if (!eq)
139004 + return -EBUSY;
139005 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139006 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
139007 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
139008 + /* Factor the below out, it's used from qman_enqueue_orp() too */
139009 + PORTAL_IRQ_UNLOCK(p, irqflags);
139010 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139011 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139012 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139013 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139014 + /* NB: return success even if signal occurs before
139015 + * condition is true. pvb_commit guarantees success */
139016 + wait_event_interruptible(affine_queue,
139017 + (p->eqci_owned != fq));
139018 + else
139019 + wait_event(affine_queue, (p->eqci_owned != fq));
139020 + }
139021 +#endif
139022 + return 0;
139023 +}
139024 +EXPORT_SYMBOL(qman_p_enqueue);
139025 +
139026 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags)
139027 +{
139028 + struct qman_portal *p;
139029 + struct qm_eqcr_entry *eq;
139030 + unsigned long irqflags __maybe_unused;
139031 +
139032 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139033 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
139034 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
139035 + else
139036 +#endif
139037 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
139038 + if (!eq)
139039 + return -EBUSY;
139040 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139041 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
139042 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
139043 + /* Factor the below out, it's used from qman_enqueue_orp() too */
139044 + PORTAL_IRQ_UNLOCK(p, irqflags);
139045 + put_affine_portal();
139046 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139047 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139048 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139049 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139050 + /* NB: return success even if signal occurs before
139051 + * condition is true. pvb_commit guarantees success */
139052 + wait_event_interruptible(affine_queue,
139053 + (p->eqci_owned != fq));
139054 + else
139055 + wait_event(affine_queue, (p->eqci_owned != fq));
139056 + }
139057 +#endif
139058 + return 0;
139059 +}
139060 +EXPORT_SYMBOL(qman_enqueue);
139061 +
139062 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
139063 + const struct qm_fd *fd, u32 flags,
139064 + struct qman_fq *orp, u16 orp_seqnum)
139065 +{
139066 + struct qm_eqcr_entry *eq;
139067 + unsigned long irqflags __maybe_unused;
139068 +
139069 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139070 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
139071 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
139072 + else
139073 +#endif
139074 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
139075 + if (!eq)
139076 + return -EBUSY;
139077 + /* Process ORP-specifics here */
139078 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
139079 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
139080 + else {
139081 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
139082 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
139083 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
139084 + else
139085 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
139086 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
139087 + }
139088 + eq->seqnum = cpu_to_be16(orp_seqnum);
139089 + eq->orp = cpu_to_be32(orp->fqid);
139090 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139091 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
139092 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
139093 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
139094 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
139095 + PORTAL_IRQ_UNLOCK(p, irqflags);
139096 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139097 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139098 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139099 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139100 + /* NB: return success even if signal occurs before
139101 + * condition is true. pvb_commit guarantees success */
139102 + wait_event_interruptible(affine_queue,
139103 + (p->eqci_owned != fq));
139104 + else
139105 + wait_event(affine_queue, (p->eqci_owned != fq));
139106 + }
139107 +#endif
139108 + return 0;
139109 +}
139110 +EXPORT_SYMBOL(qman_p_enqueue_orp);
139111 +
139112 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
139113 + struct qman_fq *orp, u16 orp_seqnum)
139114 +{
139115 + struct qman_portal *p;
139116 + struct qm_eqcr_entry *eq;
139117 + unsigned long irqflags __maybe_unused;
139118 +
139119 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139120 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
139121 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
139122 + else
139123 +#endif
139124 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
139125 + if (!eq)
139126 + return -EBUSY;
139127 + /* Process ORP-specifics here */
139128 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
139129 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
139130 + else {
139131 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
139132 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
139133 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
139134 + else
139135 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
139136 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
139137 + }
139138 + eq->seqnum = cpu_to_be16(orp_seqnum);
139139 + eq->orp = cpu_to_be32(orp->fqid);
139140 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139141 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
139142 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
139143 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
139144 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
139145 + PORTAL_IRQ_UNLOCK(p, irqflags);
139146 + put_affine_portal();
139147 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139148 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139149 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139150 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139151 + /* NB: return success even if signal occurs before
139152 + * condition is true. pvb_commit guarantees success */
139153 + wait_event_interruptible(affine_queue,
139154 + (p->eqci_owned != fq));
139155 + else
139156 + wait_event(affine_queue, (p->eqci_owned != fq));
139157 + }
139158 +#endif
139159 + return 0;
139160 +}
139161 +EXPORT_SYMBOL(qman_enqueue_orp);
139162 +
139163 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
139164 + const struct qm_fd *fd, u32 flags,
139165 + qman_cb_precommit cb, void *cb_arg)
139166 +{
139167 + struct qm_eqcr_entry *eq;
139168 + unsigned long irqflags __maybe_unused;
139169 +
139170 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139171 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
139172 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
139173 + else
139174 +#endif
139175 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
139176 + if (!eq)
139177 + return -EBUSY;
139178 + /* invoke user supplied callback function before writing commit verb */
139179 + if (cb(cb_arg)) {
139180 + PORTAL_IRQ_UNLOCK(p, irqflags);
139181 + return -EINVAL;
139182 + }
139183 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139184 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
139185 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
139186 + /* Factor the below out, it's used from qman_enqueue_orp() too */
139187 + PORTAL_IRQ_UNLOCK(p, irqflags);
139188 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139189 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139190 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139191 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139192 + /* NB: return success even if signal occurs before
139193 + * condition is true. pvb_commit guarantees success */
139194 + wait_event_interruptible(affine_queue,
139195 + (p->eqci_owned != fq));
139196 + else
139197 + wait_event(affine_queue, (p->eqci_owned != fq));
139198 + }
139199 +#endif
139200 + return 0;
139201 +}
139202 +EXPORT_SYMBOL(qman_p_enqueue_precommit);
139203 +
139204 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
139205 + u32 flags, qman_cb_precommit cb, void *cb_arg)
139206 +{
139207 + struct qman_portal *p;
139208 + struct qm_eqcr_entry *eq;
139209 + unsigned long irqflags __maybe_unused;
139210 +
139211 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139212 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
139213 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
139214 + else
139215 +#endif
139216 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
139217 + if (!eq)
139218 + return -EBUSY;
139219 + /* invoke user supplied callback function before writing commit verb */
139220 + if (cb(cb_arg)) {
139221 + PORTAL_IRQ_UNLOCK(p, irqflags);
139222 + put_affine_portal();
139223 + return -EINVAL;
139224 + }
139225 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139226 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
139227 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
139228 + /* Factor the below out, it's used from qman_enqueue_orp() too */
139229 + PORTAL_IRQ_UNLOCK(p, irqflags);
139230 + put_affine_portal();
139231 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139232 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139233 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139234 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139235 + /* NB: return success even if signal occurs before
139236 + * condition is true. pvb_commit guarantees success */
139237 + wait_event_interruptible(affine_queue,
139238 + (p->eqci_owned != fq));
139239 + else
139240 + wait_event(affine_queue, (p->eqci_owned != fq));
139241 + }
139242 +#endif
139243 + return 0;
139244 +}
139245 +EXPORT_SYMBOL(qman_enqueue_precommit);
139246 +
139247 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
139248 + struct qm_mcc_initcgr *opts)
139249 +{
139250 + struct qm_mc_command *mcc;
139251 + struct qm_mc_result *mcr;
139252 + struct qman_portal *p = get_affine_portal();
139253 + unsigned long irqflags __maybe_unused;
139254 + u8 res;
139255 + u8 verb = QM_MCC_VERB_MODIFYCGR;
139256 +
139257 + PORTAL_IRQ_LOCK(p, irqflags);
139258 + mcc = qm_mc_start(&p->p);
139259 + if (opts)
139260 + mcc->initcgr = *opts;
139261 + mcc->initcgr.we_mask = cpu_to_be16(mcc->initcgr.we_mask);
139262 + mcc->initcgr.cgr.wr_parm_g.word =
139263 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_g.word);
139264 + mcc->initcgr.cgr.wr_parm_y.word =
139265 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_y.word);
139266 + mcc->initcgr.cgr.wr_parm_r.word =
139267 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_r.word);
139268 + mcc->initcgr.cgr.cscn_targ = cpu_to_be32(mcc->initcgr.cgr.cscn_targ);
139269 + mcc->initcgr.cgr.__cs_thres = cpu_to_be16(mcc->initcgr.cgr.__cs_thres);
139270 +
139271 + mcc->initcgr.cgid = cgr->cgrid;
139272 + if (flags & QMAN_CGR_FLAG_USE_INIT)
139273 + verb = QM_MCC_VERB_INITCGR;
139274 + qm_mc_commit(&p->p, verb);
139275 + while (!(mcr = qm_mc_result(&p->p)))
139276 + cpu_relax();
139277 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == verb);
139278 + res = mcr->result;
139279 + PORTAL_IRQ_UNLOCK(p, irqflags);
139280 + put_affine_portal();
139281 + return (res == QM_MCR_RESULT_OK) ? 0 : -EIO;
139282 +}
139283 +EXPORT_SYMBOL(qman_modify_cgr);
139284 +
139285 +#define TARG_MASK(n) (0x80000000 >> (n->config->public_cfg.channel - \
139286 + QM_CHANNEL_SWPORTAL0))
139287 +#define TARG_DCP_MASK(n) (0x80000000 >> (10 + n))
139288 +#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0)
139289 +
139290 +static u8 qman_cgr_cpus[__CGR_NUM];
139291 +
139292 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
139293 + struct qm_mcc_initcgr *opts)
139294 +{
139295 + unsigned long irqflags __maybe_unused;
139296 + struct qm_mcr_querycgr cgr_state;
139297 + struct qm_mcc_initcgr local_opts;
139298 + int ret;
139299 + struct qman_portal *p;
139300 +
139301 + /* We have to check that the provided CGRID is within the limits of the
139302 + * data-structures, for obvious reasons. However we'll let h/w take
139303 + * care of determining whether it's within the limits of what exists on
139304 + * the SoC. */
139305 + if (cgr->cgrid >= __CGR_NUM)
139306 + return -EINVAL;
139307 +
139308 + preempt_disable();
139309 + p = get_affine_portal();
139310 + qman_cgr_cpus[cgr->cgrid] = smp_processor_id();
139311 + preempt_enable();
139312 +
139313 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
139314 + cgr->chan = p->config->public_cfg.channel;
139315 + spin_lock_irqsave(&p->cgr_lock, irqflags);
139316 +
139317 + /* if no opts specified, just add it to the list */
139318 + if (!opts)
139319 + goto add_list;
139320 +
139321 + ret = qman_query_cgr(cgr, &cgr_state);
139322 + if (ret)
139323 + goto release_lock;
139324 + if (opts)
139325 + local_opts = *opts;
139326 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
139327 + local_opts.cgr.cscn_targ_upd_ctrl =
139328 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p);
139329 + else
139330 + /* Overwrite TARG */
139331 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
139332 + TARG_MASK(p);
139333 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
139334 +
139335 + /* send init if flags indicate so */
139336 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
139337 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, &local_opts);
139338 + else
139339 + ret = qman_modify_cgr(cgr, 0, &local_opts);
139340 + if (ret)
139341 + goto release_lock;
139342 +add_list:
139343 + list_add(&cgr->node, &p->cgr_cbs);
139344 +
139345 + /* Determine if newly added object requires its callback to be called */
139346 + ret = qman_query_cgr(cgr, &cgr_state);
139347 + if (ret) {
139348 + /* we can't go back, so proceed and return success, but screen
139349 + * and wail to the log file */
139350 + pr_crit("CGR HW state partially modified\n");
139351 + ret = 0;
139352 + goto release_lock;
139353 + }
139354 + if (cgr->cb && cgr_state.cgr.cscn_en && qman_cgrs_get(&p->cgrs[1],
139355 + cgr->cgrid))
139356 + cgr->cb(p, cgr, 1);
139357 +release_lock:
139358 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
139359 + put_affine_portal();
139360 + return ret;
139361 +}
139362 +EXPORT_SYMBOL(qman_create_cgr);
139363 +
139364 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
139365 + struct qm_mcc_initcgr *opts)
139366 +{
139367 + unsigned long irqflags __maybe_unused;
139368 + struct qm_mcc_initcgr local_opts;
139369 + struct qm_mcr_querycgr cgr_state;
139370 + int ret;
139371 +
139372 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30) {
139373 + pr_warn("This QMan version doesn't support to send CSCN to DCP portal\n");
139374 + return -EINVAL;
139375 + }
139376 + /* We have to check that the provided CGRID is within the limits of the
139377 + * data-structures, for obvious reasons. However we'll let h/w take
139378 + * care of determining whether it's within the limits of what exists on
139379 + * the SoC.
139380 + */
139381 + if (cgr->cgrid >= __CGR_NUM)
139382 + return -EINVAL;
139383 +
139384 + ret = qman_query_cgr(cgr, &cgr_state);
139385 + if (ret)
139386 + return ret;
139387 +
139388 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
139389 + if (opts)
139390 + local_opts = *opts;
139391 +
139392 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
139393 + local_opts.cgr.cscn_targ_upd_ctrl =
139394 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT |
139395 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_portal;
139396 + else
139397 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
139398 + TARG_DCP_MASK(dcp_portal);
139399 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
139400 +
139401 + /* send init if flags indicate so */
139402 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
139403 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT,
139404 + &local_opts);
139405 + else
139406 + ret = qman_modify_cgr(cgr, 0, &local_opts);
139407 +
139408 + return ret;
139409 +}
139410 +EXPORT_SYMBOL(qman_create_cgr_to_dcp);
139411 +
139412 +int qman_delete_cgr(struct qman_cgr *cgr)
139413 +{
139414 + unsigned long irqflags __maybe_unused;
139415 + struct qm_mcr_querycgr cgr_state;
139416 + struct qm_mcc_initcgr local_opts;
139417 + int ret = 0;
139418 + struct qman_cgr *i;
139419 + struct qman_portal *p = get_affine_portal();
139420 +
139421 + if (cgr->chan != p->config->public_cfg.channel) {
139422 + pr_crit("Attempting to delete cgr from different portal "
139423 + "than it was create: create 0x%x, delete 0x%x\n",
139424 + cgr->chan, p->config->public_cfg.channel);
139425 + ret = -EINVAL;
139426 + goto put_portal;
139427 + }
139428 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
139429 + spin_lock_irqsave(&p->cgr_lock, irqflags);
139430 + list_del(&cgr->node);
139431 + /*
139432 + * If there are no other CGR objects for this CGRID in the list, update
139433 + * CSCN_TARG accordingly
139434 + */
139435 + list_for_each_entry(i, &p->cgr_cbs, node)
139436 + if ((i->cgrid == cgr->cgrid) && i->cb)
139437 + goto release_lock;
139438 + ret = qman_query_cgr(cgr, &cgr_state);
139439 + if (ret) {
139440 + /* add back to the list */
139441 + list_add(&cgr->node, &p->cgr_cbs);
139442 + goto release_lock;
139443 + }
139444 + /* Overwrite TARG */
139445 + local_opts.we_mask = QM_CGR_WE_CSCN_TARG;
139446 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
139447 + local_opts.cgr.cscn_targ_upd_ctrl = PORTAL_IDX(p);
139448 + else
139449 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ &
139450 + ~(TARG_MASK(p));
139451 + ret = qman_modify_cgr(cgr, 0, &local_opts);
139452 + if (ret)
139453 + /* add back to the list */
139454 + list_add(&cgr->node, &p->cgr_cbs);
139455 +release_lock:
139456 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
139457 +put_portal:
139458 + put_affine_portal();
139459 + return ret;
139460 +}
139461 +EXPORT_SYMBOL(qman_delete_cgr);
139462 +
139463 +struct cgr_comp {
139464 + struct qman_cgr *cgr;
139465 + struct completion completion;
139466 +};
139467 +
139468 +static int qman_delete_cgr_thread(void *p)
139469 +{
139470 + struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
139471 + int res;
139472 +
139473 + res = qman_delete_cgr((struct qman_cgr *)cgr_comp->cgr);
139474 + complete(&cgr_comp->completion);
139475 +
139476 + return res;
139477 +}
139478 +
139479 +void qman_delete_cgr_safe(struct qman_cgr *cgr)
139480 +{
139481 + struct task_struct *thread;
139482 + struct cgr_comp cgr_comp;
139483 +
139484 + preempt_disable();
139485 + if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
139486 + init_completion(&cgr_comp.completion);
139487 + cgr_comp.cgr = cgr;
139488 + thread = kthread_create(qman_delete_cgr_thread, &cgr_comp,
139489 + "cgr_del");
139490 +
139491 + if (likely(!IS_ERR(thread))) {
139492 + kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
139493 + wake_up_process(thread);
139494 + wait_for_completion(&cgr_comp.completion);
139495 + preempt_enable();
139496 + return;
139497 + }
139498 + }
139499 + qman_delete_cgr(cgr);
139500 + preempt_enable();
139501 +}
139502 +EXPORT_SYMBOL(qman_delete_cgr_safe);
139503 +
139504 +int qm_get_clock(u64 *clock_hz)
139505 +{
139506 + if (!qman_clk) {
139507 + pr_warn("Qman clock speed is unknown\n");
139508 + return -EINVAL;
139509 + }
139510 + *clock_hz = (u64)qman_clk;
139511 + return 0;
139512 +}
139513 +EXPORT_SYMBOL(qm_get_clock);
139514 +
139515 +int qm_set_clock(u64 clock_hz)
139516 +{
139517 + if (qman_clk)
139518 + return -1;
139519 + qman_clk = (u32)clock_hz;
139520 + return 0;
139521 +}
139522 +EXPORT_SYMBOL(qm_set_clock);
139523 +
139524 +/* CEETM management command */
139525 +static int qman_ceetm_configure_lfqmt(struct qm_mcc_ceetm_lfqmt_config *opts)
139526 +{
139527 + struct qm_mc_command *mcc;
139528 + struct qm_mc_result *mcr;
139529 + struct qman_portal *p;
139530 + unsigned long irqflags __maybe_unused;
139531 + u8 res;
139532 +
139533 + p = get_affine_portal();
139534 + PORTAL_IRQ_LOCK(p, irqflags);
139535 +
139536 + mcc = qm_mc_start(&p->p);
139537 + mcc->lfqmt_config = *opts;
139538 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_CONFIG);
139539 + while (!(mcr = qm_mc_result(&p->p)))
139540 + cpu_relax();
139541 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139542 + QM_CEETM_VERB_LFQMT_CONFIG);
139543 + PORTAL_IRQ_UNLOCK(p, irqflags);
139544 + put_affine_portal();
139545 +
139546 + res = mcr->result;
139547 + if (res != QM_MCR_RESULT_OK) {
139548 + pr_err("CEETM: CONFIGURE LFQMT failed\n");
139549 + return -EIO;
139550 + }
139551 + return 0;
139552 +}
139553 +
139554 +int qman_ceetm_query_lfqmt(int lfqid,
139555 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query)
139556 +{
139557 + struct qm_mc_command *mcc;
139558 + struct qm_mc_result *mcr;
139559 + struct qman_portal *p;
139560 + unsigned long irqflags __maybe_unused;
139561 + u8 res;
139562 +
139563 + p = get_affine_portal();
139564 + PORTAL_IRQ_LOCK(p, irqflags);
139565 +
139566 + mcc = qm_mc_start(&p->p);
139567 + mcc->lfqmt_query.lfqid = lfqid;
139568 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_QUERY);
139569 + while (!(mcr = qm_mc_result(&p->p)))
139570 + cpu_relax();
139571 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_LFQMT_QUERY);
139572 + res = mcr->result;
139573 + if (res == QM_MCR_RESULT_OK)
139574 + *lfqmt_query = mcr->lfqmt_query;
139575 +
139576 + PORTAL_IRQ_UNLOCK(p, irqflags);
139577 + put_affine_portal();
139578 + if (res != QM_MCR_RESULT_OK) {
139579 + pr_err("CEETM: QUERY LFQMT failed\n");
139580 + return -EIO;
139581 + }
139582 + return 0;
139583 +}
139584 +EXPORT_SYMBOL(qman_ceetm_query_lfqmt);
139585 +
139586 +static int qman_ceetm_configure_cq(struct qm_mcc_ceetm_cq_config *opts)
139587 +{
139588 + struct qm_mc_command *mcc;
139589 + struct qm_mc_result *mcr;
139590 + struct qman_portal *p;
139591 + unsigned long irqflags __maybe_unused;
139592 + u8 res;
139593 +
139594 + p = get_affine_portal();
139595 + PORTAL_IRQ_LOCK(p, irqflags);
139596 +
139597 + mcc = qm_mc_start(&p->p);
139598 + mcc->cq_config = *opts;
139599 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_CONFIG);
139600 + while (!(mcr = qm_mc_result(&p->p)))
139601 + cpu_relax();
139602 + res = mcr->result;
139603 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_CONFIG);
139604 +
139605 + PORTAL_IRQ_UNLOCK(p, irqflags);
139606 + put_affine_portal();
139607 +
139608 + if (res != QM_MCR_RESULT_OK) {
139609 + pr_err("CEETM: CONFIGURE CQ failed\n");
139610 + return -EIO;
139611 + }
139612 + return 0;
139613 +}
139614 +
139615 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
139616 + struct qm_mcr_ceetm_cq_query *cq_query)
139617 +{
139618 + struct qm_mc_command *mcc;
139619 + struct qm_mc_result *mcr;
139620 + struct qman_portal *p;
139621 + unsigned long irqflags __maybe_unused;
139622 + u8 res;
139623 +
139624 + p = get_affine_portal();
139625 + PORTAL_IRQ_LOCK(p, irqflags);
139626 +
139627 + mcc = qm_mc_start(&p->p);
139628 + mcc->cq_query.cqid = cpu_to_be16(cqid);
139629 + mcc->cq_query.dcpid = dcpid;
139630 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_QUERY);
139631 + while (!(mcr = qm_mc_result(&p->p)))
139632 + cpu_relax();
139633 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_QUERY);
139634 + res = mcr->result;
139635 + if (res == QM_MCR_RESULT_OK) {
139636 + *cq_query = mcr->cq_query;
139637 + hw_cq_query_to_cpu(cq_query);
139638 + }
139639 +
139640 + PORTAL_IRQ_UNLOCK(p, irqflags);
139641 + put_affine_portal();
139642 +
139643 + if (res != QM_MCR_RESULT_OK) {
139644 + pr_err("CEETM: QUERY CQ failed\n");
139645 + return -EIO;
139646 + }
139647 +
139648 + return 0;
139649 +}
139650 +EXPORT_SYMBOL(qman_ceetm_query_cq);
139651 +
139652 +static int qman_ceetm_configure_dct(struct qm_mcc_ceetm_dct_config *opts)
139653 +{
139654 + struct qm_mc_command *mcc;
139655 + struct qm_mc_result *mcr;
139656 + struct qman_portal *p;
139657 + unsigned long irqflags __maybe_unused;
139658 + u8 res;
139659 +
139660 + p = get_affine_portal();
139661 + PORTAL_IRQ_LOCK(p, irqflags);
139662 +
139663 + mcc = qm_mc_start(&p->p);
139664 + mcc->dct_config = *opts;
139665 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_CONFIG);
139666 + while (!(mcr = qm_mc_result(&p->p)))
139667 + cpu_relax();
139668 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_CONFIG);
139669 + res = mcr->result;
139670 +
139671 + PORTAL_IRQ_UNLOCK(p, irqflags);
139672 + put_affine_portal();
139673 +
139674 + if (res != QM_MCR_RESULT_OK) {
139675 + pr_err("CEETM: CONFIGURE DCT failed\n");
139676 + return -EIO;
139677 + }
139678 + return 0;
139679 +}
139680 +
139681 +static int qman_ceetm_query_dct(struct qm_mcc_ceetm_dct_query *opts,
139682 + struct qm_mcr_ceetm_dct_query *dct_query)
139683 +{
139684 + struct qm_mc_command *mcc;
139685 + struct qm_mc_result *mcr;
139686 + struct qman_portal *p = get_affine_portal();
139687 + unsigned long irqflags __maybe_unused;
139688 + u8 res;
139689 +
139690 + PORTAL_IRQ_LOCK(p, irqflags);
139691 +
139692 + mcc = qm_mc_start(&p->p);
139693 + mcc->dct_query = *opts;
139694 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_QUERY);
139695 + while (!(mcr = qm_mc_result(&p->p)))
139696 + cpu_relax();
139697 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_QUERY);
139698 + res = mcr->result;
139699 +
139700 + PORTAL_IRQ_UNLOCK(p, irqflags);
139701 + put_affine_portal();
139702 +
139703 + if (res != QM_MCR_RESULT_OK) {
139704 + pr_err("CEETM: QUERY DCT failed\n");
139705 + return -EIO;
139706 + }
139707 +
139708 + *dct_query = mcr->dct_query;
139709 + return 0;
139710 +}
139711 +
139712 +static int qman_ceetm_configure_class_scheduler(
139713 + struct qm_mcc_ceetm_class_scheduler_config *opts)
139714 +{
139715 + struct qm_mc_command *mcc;
139716 + struct qm_mc_result *mcr;
139717 + struct qman_portal *p;
139718 + unsigned long irqflags __maybe_unused;
139719 + u8 res;
139720 +
139721 + p = get_affine_portal();
139722 + PORTAL_IRQ_LOCK(p, irqflags);
139723 +
139724 + mcc = qm_mc_start(&p->p);
139725 + mcc->csch_config = *opts;
139726 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
139727 + while (!(mcr = qm_mc_result(&p->p)))
139728 + cpu_relax();
139729 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139730 + QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
139731 + res = mcr->result;
139732 +
139733 + PORTAL_IRQ_UNLOCK(p, irqflags);
139734 + put_affine_portal();
139735 +
139736 + if (res != QM_MCR_RESULT_OK) {
139737 + pr_err("CEETM: CONFIGURE CLASS SCHEDULER failed\n");
139738 + return -EIO;
139739 + }
139740 + return 0;
139741 +}
139742 +
139743 +static int qman_ceetm_query_class_scheduler(struct qm_ceetm_channel *channel,
139744 + struct qm_mcr_ceetm_class_scheduler_query *query)
139745 +{
139746 + struct qm_mc_command *mcc;
139747 + struct qm_mc_result *mcr;
139748 + struct qman_portal *p;
139749 + unsigned long irqflags __maybe_unused;
139750 + u8 res;
139751 +
139752 + p = get_affine_portal();
139753 + PORTAL_IRQ_LOCK(p, irqflags);
139754 +
139755 + mcc = qm_mc_start(&p->p);
139756 + mcc->csch_query.cqcid = cpu_to_be16(channel->idx);
139757 + mcc->csch_query.dcpid = channel->dcp_idx;
139758 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
139759 + while (!(mcr = qm_mc_result(&p->p)))
139760 + cpu_relax();
139761 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139762 + QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
139763 + res = mcr->result;
139764 +
139765 + PORTAL_IRQ_UNLOCK(p, irqflags);
139766 + put_affine_portal();
139767 +
139768 + if (res != QM_MCR_RESULT_OK) {
139769 + pr_err("CEETM: QUERY CLASS SCHEDULER failed\n");
139770 + return -EIO;
139771 + }
139772 + *query = mcr->csch_query;
139773 + return 0;
139774 +}
139775 +
139776 +static int qman_ceetm_configure_mapping_shaper_tcfc(
139777 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config *opts)
139778 +{
139779 + struct qm_mc_command *mcc;
139780 + struct qm_mc_result *mcr;
139781 + struct qman_portal *p;
139782 + unsigned long irqflags __maybe_unused;
139783 + u8 res;
139784 +
139785 + p = get_affine_portal();
139786 + PORTAL_IRQ_LOCK(p, irqflags);
139787 +
139788 + mcc = qm_mc_start(&p->p);
139789 + mcc->mst_config = *opts;
139790 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
139791 + while (!(mcr = qm_mc_result(&p->p)))
139792 + cpu_relax();
139793 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139794 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
139795 + res = mcr->result;
139796 +
139797 + PORTAL_IRQ_UNLOCK(p, irqflags);
139798 + put_affine_portal();
139799 +
139800 + if (res != QM_MCR_RESULT_OK) {
139801 + pr_err("CEETM: CONFIGURE CHANNEL MAPPING failed\n");
139802 + return -EIO;
139803 + }
139804 + return 0;
139805 +}
139806 +
139807 +static int qman_ceetm_query_mapping_shaper_tcfc(
139808 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query *opts,
139809 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query *response)
139810 +{
139811 + struct qm_mc_command *mcc;
139812 + struct qm_mc_result *mcr;
139813 + struct qman_portal *p;
139814 + unsigned long irqflags __maybe_unused;
139815 + u8 res;
139816 +
139817 + p = get_affine_portal();
139818 + PORTAL_IRQ_LOCK(p, irqflags);
139819 +
139820 + mcc = qm_mc_start(&p->p);
139821 + mcc->mst_query = *opts;
139822 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
139823 + while (!(mcr = qm_mc_result(&p->p)))
139824 + cpu_relax();
139825 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139826 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
139827 + res = mcr->result;
139828 +
139829 + PORTAL_IRQ_UNLOCK(p, irqflags);
139830 + put_affine_portal();
139831 +
139832 + if (res != QM_MCR_RESULT_OK) {
139833 + pr_err("CEETM: QUERY CHANNEL MAPPING failed\n");
139834 + return -EIO;
139835 + }
139836 +
139837 + *response = mcr->mst_query;
139838 + return 0;
139839 +}
139840 +
139841 +static int qman_ceetm_configure_ccgr(struct qm_mcc_ceetm_ccgr_config *opts)
139842 +{
139843 + struct qm_mc_command *mcc;
139844 + struct qm_mc_result *mcr;
139845 + struct qman_portal *p;
139846 + unsigned long irqflags __maybe_unused;
139847 + u8 res;
139848 +
139849 + p = get_affine_portal();
139850 + PORTAL_IRQ_LOCK(p, irqflags);
139851 +
139852 + mcc = qm_mc_start(&p->p);
139853 + mcc->ccgr_config = *opts;
139854 +
139855 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_CONFIG);
139856 + while (!(mcr = qm_mc_result(&p->p)))
139857 + cpu_relax();
139858 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_CONFIG);
139859 +
139860 + PORTAL_IRQ_UNLOCK(p, irqflags);
139861 + put_affine_portal();
139862 +
139863 + res = mcr->result;
139864 + if (res != QM_MCR_RESULT_OK) {
139865 + pr_err("CEETM: CONFIGURE CCGR failed\n");
139866 + return -EIO;
139867 + }
139868 + return 0;
139869 +}
139870 +
139871 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
139872 + struct qm_mcr_ceetm_ccgr_query *response)
139873 +{
139874 + struct qm_mc_command *mcc;
139875 + struct qm_mc_result *mcr;
139876 + struct qman_portal *p;
139877 + unsigned long irqflags __maybe_unused;
139878 + u8 res;
139879 +
139880 + p = get_affine_portal();
139881 + PORTAL_IRQ_LOCK(p, irqflags);
139882 +
139883 + mcc = qm_mc_start(&p->p);
139884 + mcc->ccgr_query.ccgrid = cpu_to_be16(ccgr_query->ccgrid);
139885 + mcc->ccgr_query.dcpid = ccgr_query->dcpid;
139886 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
139887 +
139888 + while (!(mcr = qm_mc_result(&p->p)))
139889 + cpu_relax();
139890 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_QUERY);
139891 + res = mcr->result;
139892 + if (res == QM_MCR_RESULT_OK) {
139893 + *response = mcr->ccgr_query;
139894 + hw_ccgr_query_to_cpu(response);
139895 + }
139896 +
139897 + PORTAL_IRQ_UNLOCK(p, irqflags);
139898 + put_affine_portal();
139899 + if (res != QM_MCR_RESULT_OK) {
139900 + pr_err("CEETM: QUERY CCGR failed\n");
139901 + return -EIO;
139902 + }
139903 + return 0;
139904 +}
139905 +EXPORT_SYMBOL(qman_ceetm_query_ccgr);
139906 +
139907 +static int qman_ceetm_cq_peek_pop_xsfdrread(struct qm_ceetm_cq *cq,
139908 + u8 command_type, u16 xsfdr,
139909 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread *cq_ppxr)
139910 +{
139911 + struct qm_mc_command *mcc;
139912 + struct qm_mc_result *mcr;
139913 + struct qman_portal *p;
139914 + unsigned long irqflags __maybe_unused;
139915 + u8 res;
139916 +
139917 + p = get_affine_portal();
139918 + PORTAL_IRQ_LOCK(p, irqflags);
139919 +
139920 + mcc = qm_mc_start(&p->p);
139921 + switch (command_type) {
139922 + case 0:
139923 + case 1:
139924 + mcc->cq_ppxr.cqid = (cq->parent->idx << 4) | cq->idx;
139925 + break;
139926 + case 2:
139927 + mcc->cq_ppxr.xsfdr = xsfdr;
139928 + break;
139929 + default:
139930 + break;
139931 + }
139932 + mcc->cq_ppxr.ct = command_type;
139933 + mcc->cq_ppxr.dcpid = cq->parent->dcp_idx;
139934 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139935 + while (!(mcr = qm_mc_result(&p->p)))
139936 + cpu_relax();
139937 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139938 + QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139939 +
139940 + PORTAL_IRQ_UNLOCK(p, irqflags);
139941 + put_affine_portal();
139942 +
139943 + res = mcr->result;
139944 + if (res != QM_MCR_RESULT_OK) {
139945 + pr_err("CEETM: CQ PEEK/POP/XSFDR READ failed\n");
139946 + return -EIO;
139947 + }
139948 + *cq_ppxr = mcr->cq_ppxr;
139949 + return 0;
139950 +}
139951 +
139952 +static int qman_ceetm_query_statistics(u16 cid,
139953 + enum qm_dc_portal dcp_idx,
139954 + u16 command_type,
139955 + struct qm_mcr_ceetm_statistics_query *query_result)
139956 +{
139957 + struct qm_mc_command *mcc;
139958 + struct qm_mc_result *mcr;
139959 + struct qman_portal *p;
139960 + unsigned long irqflags __maybe_unused;
139961 + u8 res;
139962 +
139963 + p = get_affine_portal();
139964 + PORTAL_IRQ_LOCK(p, irqflags);
139965 +
139966 + mcc = qm_mc_start(&p->p);
139967 + mcc->stats_query_write.cid = cid;
139968 + mcc->stats_query_write.dcpid = dcp_idx;
139969 + mcc->stats_query_write.ct = command_type;
139970 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139971 +
139972 + while (!(mcr = qm_mc_result(&p->p)))
139973 + cpu_relax();
139974 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139975 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139976 +
139977 + PORTAL_IRQ_UNLOCK(p, irqflags);
139978 + put_affine_portal();
139979 +
139980 + res = mcr->result;
139981 + if (res != QM_MCR_RESULT_OK) {
139982 + pr_err("CEETM: STATISTICS QUERY failed\n");
139983 + return -EIO;
139984 + }
139985 + *query_result = mcr->stats_query;
139986 + return 0;
139987 +}
139988 +
139989 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
139990 + u16 command_type, u64 frame_count,
139991 + u64 byte_count)
139992 +{
139993 + struct qm_mc_command *mcc;
139994 + struct qm_mc_result *mcr;
139995 + struct qman_portal *p;
139996 + unsigned long irqflags __maybe_unused;
139997 + u8 res;
139998 +
139999 + p = get_affine_portal();
140000 + PORTAL_IRQ_LOCK(p, irqflags);
140001 +
140002 + mcc = qm_mc_start(&p->p);
140003 + mcc->stats_query_write.cid = cid;
140004 + mcc->stats_query_write.dcpid = dcp_idx;
140005 + mcc->stats_query_write.ct = command_type;
140006 + mcc->stats_query_write.frm_cnt = frame_count;
140007 + mcc->stats_query_write.byte_cnt = byte_count;
140008 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
140009 +
140010 + while (!(mcr = qm_mc_result(&p->p)))
140011 + cpu_relax();
140012 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140013 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
140014 +
140015 + PORTAL_IRQ_UNLOCK(p, irqflags);
140016 + put_affine_portal();
140017 +
140018 + res = mcr->result;
140019 + if (res != QM_MCR_RESULT_OK) {
140020 + pr_err("CEETM: STATISTICS WRITE failed\n");
140021 + return -EIO;
140022 + }
140023 + return 0;
140024 +}
140025 +EXPORT_SYMBOL(qman_ceetm_query_write_statistics);
140026 +
140027 +int qman_ceetm_bps2tokenrate(u64 bps, struct qm_ceetm_rate *token_rate,
140028 + int rounding)
140029 +{
140030 + u16 pres;
140031 + u64 temp;
140032 + u64 qman_freq;
140033 + int ret;
140034 +
140035 + /* Read PRES from CEET_CFG_PRES register */
140036 + ret = qman_ceetm_get_prescaler(&pres);
140037 + if (ret)
140038 + return -EINVAL;
140039 +
140040 + ret = qm_get_clock(&qman_freq);
140041 + if (ret)
140042 + return -EINVAL;
140043 +
140044 + /* token-rate = bytes-per-second * update-reference-period
140045 + *
140046 + * Where token-rate is N/8192 for a integer N, and
140047 + * update-reference-period is (2^22)/(PRES*QHz), where PRES
140048 + * is the prescalar value and QHz is the QMan clock frequency.
140049 + * So:
140050 + *
140051 + * token-rate = (byte-per-second*2^22)/PRES*QHZ)
140052 + *
140053 + * Converting to bits-per-second gives;
140054 + *
140055 + * token-rate = (bps*2^19) / (PRES*QHZ)
140056 + * N = (bps*2^32) / (PRES*QHz)
140057 + *
140058 + * And to avoid 64-bit overflow if 'bps' is larger than 4Gbps
140059 + * (yet minimise rounding error if 'bps' is small), we reorganise
140060 + * the formula to use two 16-bit shifts rather than 1 32-bit shift.
140061 + * N = (((bps*2^16)/PRES)*2^16)/QHz
140062 + */
140063 + temp = ROUNDING((bps << 16), pres, rounding);
140064 + temp = ROUNDING((temp << 16), qman_freq, rounding);
140065 + token_rate->whole = temp >> 13;
140066 + token_rate->fraction = temp & (((u64)1 << 13) - 1);
140067 + return 0;
140068 +}
140069 +EXPORT_SYMBOL(qman_ceetm_bps2tokenrate);
140070 +
140071 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, u64 *bps,
140072 + int rounding)
140073 +{
140074 + u16 pres;
140075 + u64 temp;
140076 + u64 qman_freq;
140077 + int ret;
140078 +
140079 + /* Read PRES from CEET_CFG_PRES register */
140080 + ret = qman_ceetm_get_prescaler(&pres);
140081 + if (ret)
140082 + return -EINVAL;
140083 +
140084 + ret = qm_get_clock(&qman_freq);
140085 + if (ret)
140086 + return -EINVAL;
140087 +
140088 + /* bytes-per-second = token-rate / update-reference-period
140089 + *
140090 + * where "token-rate" is N/8192 for an integer N, and
140091 + * "update-reference-period" is (2^22)/(PRES*QHz), where PRES is
140092 + * the prescalar value and QHz is the QMan clock frequency. So;
140093 + *
140094 + * bytes-per-second = (N/8192) / (4194304/PRES*QHz)
140095 + * = N*PRES*QHz / (4194304*8192)
140096 + * = N*PRES*QHz / (2^35)
140097 + *
140098 + * Converting to bits-per-second gives;
140099 + *
140100 + * bps = N*PRES*QHZ / (2^32)
140101 + *
140102 + * Note, the numerator has a maximum width of 72 bits! So to
140103 + * avoid 64-bit overflow errors, we calculate PRES*QHZ (maximum
140104 + * width 48 bits) divided by 2^9 (reducing to maximum 39 bits), before
140105 + * multiplying by N (goes to maximum of 63 bits).
140106 + *
140107 + * temp = PRES*QHZ / (2^16)
140108 + * kbps = temp*N / (2^16)
140109 + */
140110 + temp = ROUNDING(qman_freq * pres, (u64)1 << 16 , rounding);
140111 + temp *= ((token_rate->whole << 13) + token_rate->fraction);
140112 + *bps = ROUNDING(temp, (u64)(1) << 16, rounding);
140113 + return 0;
140114 +}
140115 +EXPORT_SYMBOL(qman_ceetm_tokenrate2bps);
140116 +
140117 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, enum qm_dc_portal dcp_idx,
140118 + unsigned int sp_idx)
140119 +{
140120 + struct qm_ceetm_sp *p;
140121 +
140122 + DPA_ASSERT((dcp_idx == qm_dc_portal_fman0) ||
140123 + (dcp_idx == qm_dc_portal_fman1));
140124 +
140125 + if ((sp_idx < qman_ceetms[dcp_idx].sp_range[0]) ||
140126 + (sp_idx >= (qman_ceetms[dcp_idx].sp_range[0] +
140127 + qman_ceetms[dcp_idx].sp_range[1]))) {
140128 + pr_err("Sub-portal index doesn't exist\n");
140129 + return -EINVAL;
140130 + }
140131 +
140132 + list_for_each_entry(p, &qman_ceetms[dcp_idx].sub_portals, node) {
140133 + if ((p->idx == sp_idx) && (p->is_claimed == 0)) {
140134 + p->is_claimed = 1;
140135 + *sp = p;
140136 + return 0;
140137 + }
140138 + }
140139 + pr_err("The sub-portal#%d is not available!\n", sp_idx);
140140 + return -ENODEV;
140141 +}
140142 +EXPORT_SYMBOL(qman_ceetm_sp_claim);
140143 +
140144 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp)
140145 +{
140146 + struct qm_ceetm_sp *p;
140147 +
140148 + if (sp->lni && sp->lni->is_claimed == 1) {
140149 + pr_err("The dependency of sub-portal has not been released!\n");
140150 + return -EBUSY;
140151 + }
140152 +
140153 + list_for_each_entry(p, &qman_ceetms[sp->dcp_idx].sub_portals, node) {
140154 + if (p->idx == sp->idx) {
140155 + p->is_claimed = 0;
140156 + p->lni = NULL;
140157 + }
140158 + }
140159 + /* Disable CEETM mode of this sub-portal */
140160 + qman_sp_disable_ceetm_mode(sp->dcp_idx, sp->idx);
140161 +
140162 + return 0;
140163 +}
140164 +EXPORT_SYMBOL(qman_ceetm_sp_release);
140165 +
140166 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, enum qm_dc_portal dcp_idx,
140167 + unsigned int lni_idx)
140168 +{
140169 + struct qm_ceetm_lni *p;
140170 +
140171 + if ((lni_idx < qman_ceetms[dcp_idx].lni_range[0]) ||
140172 + (lni_idx >= (qman_ceetms[dcp_idx].lni_range[0] +
140173 + qman_ceetms[dcp_idx].lni_range[1]))) {
140174 + pr_err("The lni index is out of range\n");
140175 + return -EINVAL;
140176 + }
140177 +
140178 + list_for_each_entry(p, &qman_ceetms[dcp_idx].lnis, node) {
140179 + if ((p->idx == lni_idx) && (p->is_claimed == 0)) {
140180 + *lni = p;
140181 + p->is_claimed = 1;
140182 + return 0;
140183 + }
140184 + }
140185 +
140186 + pr_err("The LNI#%d is not available!\n", lni_idx);
140187 + return -EINVAL;
140188 +}
140189 +EXPORT_SYMBOL(qman_ceetm_lni_claim);
140190 +
140191 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni)
140192 +{
140193 + struct qm_ceetm_lni *p;
140194 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140195 +
140196 + if (!list_empty(&lni->channels)) {
140197 + pr_err("The LNI dependencies are not released!\n");
140198 + return -EBUSY;
140199 + }
140200 +
140201 + list_for_each_entry(p, &qman_ceetms[lni->dcp_idx].lnis, node) {
140202 + if (p->idx == lni->idx) {
140203 + p->shaper_enable = 0;
140204 + p->shaper_couple = 0;
140205 + p->cr_token_rate.whole = 0;
140206 + p->cr_token_rate.fraction = 0;
140207 + p->er_token_rate.whole = 0;
140208 + p->er_token_rate.fraction = 0;
140209 + p->cr_token_bucket_limit = 0;
140210 + p->er_token_bucket_limit = 0;
140211 + p->is_claimed = 0;
140212 + }
140213 + }
140214 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140215 + config_opts.dcpid = lni->dcp_idx;
140216 + memset(&config_opts.shaper_config, 0,
140217 + sizeof(config_opts.shaper_config));
140218 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140219 +}
140220 +EXPORT_SYMBOL(qman_ceetm_lni_release);
140221 +
140222 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, struct qm_ceetm_lni *lni)
140223 +{
140224 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140225 +
140226 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
140227 + config_opts.dcpid = sp->dcp_idx;
140228 + config_opts.sp_mapping.map_lni_id = lni->idx;
140229 + sp->lni = lni;
140230 +
140231 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts))
140232 + return -EINVAL;
140233 +
140234 + /* Enable CEETM mode for this sub-portal */
140235 + return qman_sp_enable_ceetm_mode(sp->dcp_idx, sp->idx);
140236 +}
140237 +EXPORT_SYMBOL(qman_ceetm_sp_set_lni);
140238 +
140239 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, unsigned int *lni_idx)
140240 +{
140241 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140242 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140243 +
140244 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
140245 + query_opts.dcpid = sp->dcp_idx;
140246 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140247 + pr_err("Can't get SP <-> LNI mapping\n");
140248 + return -EINVAL;
140249 + }
140250 + *lni_idx = query_result.sp_mapping_query.map_lni_id;
140251 + sp->lni->idx = query_result.sp_mapping_query.map_lni_id;
140252 + return 0;
140253 +}
140254 +EXPORT_SYMBOL(qman_ceetm_sp_get_lni);
140255 +
140256 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
140257 + int oal)
140258 +{
140259 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140260 +
140261 + if (lni->shaper_enable) {
140262 + pr_err("The shaper has already been enabled\n");
140263 + return -EINVAL;
140264 + }
140265 + lni->shaper_enable = 1;
140266 + lni->shaper_couple = coupled;
140267 + lni->oal = oal;
140268 +
140269 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140270 + config_opts.dcpid = lni->dcp_idx;
140271 + config_opts.shaper_config.cpl = coupled;
140272 + config_opts.shaper_config.oal = oal;
140273 + config_opts.shaper_config.crtcr = cpu_to_be24((lni->cr_token_rate.whole
140274 + << 13) | lni->cr_token_rate.fraction);
140275 + config_opts.shaper_config.ertcr = cpu_to_be24((lni->er_token_rate.whole
140276 + << 13) | lni->er_token_rate.fraction);
140277 + config_opts.shaper_config.crtbl =
140278 + cpu_to_be16(lni->cr_token_bucket_limit);
140279 + config_opts.shaper_config.ertbl =
140280 + cpu_to_be16(lni->er_token_bucket_limit);
140281 + config_opts.shaper_config.mps = 60;
140282 +
140283 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140284 +}
140285 +EXPORT_SYMBOL(qman_ceetm_lni_enable_shaper);
140286 +
140287 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni)
140288 +{
140289 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140290 +
140291 + if (!lni->shaper_enable) {
140292 + pr_err("The shaper has been disabled\n");
140293 + return -EINVAL;
140294 + }
140295 +
140296 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140297 + config_opts.dcpid = lni->dcp_idx;
140298 + config_opts.shaper_config.cpl = lni->shaper_couple;
140299 + config_opts.shaper_config.oal = lni->oal;
140300 + config_opts.shaper_config.crtbl =
140301 + cpu_to_be16(lni->cr_token_bucket_limit);
140302 + config_opts.shaper_config.ertbl =
140303 + cpu_to_be16(lni->er_token_bucket_limit);
140304 + /* Set CR/ER rate with all 1's to configure an infinite rate, thus
140305 + * disable the shaping.
140306 + */
140307 + config_opts.shaper_config.crtcr = 0xFFFFFF;
140308 + config_opts.shaper_config.ertcr = 0xFFFFFF;
140309 + config_opts.shaper_config.mps = 60;
140310 + lni->shaper_enable = 0;
140311 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140312 +}
140313 +EXPORT_SYMBOL(qman_ceetm_lni_disable_shaper);
140314 +
140315 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni)
140316 +{
140317 + return lni->shaper_enable;
140318 +}
140319 +EXPORT_SYMBOL(qman_ceetm_lni_is_shaper_enabled);
140320 +
140321 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
140322 + const struct qm_ceetm_rate *token_rate,
140323 + u16 token_limit)
140324 +{
140325 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140326 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140327 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140328 + int ret;
140329 +
140330 + lni->cr_token_rate.whole = token_rate->whole;
140331 + lni->cr_token_rate.fraction = token_rate->fraction;
140332 + lni->cr_token_bucket_limit = token_limit;
140333 + if (!lni->shaper_enable)
140334 + return 0;
140335 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140336 + query_opts.dcpid = lni->dcp_idx;
140337 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
140338 + &query_result);
140339 + if (ret) {
140340 + pr_err("Fail to get current LNI shaper setting\n");
140341 + return -EINVAL;
140342 + }
140343 +
140344 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140345 + config_opts.dcpid = lni->dcp_idx;
140346 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole << 13)
140347 + | (token_rate->fraction));
140348 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140349 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140350 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
140351 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
140352 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
140353 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
140354 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140355 +}
140356 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate);
140357 +
140358 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
140359 + u64 bps,
140360 + u16 token_limit)
140361 +{
140362 + struct qm_ceetm_rate token_rate;
140363 + int ret;
140364 +
140365 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140366 + if (ret) {
140367 + pr_err("Can not convert bps to token rate\n");
140368 + return -EINVAL;
140369 + }
140370 +
140371 + return qman_ceetm_lni_set_commit_rate(lni, &token_rate, token_limit);
140372 +}
140373 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate_bps);
140374 +
140375 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
140376 + struct qm_ceetm_rate *token_rate,
140377 + u16 *token_limit)
140378 +{
140379 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140380 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140381 + int ret;
140382 +
140383 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140384 + query_opts.dcpid = lni->dcp_idx;
140385 +
140386 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140387 + if (ret) {
140388 + pr_err("The LNI CR rate or limit is not set\n");
140389 + return -EINVAL;
140390 + }
140391 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
140392 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
140393 + 0x1FFF;
140394 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140395 + return 0;
140396 +}
140397 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate);
140398 +
140399 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
140400 + u64 *bps, u16 *token_limit)
140401 +{
140402 + struct qm_ceetm_rate token_rate;
140403 + int ret;
140404 +
140405 + ret = qman_ceetm_lni_get_commit_rate(lni, &token_rate, token_limit);
140406 + if (ret) {
140407 + pr_err("The LNI CR rate or limit is not available\n");
140408 + return -EINVAL;
140409 + }
140410 +
140411 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140412 +}
140413 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate_bps);
140414 +
140415 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
140416 + const struct qm_ceetm_rate *token_rate,
140417 + u16 token_limit)
140418 +{
140419 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140420 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140421 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140422 + int ret;
140423 +
140424 + lni->er_token_rate.whole = token_rate->whole;
140425 + lni->er_token_rate.fraction = token_rate->fraction;
140426 + lni->er_token_bucket_limit = token_limit;
140427 + if (!lni->shaper_enable)
140428 + return 0;
140429 +
140430 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140431 + query_opts.dcpid = lni->dcp_idx;
140432 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
140433 + &query_result);
140434 + if (ret) {
140435 + pr_err("Fail to get current LNI shaper setting\n");
140436 + return -EINVAL;
140437 + }
140438 +
140439 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140440 + config_opts.dcpid = lni->dcp_idx;
140441 + config_opts.shaper_config.ertcr = cpu_to_be24(
140442 + (token_rate->whole << 13) | (token_rate->fraction));
140443 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
140444 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140445 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
140446 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
140447 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
140448 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
140449 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140450 +}
140451 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate);
140452 +
140453 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
140454 + u64 bps,
140455 + u16 token_limit)
140456 +{
140457 + struct qm_ceetm_rate token_rate;
140458 + int ret;
140459 +
140460 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140461 + if (ret) {
140462 + pr_err("Can not convert bps to token rate\n");
140463 + return -EINVAL;
140464 + }
140465 + return qman_ceetm_lni_set_excess_rate(lni, &token_rate, token_limit);
140466 +}
140467 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate_bps);
140468 +
140469 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
140470 + struct qm_ceetm_rate *token_rate,
140471 + u16 *token_limit)
140472 +{
140473 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140474 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140475 + int ret;
140476 +
140477 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140478 + query_opts.dcpid = lni->dcp_idx;
140479 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140480 + if (ret) {
140481 + pr_err("The LNI ER rate or limit is not set\n");
140482 + return -EINVAL;
140483 + }
140484 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
140485 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
140486 + 0x1FFF;
140487 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
140488 + return 0;
140489 +}
140490 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate);
140491 +
140492 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
140493 + u64 *bps, u16 *token_limit)
140494 +{
140495 + struct qm_ceetm_rate token_rate;
140496 + int ret;
140497 +
140498 + ret = qman_ceetm_lni_get_excess_rate(lni, &token_rate, token_limit);
140499 + if (ret) {
140500 + pr_err("The LNI ER rate or limit is not available\n");
140501 + return -EINVAL;
140502 + }
140503 +
140504 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140505 +}
140506 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate_bps);
140507 +
140508 +#define QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(n) ((15 - n) * 4)
140509 +#define QMAN_CEETM_LNITCFCC_ENABLE 0x8
140510 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
140511 + unsigned int cq_level,
140512 + int traffic_class)
140513 +{
140514 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140515 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140516 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140517 + u64 lnitcfcc;
140518 +
140519 + if ((cq_level > 15) | (traffic_class > 7)) {
140520 + pr_err("The CQ or traffic class id is out of range\n");
140521 + return -EINVAL;
140522 + }
140523 +
140524 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
140525 + query_opts.dcpid = lni->dcp_idx;
140526 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140527 + pr_err("Fail to query tcfcc\n");
140528 + return -EINVAL;
140529 + }
140530 +
140531 + lnitcfcc = be64_to_cpu(query_result.tcfc_query.lnitcfcc);
140532 + if (traffic_class == -1) {
140533 + /* disable tcfc for this CQ */
140534 + lnitcfcc &= ~((u64)QMAN_CEETM_LNITCFCC_ENABLE <<
140535 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
140536 + } else {
140537 + lnitcfcc &= ~((u64)0xF <<
140538 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
140539 + lnitcfcc |= ((u64)(QMAN_CEETM_LNITCFCC_ENABLE |
140540 + traffic_class)) <<
140541 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level);
140542 + }
140543 + config_opts.tcfc_config.lnitcfcc = cpu_to_be64(lnitcfcc);
140544 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
140545 + config_opts.dcpid = lni->dcp_idx;
140546 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140547 +}
140548 +EXPORT_SYMBOL(qman_ceetm_lni_set_tcfcc);
140549 +
140550 +#define QMAN_CEETM_LNITCFCC_TC_MASK 0x7
140551 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, unsigned int cq_level,
140552 + int *traffic_class)
140553 +{
140554 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140555 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140556 + int ret;
140557 + u8 lnitcfcc;
140558 +
140559 + if (cq_level > 15) {
140560 + pr_err("the CQ level is out of range\n");
140561 + return -EINVAL;
140562 + }
140563 +
140564 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
140565 + query_opts.dcpid = lni->dcp_idx;
140566 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140567 + if (ret)
140568 + return ret;
140569 + lnitcfcc = (u8)be64_to_cpu((query_result.tcfc_query.lnitcfcc) >>
140570 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
140571 + if (lnitcfcc & QMAN_CEETM_LNITCFCC_ENABLE)
140572 + *traffic_class = lnitcfcc & QMAN_CEETM_LNITCFCC_TC_MASK;
140573 + else
140574 + *traffic_class = -1;
140575 + return 0;
140576 +}
140577 +EXPORT_SYMBOL(qman_ceetm_lni_get_tcfcc);
140578 +
140579 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
140580 + struct qm_ceetm_lni *lni)
140581 +{
140582 + struct qm_ceetm_channel *p;
140583 + u32 channel_idx;
140584 + int ret = 0;
140585 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140586 +
140587 + if (lni->dcp_idx == qm_dc_portal_fman0) {
140588 + ret = qman_alloc_ceetm0_channel(&channel_idx);
140589 + } else if (lni->dcp_idx == qm_dc_portal_fman1) {
140590 + ret = qman_alloc_ceetm1_channel(&channel_idx);
140591 + } else {
140592 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140593 + lni->dcp_idx);
140594 + return -EINVAL;
140595 + }
140596 +
140597 + if (ret) {
140598 + pr_err("The is no channel available for LNI#%d\n", lni->idx);
140599 + return -ENODEV;
140600 + }
140601 +
140602 + p = kzalloc(sizeof(*p), GFP_KERNEL);
140603 + if (!p)
140604 + return -ENOMEM;
140605 + p->idx = channel_idx;
140606 + p->dcp_idx = lni->dcp_idx;
140607 + p->lni_idx = lni->idx;
140608 + list_add_tail(&p->node, &lni->channels);
140609 + INIT_LIST_HEAD(&p->class_queues);
140610 + INIT_LIST_HEAD(&p->ccgs);
140611 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140612 + channel_idx);
140613 + config_opts.dcpid = lni->dcp_idx;
140614 + config_opts.channel_mapping.map_lni_id = lni->idx;
140615 + config_opts.channel_mapping.map_shaped = 0;
140616 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140617 + pr_err("Can't map channel#%d for LNI#%d\n",
140618 + channel_idx, lni->idx);
140619 + return -EINVAL;
140620 + }
140621 + *channel = p;
140622 + return 0;
140623 +}
140624 +EXPORT_SYMBOL(qman_ceetm_channel_claim);
140625 +
140626 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel)
140627 +{
140628 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140629 + if (!list_empty(&channel->class_queues)) {
140630 + pr_err("CEETM channel#%d has class queue unreleased!\n",
140631 + channel->idx);
140632 + return -EBUSY;
140633 + }
140634 + if (!list_empty(&channel->ccgs)) {
140635 + pr_err("CEETM channel#%d has ccg unreleased!\n",
140636 + channel->idx);
140637 + return -EBUSY;
140638 + }
140639 +
140640 + /* channel->dcp_idx corresponds to known fman validation */
140641 + if ((channel->dcp_idx != qm_dc_portal_fman0) &&
140642 + (channel->dcp_idx != qm_dc_portal_fman1)) {
140643 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140644 + channel->dcp_idx);
140645 + return -EINVAL;
140646 + }
140647 +
140648 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140649 + channel->idx);
140650 + config_opts.dcpid = channel->dcp_idx;
140651 + memset(&config_opts.shaper_config, 0,
140652 + sizeof(config_opts.shaper_config));
140653 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140654 + pr_err("Can't reset channel shapping parameters\n");
140655 + return -EINVAL;
140656 + }
140657 +
140658 + if (channel->dcp_idx == qm_dc_portal_fman0) {
140659 + qman_release_ceetm0_channelid(channel->idx);
140660 + } else if (channel->dcp_idx == qm_dc_portal_fman1) {
140661 + qman_release_ceetm1_channelid(channel->idx);
140662 + } else {
140663 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140664 + channel->dcp_idx);
140665 + return -EINVAL;
140666 + }
140667 + list_del(&channel->node);
140668 + kfree(channel);
140669 +
140670 + return 0;
140671 +}
140672 +EXPORT_SYMBOL(qman_ceetm_channel_release);
140673 +
140674 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
140675 + int coupled)
140676 +{
140677 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140678 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140679 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140680 +
140681 + if (channel->shaper_enable == 1) {
140682 + pr_err("This channel shaper has been enabled!\n");
140683 + return -EINVAL;
140684 + }
140685 +
140686 + channel->shaper_enable = 1;
140687 + channel->shaper_couple = coupled;
140688 +
140689 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140690 + channel->idx);
140691 + query_opts.dcpid = channel->dcp_idx;
140692 +
140693 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140694 + pr_err("Can't query channel mapping\n");
140695 + return -EINVAL;
140696 + }
140697 +
140698 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140699 + channel->idx);
140700 + config_opts.dcpid = channel->dcp_idx;
140701 + config_opts.channel_mapping.map_lni_id =
140702 + query_result.channel_mapping_query.map_lni_id;
140703 + config_opts.channel_mapping.map_shaped = 1;
140704 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140705 + pr_err("Can't enable shaper for channel #%d\n", channel->idx);
140706 + return -EINVAL;
140707 + }
140708 +
140709 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140710 + channel->idx);
140711 + config_opts.shaper_config.cpl = coupled;
140712 + config_opts.shaper_config.crtcr =
140713 + cpu_to_be24((channel->cr_token_rate.whole
140714 + << 13) |
140715 + channel->cr_token_rate.fraction);
140716 + config_opts.shaper_config.ertcr =
140717 + cpu_to_be24(channel->er_token_rate.whole
140718 + << 13 |
140719 + channel->er_token_rate.fraction);
140720 + config_opts.shaper_config.crtbl =
140721 + cpu_to_be16(channel->cr_token_bucket_limit);
140722 + config_opts.shaper_config.ertbl =
140723 + cpu_to_be16(channel->er_token_bucket_limit);
140724 +
140725 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140726 +}
140727 +EXPORT_SYMBOL(qman_ceetm_channel_enable_shaper);
140728 +
140729 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel)
140730 +{
140731 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140732 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140733 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140734 +
140735 +
140736 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140737 + channel->idx);
140738 + query_opts.dcpid = channel->dcp_idx;
140739 +
140740 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140741 + pr_err("Can't query channel mapping\n");
140742 + return -EINVAL;
140743 + }
140744 +
140745 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140746 + channel->idx);
140747 + config_opts.dcpid = channel->dcp_idx;
140748 + config_opts.channel_mapping.map_shaped = 0;
140749 + config_opts.channel_mapping.map_lni_id =
140750 + query_result.channel_mapping_query.map_lni_id;
140751 +
140752 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140753 +}
140754 +EXPORT_SYMBOL(qman_ceetm_channel_disable_shaper);
140755 +
140756 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel)
140757 +{
140758 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140759 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140760 +
140761 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140762 + channel->idx);
140763 + query_opts.dcpid = channel->dcp_idx;
140764 +
140765 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140766 + pr_err("Can't query channel mapping\n");
140767 + return -EINVAL;
140768 + }
140769 +
140770 + return query_result.channel_mapping_query.map_shaped;
140771 +}
140772 +EXPORT_SYMBOL(qman_ceetm_channel_is_shaper_enabled);
140773 +
140774 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
140775 + const struct qm_ceetm_rate *token_rate,
140776 + u16 token_limit)
140777 +{
140778 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140779 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140780 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140781 + int ret;
140782 +
140783 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140784 + channel->idx);
140785 + query_opts.dcpid = channel->dcp_idx;
140786 +
140787 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140788 + if (ret) {
140789 + pr_err("Fail to get the current channel shaper setting\n");
140790 + return -EINVAL;
140791 + }
140792 +
140793 + channel->cr_token_rate.whole = token_rate->whole;
140794 + channel->cr_token_rate.fraction = token_rate->fraction;
140795 + channel->cr_token_bucket_limit = token_limit;
140796 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140797 + channel->idx);
140798 + config_opts.dcpid = channel->dcp_idx;
140799 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole
140800 + << 13) | (token_rate->fraction));
140801 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140802 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140803 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
140804 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
140805 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140806 +}
140807 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate);
140808 +
140809 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
140810 + u64 bps, u16 token_limit)
140811 +{
140812 + struct qm_ceetm_rate token_rate;
140813 + int ret;
140814 +
140815 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140816 + if (ret) {
140817 + pr_err("Can not convert bps to token rate\n");
140818 + return -EINVAL;
140819 + }
140820 + return qman_ceetm_channel_set_commit_rate(channel, &token_rate,
140821 + token_limit);
140822 +}
140823 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate_bps);
140824 +
140825 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
140826 + struct qm_ceetm_rate *token_rate,
140827 + u16 *token_limit)
140828 +{
140829 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140830 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140831 + int ret;
140832 +
140833 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140834 + channel->idx);
140835 + query_opts.dcpid = channel->dcp_idx;
140836 +
140837 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140838 + if (ret | !query_result.shaper_query.crtcr |
140839 + !query_result.shaper_query.crtbl) {
140840 + pr_err("The channel commit rate or limit is not set\n");
140841 + return -EINVAL;
140842 + }
140843 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
140844 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
140845 + 0x1FFF;
140846 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140847 + return 0;
140848 +}
140849 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate);
140850 +
140851 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
140852 + u64 *bps, u16 *token_limit)
140853 +{
140854 + struct qm_ceetm_rate token_rate;
140855 + int ret;
140856 +
140857 + ret = qman_ceetm_channel_get_commit_rate(channel, &token_rate,
140858 + token_limit);
140859 + if (ret) {
140860 + pr_err("The channel CR rate or limit is not available\n");
140861 + return -EINVAL;
140862 + }
140863 +
140864 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140865 +}
140866 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate_bps);
140867 +
140868 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
140869 + const struct qm_ceetm_rate *token_rate,
140870 + u16 token_limit)
140871 +{
140872 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140873 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140874 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140875 + int ret;
140876 +
140877 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140878 + channel->idx);
140879 + query_opts.dcpid = channel->dcp_idx;
140880 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140881 + if (ret) {
140882 + pr_err("Fail to get the current channel shaper setting\n");
140883 + return -EINVAL;
140884 + }
140885 +
140886 + channel->er_token_rate.whole = token_rate->whole;
140887 + channel->er_token_rate.fraction = token_rate->fraction;
140888 + channel->er_token_bucket_limit = token_limit;
140889 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140890 + channel->idx);
140891 + config_opts.dcpid = channel->dcp_idx;
140892 + config_opts.shaper_config.ertcr = cpu_to_be24(
140893 + (token_rate->whole << 13) | (token_rate->fraction));
140894 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
140895 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140896 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
140897 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
140898 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140899 +}
140900 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate);
140901 +
140902 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
140903 + u64 bps, u16 token_limit)
140904 +{
140905 + struct qm_ceetm_rate token_rate;
140906 + int ret;
140907 +
140908 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140909 + if (ret) {
140910 + pr_err("Can not convert bps to token rate\n");
140911 + return -EINVAL;
140912 + }
140913 + return qman_ceetm_channel_set_excess_rate(channel, &token_rate,
140914 + token_limit);
140915 +}
140916 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate_bps);
140917 +
140918 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
140919 + struct qm_ceetm_rate *token_rate,
140920 + u16 *token_limit)
140921 +{
140922 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140923 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140924 + int ret;
140925 +
140926 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140927 + channel->idx);
140928 + query_opts.dcpid = channel->dcp_idx;
140929 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140930 + if (ret | !query_result.shaper_query.ertcr |
140931 + !query_result.shaper_query.ertbl) {
140932 + pr_err("The channel excess rate or limit is not set\n");
140933 + return -EINVAL;
140934 + }
140935 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
140936 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
140937 + 0x1FFF;
140938 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
140939 + return 0;
140940 +}
140941 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate);
140942 +
140943 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
140944 + u64 *bps, u16 *token_limit)
140945 +{
140946 + struct qm_ceetm_rate token_rate;
140947 + int ret;
140948 +
140949 + ret = qman_ceetm_channel_get_excess_rate(channel, &token_rate,
140950 + token_limit);
140951 + if (ret) {
140952 + pr_err("The channel ER rate or limit is not available\n");
140953 + return -EINVAL;
140954 + }
140955 +
140956 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140957 +}
140958 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate_bps);
140959 +
140960 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
140961 + u16 token_limit)
140962 +{
140963 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140964 +
140965 + if (channel->shaper_enable) {
140966 + pr_err("This channel is a shaped one\n");
140967 + return -EINVAL;
140968 + }
140969 +
140970 + channel->cr_token_bucket_limit = token_limit;
140971 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140972 + channel->idx);
140973 + config_opts.dcpid = channel->dcp_idx;
140974 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140975 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140976 +}
140977 +EXPORT_SYMBOL(qman_ceetm_channel_set_weight);
140978 +
140979 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
140980 + u16 *token_limit)
140981 +{
140982 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140983 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140984 + int ret;
140985 +
140986 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140987 + channel->idx);
140988 + query_opts.dcpid = channel->dcp_idx;
140989 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140990 + if (ret | !query_result.shaper_query.crtbl) {
140991 + pr_err("This unshaped channel's uFQ wight is unavailable\n");
140992 + return -EINVAL;
140993 + }
140994 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140995 + return 0;
140996 +}
140997 +EXPORT_SYMBOL(qman_ceetm_channel_get_weight);
140998 +
140999 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, int group_b,
141000 + unsigned int prio_a, unsigned int prio_b)
141001 +{
141002 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
141003 + struct qm_mcr_ceetm_class_scheduler_query query_result;
141004 + int i;
141005 +
141006 + if (prio_a > 7) {
141007 + pr_err("The priority of group A is out of range\n");
141008 + return -EINVAL;
141009 + }
141010 + if (group_b && (prio_b > 7)) {
141011 + pr_err("The priority of group B is out of range\n");
141012 + return -EINVAL;
141013 + }
141014 +
141015 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
141016 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
141017 + return -EINVAL;
141018 + }
141019 +
141020 + config_opts.cqcid = cpu_to_be16(channel->idx);
141021 + config_opts.dcpid = channel->dcp_idx;
141022 + config_opts.gpc_combine_flag = !group_b;
141023 + config_opts.gpc_prio_a = prio_a;
141024 + config_opts.gpc_prio_b = prio_b;
141025 +
141026 + for (i = 0; i < 8; i++)
141027 + config_opts.w[i] = query_result.w[i];
141028 + config_opts.crem = query_result.crem;
141029 + config_opts.erem = query_result.erem;
141030 +
141031 + return qman_ceetm_configure_class_scheduler(&config_opts);
141032 +}
141033 +EXPORT_SYMBOL(qman_ceetm_channel_set_group);
141034 +
141035 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, int *group_b,
141036 + unsigned int *prio_a, unsigned int *prio_b)
141037 +{
141038 + struct qm_mcr_ceetm_class_scheduler_query query_result;
141039 +
141040 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
141041 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
141042 + return -EINVAL;
141043 + }
141044 + *group_b = !query_result.gpc_combine_flag;
141045 + *prio_a = query_result.gpc_prio_a;
141046 + *prio_b = query_result.gpc_prio_b;
141047 +
141048 + return 0;
141049 +}
141050 +EXPORT_SYMBOL(qman_ceetm_channel_get_group);
141051 +
141052 +#define GROUP_A_ELIGIBILITY_SET (1 << 8)
141053 +#define GROUP_B_ELIGIBILITY_SET (1 << 9)
141054 +#define CQ_ELIGIBILITY_SET(n) (1 << (7 - n))
141055 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
141056 + *channel, int group_b, int cre)
141057 +{
141058 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
141059 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
141060 + int i;
141061 +
141062 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
141063 + pr_err("Cannot get the channel %d scheduler setting.\n",
141064 + channel->idx);
141065 + return -EINVAL;
141066 + }
141067 + csch_config.cqcid = cpu_to_be16(channel->idx);
141068 + csch_config.dcpid = channel->dcp_idx;
141069 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
141070 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
141071 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
141072 +
141073 + for (i = 0; i < 8; i++)
141074 + csch_config.w[i] = csch_query.w[i];
141075 + csch_config.erem = csch_query.erem;
141076 + if (group_b)
141077 + csch_config.crem = (be16_to_cpu(csch_query.crem)
141078 + & ~GROUP_B_ELIGIBILITY_SET)
141079 + | (cre ? GROUP_B_ELIGIBILITY_SET : 0);
141080 + else
141081 + csch_config.crem = (be16_to_cpu(csch_query.crem)
141082 + & ~GROUP_A_ELIGIBILITY_SET)
141083 + | (cre ? GROUP_A_ELIGIBILITY_SET : 0);
141084 +
141085 + csch_config.crem = cpu_to_be16(csch_config.crem);
141086 +
141087 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
141088 + pr_err("Cannot config channel %d's scheduler with "
141089 + "group_%c's cr eligibility\n", channel->idx,
141090 + group_b ? 'b' : 'a');
141091 + return -EINVAL;
141092 + }
141093 +
141094 + return 0;
141095 +}
141096 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_cr_eligibility);
141097 +
141098 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
141099 + *channel, int group_b, int ere)
141100 +{
141101 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
141102 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
141103 + int i;
141104 +
141105 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
141106 + pr_err("Cannot get the channel %d scheduler setting.\n",
141107 + channel->idx);
141108 + return -EINVAL;
141109 + }
141110 + csch_config.cqcid = cpu_to_be16(channel->idx);
141111 + csch_config.dcpid = channel->dcp_idx;
141112 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
141113 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
141114 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
141115 +
141116 + for (i = 0; i < 8; i++)
141117 + csch_config.w[i] = csch_query.w[i];
141118 + csch_config.crem = csch_query.crem;
141119 + if (group_b)
141120 + csch_config.erem = (be16_to_cpu(csch_query.erem)
141121 + & ~GROUP_B_ELIGIBILITY_SET)
141122 + | (ere ? GROUP_B_ELIGIBILITY_SET : 0);
141123 + else
141124 + csch_config.erem = (be16_to_cpu(csch_query.erem)
141125 + & ~GROUP_A_ELIGIBILITY_SET)
141126 + | (ere ? GROUP_A_ELIGIBILITY_SET : 0);
141127 +
141128 + csch_config.erem = cpu_to_be16(csch_config.erem);
141129 +
141130 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
141131 + pr_err("Cannot config channel %d's scheduler with "
141132 + "group_%c's er eligibility\n", channel->idx,
141133 + group_b ? 'b' : 'a');
141134 + return -EINVAL;
141135 + }
141136 +
141137 + return 0;
141138 +}
141139 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_er_eligibility);
141140 +
141141 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
141142 + unsigned int idx, int cre)
141143 +{
141144 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
141145 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
141146 + int i;
141147 +
141148 + if (idx > 7) {
141149 + pr_err("CQ index is out of range\n");
141150 + return -EINVAL;
141151 + }
141152 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
141153 + pr_err("Cannot get the channel %d scheduler setting.\n",
141154 + channel->idx);
141155 + return -EINVAL;
141156 + }
141157 + csch_config.cqcid = cpu_to_be16(channel->idx);
141158 + csch_config.dcpid = channel->dcp_idx;
141159 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
141160 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
141161 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
141162 + for (i = 0; i < 8; i++)
141163 + csch_config.w[i] = csch_query.w[i];
141164 + csch_config.erem = csch_query.erem;
141165 + csch_config.crem = (be16_to_cpu(csch_query.crem)
141166 + & ~CQ_ELIGIBILITY_SET(idx)) |
141167 + (cre ? CQ_ELIGIBILITY_SET(idx) : 0);
141168 + csch_config.crem = cpu_to_be16(csch_config.crem);
141169 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
141170 + pr_err("Cannot config channel scheduler to set "
141171 + "cr eligibility mask for CQ#%d\n", idx);
141172 + return -EINVAL;
141173 + }
141174 +
141175 + return 0;
141176 +}
141177 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_cr_eligibility);
141178 +
141179 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
141180 + unsigned int idx, int ere)
141181 +{
141182 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
141183 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
141184 + int i;
141185 +
141186 + if (idx > 7) {
141187 + pr_err("CQ index is out of range\n");
141188 + return -EINVAL;
141189 + }
141190 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
141191 + pr_err("Cannot get the channel %d scheduler setting.\n",
141192 + channel->idx);
141193 + return -EINVAL;
141194 + }
141195 + csch_config.cqcid = cpu_to_be16(channel->idx);
141196 + csch_config.dcpid = channel->dcp_idx;
141197 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
141198 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
141199 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
141200 + for (i = 0; i < 8; i++)
141201 + csch_config.w[i] = csch_query.w[i];
141202 + csch_config.crem = csch_query.crem;
141203 + csch_config.erem = (be16_to_cpu(csch_query.erem)
141204 + & ~CQ_ELIGIBILITY_SET(idx)) |
141205 + (ere ? CQ_ELIGIBILITY_SET(idx) : 0);
141206 + csch_config.erem = cpu_to_be16(csch_config.erem);
141207 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
141208 + pr_err("Cannot config channel scheduler to set "
141209 + "er eligibility mask for CQ#%d\n", idx);
141210 + return -EINVAL;
141211 + }
141212 + return 0;
141213 +}
141214 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_er_eligibility);
141215 +
141216 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
141217 + struct qm_ceetm_channel *channel, unsigned int idx,
141218 + struct qm_ceetm_ccg *ccg)
141219 +{
141220 + struct qm_ceetm_cq *p;
141221 + struct qm_mcc_ceetm_cq_config cq_config;
141222 +
141223 + if (idx > 7) {
141224 + pr_err("The independent class queue id is out of range\n");
141225 + return -EINVAL;
141226 + }
141227 +
141228 + list_for_each_entry(p, &channel->class_queues, node) {
141229 + if (p->idx == idx) {
141230 + pr_err("The CQ#%d has been claimed!\n", idx);
141231 + return -EINVAL;
141232 + }
141233 + }
141234 +
141235 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141236 + if (!p) {
141237 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
141238 + return -ENOMEM;
141239 + }
141240 +
141241 + list_add_tail(&p->node, &channel->class_queues);
141242 + p->idx = idx;
141243 + p->is_claimed = 1;
141244 + p->parent = channel;
141245 + INIT_LIST_HEAD(&p->bound_lfqids);
141246 +
141247 + if (ccg) {
141248 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
141249 + cq_config.dcpid = channel->dcp_idx;
141250 + cq_config.ccgid = cpu_to_be16(ccg->idx);
141251 + if (qman_ceetm_configure_cq(&cq_config)) {
141252 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
141253 + idx, ccg->idx);
141254 + list_del(&p->node);
141255 + kfree(p);
141256 + return -EINVAL;
141257 + }
141258 + }
141259 +
141260 + *cq = p;
141261 + return 0;
141262 +}
141263 +EXPORT_SYMBOL(qman_ceetm_cq_claim);
141264 +
141265 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
141266 + struct qm_ceetm_channel *channel, unsigned int idx,
141267 + struct qm_ceetm_ccg *ccg)
141268 +{
141269 + struct qm_ceetm_cq *p;
141270 + struct qm_mcc_ceetm_cq_config cq_config;
141271 +
141272 + if ((idx < 8) || (idx > 15)) {
141273 + pr_err("This grouped class queue id is out of range\n");
141274 + return -EINVAL;
141275 + }
141276 +
141277 + list_for_each_entry(p, &channel->class_queues, node) {
141278 + if (p->idx == idx) {
141279 + pr_err("The CQ#%d has been claimed!\n", idx);
141280 + return -EINVAL;
141281 + }
141282 + }
141283 +
141284 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141285 + if (!p) {
141286 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
141287 + return -ENOMEM;
141288 + }
141289 +
141290 + list_add_tail(&p->node, &channel->class_queues);
141291 + p->idx = idx;
141292 + p->is_claimed = 1;
141293 + p->parent = channel;
141294 + INIT_LIST_HEAD(&p->bound_lfqids);
141295 +
141296 + if (ccg) {
141297 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
141298 + cq_config.dcpid = channel->dcp_idx;
141299 + cq_config.ccgid = cpu_to_be16(ccg->idx);
141300 + if (qman_ceetm_configure_cq(&cq_config)) {
141301 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
141302 + idx, ccg->idx);
141303 + list_del(&p->node);
141304 + kfree(p);
141305 + return -EINVAL;
141306 + }
141307 + }
141308 + *cq = p;
141309 + return 0;
141310 +}
141311 +EXPORT_SYMBOL(qman_ceetm_cq_claim_A);
141312 +
141313 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
141314 + struct qm_ceetm_channel *channel, unsigned int idx,
141315 + struct qm_ceetm_ccg *ccg)
141316 +{
141317 + struct qm_ceetm_cq *p;
141318 + struct qm_mcc_ceetm_cq_config cq_config;
141319 +
141320 + if ((idx < 12) || (idx > 15)) {
141321 + pr_err("This grouped class queue id is out of range\n");
141322 + return -EINVAL;
141323 + }
141324 +
141325 + list_for_each_entry(p, &channel->class_queues, node) {
141326 + if (p->idx == idx) {
141327 + pr_err("The CQ#%d has been claimed!\n", idx);
141328 + return -EINVAL;
141329 + }
141330 + }
141331 +
141332 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141333 + if (!p) {
141334 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
141335 + return -ENOMEM;
141336 + }
141337 +
141338 + list_add_tail(&p->node, &channel->class_queues);
141339 + p->idx = idx;
141340 + p->is_claimed = 1;
141341 + p->parent = channel;
141342 + INIT_LIST_HEAD(&p->bound_lfqids);
141343 +
141344 + if (ccg) {
141345 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
141346 + cq_config.dcpid = channel->dcp_idx;
141347 + cq_config.ccgid = cpu_to_be16(ccg->idx);
141348 + if (qman_ceetm_configure_cq(&cq_config)) {
141349 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
141350 + idx, ccg->idx);
141351 + list_del(&p->node);
141352 + kfree(p);
141353 + return -EINVAL;
141354 + }
141355 + }
141356 + *cq = p;
141357 + return 0;
141358 +}
141359 +EXPORT_SYMBOL(qman_ceetm_cq_claim_B);
141360 +
141361 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq)
141362 +{
141363 + if (!list_empty(&cq->bound_lfqids)) {
141364 + pr_err("The CQ#%d has unreleased LFQID\n", cq->idx);
141365 + return -EBUSY;
141366 + }
141367 + list_del(&cq->node);
141368 + qman_ceetm_drain_cq(cq);
141369 + kfree(cq);
141370 + return 0;
141371 +}
141372 +EXPORT_SYMBOL(qman_ceetm_cq_release);
141373 +
141374 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
141375 + struct qm_ceetm_weight_code *weight_code)
141376 +{
141377 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
141378 + struct qm_mcr_ceetm_class_scheduler_query query_result;
141379 + int i;
141380 +
141381 + if (cq->idx < 8) {
141382 + pr_err("Can not set weight for ungrouped class queue\n");
141383 + return -EINVAL;
141384 + }
141385 +
141386 + if (qman_ceetm_query_class_scheduler(cq->parent, &query_result)) {
141387 + pr_err("Can't query channel#%d's scheduler!\n",
141388 + cq->parent->idx);
141389 + return -EINVAL;
141390 + }
141391 +
141392 + config_opts.cqcid = cpu_to_be16(cq->parent->idx);
141393 + config_opts.dcpid = cq->parent->dcp_idx;
141394 + config_opts.crem = query_result.crem;
141395 + config_opts.erem = query_result.erem;
141396 + config_opts.gpc_combine_flag = query_result.gpc_combine_flag;
141397 + config_opts.gpc_prio_a = query_result.gpc_prio_a;
141398 + config_opts.gpc_prio_b = query_result.gpc_prio_b;
141399 +
141400 + for (i = 0; i < 8; i++)
141401 + config_opts.w[i] = query_result.w[i];
141402 + config_opts.w[cq->idx - 8] = ((weight_code->y << 3) |
141403 + (weight_code->x & 0x7));
141404 + return qman_ceetm_configure_class_scheduler(&config_opts);
141405 +}
141406 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight);
141407 +
141408 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
141409 + struct qm_ceetm_weight_code *weight_code)
141410 +{
141411 + struct qm_mcr_ceetm_class_scheduler_query query_result;
141412 +
141413 + if (cq->idx < 8) {
141414 + pr_err("Can not get weight for ungrouped class queue\n");
141415 + return -EINVAL;
141416 + }
141417 +
141418 + if (qman_ceetm_query_class_scheduler(cq->parent,
141419 + &query_result)) {
141420 + pr_err("Can't get the weight code for CQ#%d!\n", cq->idx);
141421 + return -EINVAL;
141422 + }
141423 + weight_code->y = query_result.w[cq->idx - 8] >> 3;
141424 + weight_code->x = query_result.w[cq->idx - 8] & 0x7;
141425 +
141426 + return 0;
141427 +}
141428 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight);
141429 +
141430 +/* The WBFS code is represent as {x,y}, the effect wieght can be calculated as:
141431 + * effective weight = 2^x / (1 - (y/64))
141432 + * = 2^(x+6) / (64 - y)
141433 + */
141434 +static void reduce_fraction(u32 *n, u32 *d)
141435 +{
141436 + u32 factor = 2;
141437 + u32 lesser = (*n < *d) ? *n : *d;
141438 + /* If factor exceeds the square-root of the lesser of *n and *d,
141439 + * then there's no point continuing. Proof: if there was a factor
141440 + * bigger than the square root, that would imply there exists
141441 + * another factor smaller than the square-root with which it
141442 + * multiplies to give 'lesser' - but that's a contradiction
141443 + * because the other factor would have already been found and
141444 + * divided out.
141445 + */
141446 + while ((factor * factor) <= lesser) {
141447 + /* If 'factor' is a factor of *n and *d, divide them both
141448 + * by 'factor' as many times as possible.
141449 + */
141450 + while (!(*n % factor) && !(*d % factor)) {
141451 + *n /= factor;
141452 + *d /= factor;
141453 + lesser /= factor;
141454 + }
141455 + if (factor == 2)
141456 + factor = 3;
141457 + else
141458 + factor += 2;
141459 + }
141460 +}
141461 +
141462 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
141463 + u32 *numerator,
141464 + u32 *denominator)
141465 +{
141466 + *numerator = (u32) 1 << (weight_code->x + 6);
141467 + *denominator = 64 - weight_code->y;
141468 + reduce_fraction(numerator, denominator);
141469 + return 0;
141470 +}
141471 +EXPORT_SYMBOL(qman_ceetm_wbfs2ratio);
141472 +
141473 +/* For a given x, the weight is between 2^x (inclusive) and 2^(x+1) (exclusive).
141474 + * So find 'x' by range, and then estimate 'y' using:
141475 + * 64 - y = 2^(x + 6) / weight
141476 + * = 2^(x + 6) / (n/d)
141477 + * = d * 2^(x+6) / n
141478 + * y = 64 - (d * 2^(x+6) / n)
141479 + */
141480 +int qman_ceetm_ratio2wbfs(u32 numerator,
141481 + u32 denominator,
141482 + struct qm_ceetm_weight_code *weight_code,
141483 + int rounding)
141484 +{
141485 + unsigned int y, x = 0;
141486 + /* search incrementing 'x' until:
141487 + * weight < 2^(x+1)
141488 + * n/d < 2^(x+1)
141489 + * n < d * 2^(x+1)
141490 + */
141491 + while ((x < 8) && (numerator >= (denominator << (x + 1))))
141492 + x++;
141493 + if (x >= 8)
141494 + return -ERANGE;
141495 + /* because of the subtraction, use '-rounding' */
141496 + y = 64 - ROUNDING(denominator << (x + 6), numerator, -rounding);
141497 + if (y >= 32)
141498 + return -ERANGE;
141499 + weight_code->x = x;
141500 + weight_code->y = y;
141501 + return 0;
141502 +}
141503 +EXPORT_SYMBOL(qman_ceetm_ratio2wbfs);
141504 +
141505 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio)
141506 +{
141507 + struct qm_ceetm_weight_code weight_code;
141508 +
141509 + if (qman_ceetm_ratio2wbfs(ratio, 100, &weight_code, 0)) {
141510 + pr_err("Cannot get wbfs code for cq %x\n", cq->idx);
141511 + return -EINVAL;
141512 + }
141513 + return qman_ceetm_set_queue_weight(cq, &weight_code);
141514 +}
141515 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight_in_ratio);
141516 +
141517 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio)
141518 +{
141519 + struct qm_ceetm_weight_code weight_code;
141520 + u32 n, d;
141521 +
141522 + if (qman_ceetm_get_queue_weight(cq, &weight_code)) {
141523 + pr_err("Cannot query the weight code for cq%x\n", cq->idx);
141524 + return -EINVAL;
141525 + }
141526 +
141527 + if (qman_ceetm_wbfs2ratio(&weight_code, &n, &d)) {
141528 + pr_err("Cannot get the ratio with wbfs code\n");
141529 + return -EINVAL;
141530 + }
141531 +
141532 + *ratio = (n * 100) / d;
141533 + return 0;
141534 +}
141535 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight_in_ratio);
141536 +
141537 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
141538 + u64 *frame_count, u64 *byte_count)
141539 +{
141540 + struct qm_mcr_ceetm_statistics_query result;
141541 + u16 cid, command_type;
141542 + enum qm_dc_portal dcp_idx;
141543 + int ret;
141544 +
141545 + cid = cpu_to_be16((cq->parent->idx << 4) | cq->idx);
141546 + dcp_idx = cq->parent->dcp_idx;
141547 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
141548 + command_type = CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS;
141549 + else
141550 + command_type = CEETM_QUERY_DEQUEUE_STATISTICS;
141551 +
141552 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
141553 + if (ret) {
141554 + pr_err("Can't query the statistics of CQ#%d!\n", cq->idx);
141555 + return -EINVAL;
141556 + }
141557 +
141558 + *frame_count = be40_to_cpu(result.frm_cnt);
141559 + *byte_count = be48_to_cpu(result.byte_cnt);
141560 + return 0;
141561 +}
141562 +EXPORT_SYMBOL(qman_ceetm_cq_get_dequeue_statistics);
141563 +
141564 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq)
141565 +{
141566 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread ppxr;
141567 + int ret;
141568 +
141569 + do {
141570 + ret = qman_ceetm_cq_peek_pop_xsfdrread(cq, 1, 0, &ppxr);
141571 + if (ret) {
141572 + pr_err("Failed to pop frame from CQ\n");
141573 + return -EINVAL;
141574 + }
141575 + } while (!(ppxr.stat & 0x2));
141576 +
141577 + return 0;
141578 +}
141579 +EXPORT_SYMBOL(qman_ceetm_drain_cq);
141580 +
141581 +#define CEETM_LFQMT_LFQID_MSB 0xF00000
141582 +#define CEETM_LFQMT_LFQID_LSB 0x000FFF
141583 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
141584 + struct qm_ceetm_cq *cq)
141585 +{
141586 + struct qm_ceetm_lfq *p;
141587 + u32 lfqid;
141588 + int ret = 0;
141589 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
141590 +
141591 + if (cq->parent->dcp_idx == qm_dc_portal_fman0) {
141592 + ret = qman_alloc_ceetm0_lfqid(&lfqid);
141593 + } else if (cq->parent->dcp_idx == qm_dc_portal_fman1) {
141594 + ret = qman_alloc_ceetm1_lfqid(&lfqid);
141595 + } else {
141596 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141597 + cq->parent->dcp_idx);
141598 + return -EINVAL;
141599 + }
141600 +
141601 + if (ret) {
141602 + pr_err("There is no lfqid avalaible for CQ#%d!\n", cq->idx);
141603 + return -ENODEV;
141604 + }
141605 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141606 + if (!p)
141607 + return -ENOMEM;
141608 + p->idx = lfqid;
141609 + p->dctidx = (u16)(lfqid & CEETM_LFQMT_LFQID_LSB);
141610 + p->parent = cq->parent;
141611 + list_add_tail(&p->node, &cq->bound_lfqids);
141612 +
141613 + lfqmt_config.lfqid = cpu_to_be24(CEETM_LFQMT_LFQID_MSB |
141614 + (cq->parent->dcp_idx << 16) |
141615 + (lfqid & CEETM_LFQMT_LFQID_LSB));
141616 + lfqmt_config.cqid = cpu_to_be16((cq->parent->idx << 4) | (cq->idx));
141617 + lfqmt_config.dctidx = cpu_to_be16(p->dctidx);
141618 + if (qman_ceetm_configure_lfqmt(&lfqmt_config)) {
141619 + pr_err("Can't configure LFQMT for LFQID#%d @ CQ#%d\n",
141620 + lfqid, cq->idx);
141621 + list_del(&p->node);
141622 + kfree(p);
141623 + return -EINVAL;
141624 + }
141625 + *lfq = p;
141626 + return 0;
141627 +}
141628 +EXPORT_SYMBOL(qman_ceetm_lfq_claim);
141629 +
141630 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq)
141631 +{
141632 + if (lfq->parent->dcp_idx == qm_dc_portal_fman0) {
141633 + qman_release_ceetm0_lfqid(lfq->idx);
141634 + } else if (lfq->parent->dcp_idx == qm_dc_portal_fman1) {
141635 + qman_release_ceetm1_lfqid(lfq->idx);
141636 + } else {
141637 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141638 + lfq->parent->dcp_idx);
141639 + return -EINVAL;
141640 + }
141641 + list_del(&lfq->node);
141642 + kfree(lfq);
141643 + return 0;
141644 +}
141645 +EXPORT_SYMBOL(qman_ceetm_lfq_release);
141646 +
141647 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, u64 context_a,
141648 + u32 context_b)
141649 +{
141650 + struct qm_mcc_ceetm_dct_config dct_config;
141651 + lfq->context_a = context_a;
141652 + lfq->context_b = context_b;
141653 + dct_config.dctidx = cpu_to_be16((u16)lfq->dctidx);
141654 + dct_config.dcpid = lfq->parent->dcp_idx;
141655 + dct_config.context_b = cpu_to_be32(context_b);
141656 + dct_config.context_a = cpu_to_be64(context_a);
141657 +
141658 + return qman_ceetm_configure_dct(&dct_config);
141659 +}
141660 +EXPORT_SYMBOL(qman_ceetm_lfq_set_context);
141661 +
141662 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, u64 *context_a,
141663 + u32 *context_b)
141664 +{
141665 + struct qm_mcc_ceetm_dct_query dct_query;
141666 + struct qm_mcr_ceetm_dct_query query_result;
141667 +
141668 + dct_query.dctidx = cpu_to_be16(lfq->dctidx);
141669 + dct_query.dcpid = lfq->parent->dcp_idx;
141670 + if (qman_ceetm_query_dct(&dct_query, &query_result)) {
141671 + pr_err("Can't query LFQID#%d's context!\n", lfq->idx);
141672 + return -EINVAL;
141673 + }
141674 + *context_a = be64_to_cpu(query_result.context_a);
141675 + *context_b = be32_to_cpu(query_result.context_b);
141676 + return 0;
141677 +}
141678 +EXPORT_SYMBOL(qman_ceetm_lfq_get_context);
141679 +
141680 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq)
141681 +{
141682 + spin_lock_init(&fq->fqlock);
141683 + fq->fqid = lfq->idx;
141684 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
141685 + if (lfq->ern)
141686 + fq->cb.ern = lfq->ern;
141687 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
141688 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
141689 + return -ENOMEM;
141690 +#endif
141691 + return 0;
141692 +}
141693 +EXPORT_SYMBOL(qman_ceetm_create_fq);
141694 +
141695 +#define MAX_CCG_IDX 0x000F
141696 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
141697 + struct qm_ceetm_channel *channel,
141698 + unsigned int idx,
141699 + void (*cscn)(struct qm_ceetm_ccg *,
141700 + void *cb_ctx,
141701 + int congested),
141702 + void *cb_ctx)
141703 +{
141704 + struct qm_ceetm_ccg *p;
141705 +
141706 + if (idx > MAX_CCG_IDX) {
141707 + pr_err("The given ccg index is out of range\n");
141708 + return -EINVAL;
141709 + }
141710 +
141711 + list_for_each_entry(p, &channel->ccgs, node) {
141712 + if (p->idx == idx) {
141713 + pr_err("The CCG#%d has been claimed\n", idx);
141714 + return -EINVAL;
141715 + }
141716 + }
141717 +
141718 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141719 + if (!p) {
141720 + pr_err("Can't allocate memory for CCG#%d!\n", idx);
141721 + return -ENOMEM;
141722 + }
141723 +
141724 + list_add_tail(&p->node, &channel->ccgs);
141725 +
141726 + p->idx = idx;
141727 + p->parent = channel;
141728 + p->cb = cscn;
141729 + p->cb_ctx = cb_ctx;
141730 + INIT_LIST_HEAD(&p->cb_node);
141731 +
141732 + *ccg = p;
141733 + return 0;
141734 +}
141735 +EXPORT_SYMBOL(qman_ceetm_ccg_claim);
141736 +
141737 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg)
141738 +{
141739 + unsigned long irqflags __maybe_unused;
141740 + struct qm_mcc_ceetm_ccgr_config config_opts;
141741 + int ret = 0;
141742 + struct qman_portal *p = get_affine_portal();
141743 +
141744 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
141745 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
141746 + if (!list_empty(&ccg->cb_node))
141747 + list_del(&ccg->cb_node);
141748 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141749 + (ccg->parent->idx << 4) | ccg->idx);
141750 + config_opts.dcpid = ccg->parent->dcp_idx;
141751 + config_opts.we_mask = cpu_to_be16(QM_CCGR_WE_CSCN_TUPD);
141752 + config_opts.cm_config.cscn_tupd = cpu_to_be16(PORTAL_IDX(p));
141753 + ret = qman_ceetm_configure_ccgr(&config_opts);
141754 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
141755 + put_affine_portal();
141756 +
141757 + list_del(&ccg->node);
141758 + kfree(ccg);
141759 + return ret;
141760 +}
141761 +EXPORT_SYMBOL(qman_ceetm_ccg_release);
141762 +
141763 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, u16 we_mask,
141764 + const struct qm_ceetm_ccg_params *params)
141765 +{
141766 + struct qm_mcc_ceetm_ccgr_config config_opts;
141767 + unsigned long irqflags __maybe_unused;
141768 + int ret;
141769 + struct qman_portal *p;
141770 +
141771 + if (((ccg->parent->idx << 4) | ccg->idx) >= (2 * __CGR_NUM))
141772 + return -EINVAL;
141773 +
141774 + p = get_affine_portal();
141775 +
141776 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
141777 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
141778 +
141779 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141780 + (ccg->parent->idx << 4) | ccg->idx);
141781 + config_opts.dcpid = ccg->parent->dcp_idx;
141782 + config_opts.we_mask = we_mask;
141783 + if (we_mask & QM_CCGR_WE_CSCN_EN) {
141784 + config_opts.we_mask |= QM_CCGR_WE_CSCN_TUPD;
141785 + config_opts.cm_config.cscn_tupd = cpu_to_be16(
141786 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p));
141787 + }
141788 + config_opts.we_mask = cpu_to_be16(config_opts.we_mask);
141789 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141790 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141791 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141792 + config_opts.cm_config.ctl_td_en = params->td_en;
141793 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141794 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141795 + config_opts.cm_config.ctl_mode = params->mode;
141796 + config_opts.cm_config.oal = params->oal;
141797 + config_opts.cm_config.cs_thres.hword =
141798 + cpu_to_be16(params->cs_thres_in.hword);
141799 + config_opts.cm_config.cs_thres_x.hword =
141800 + cpu_to_be16(params->cs_thres_out.hword);
141801 + config_opts.cm_config.td_thres.hword =
141802 + cpu_to_be16(params->td_thres.hword);
141803 + config_opts.cm_config.wr_parm_g.word =
141804 + cpu_to_be32(params->wr_parm_g.word);
141805 + config_opts.cm_config.wr_parm_y.word =
141806 + cpu_to_be32(params->wr_parm_y.word);
141807 + config_opts.cm_config.wr_parm_r.word =
141808 + cpu_to_be32(params->wr_parm_r.word);
141809 + ret = qman_ceetm_configure_ccgr(&config_opts);
141810 + if (ret) {
141811 + pr_err("Configure CCGR CM failed!\n");
141812 + goto release_lock;
141813 + }
141814 +
141815 + if (we_mask & QM_CCGR_WE_CSCN_EN)
141816 + if (list_empty(&ccg->cb_node))
141817 + list_add(&ccg->cb_node,
141818 + &p->ccgr_cbs[ccg->parent->dcp_idx]);
141819 +release_lock:
141820 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
141821 + put_affine_portal();
141822 + return ret;
141823 +}
141824 +EXPORT_SYMBOL(qman_ceetm_ccg_set);
141825 +
141826 +#define CEETM_CCGR_CTL_MASK 0x01
141827 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
141828 + struct qm_ceetm_ccg_params *params)
141829 +{
141830 + struct qm_mcc_ceetm_ccgr_query query_opts;
141831 + struct qm_mcr_ceetm_ccgr_query query_result;
141832 +
141833 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141834 + (ccg->parent->idx << 4) | ccg->idx);
141835 + query_opts.dcpid = ccg->parent->dcp_idx;
141836 +
141837 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141838 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141839 + return -EINVAL;
141840 + }
141841 +
141842 + params->wr_parm_r.word = query_result.cm_query.wr_parm_r.word;
141843 + params->wr_parm_y.word = query_result.cm_query.wr_parm_y.word;
141844 + params->wr_parm_g.word = query_result.cm_query.wr_parm_g.word;
141845 + params->td_thres.hword = query_result.cm_query.td_thres.hword;
141846 + params->cs_thres_out.hword = query_result.cm_query.cs_thres_x.hword;
141847 + params->cs_thres_in.hword = query_result.cm_query.cs_thres.hword;
141848 + params->oal = query_result.cm_query.oal;
141849 + params->wr_en_g = query_result.cm_query.ctl_wr_en_g;
141850 + params->wr_en_y = query_result.cm_query.ctl_wr_en_y;
141851 + params->wr_en_r = query_result.cm_query.ctl_wr_en_r;
141852 + params->td_en = query_result.cm_query.ctl_td_en;
141853 + params->td_mode = query_result.cm_query.ctl_td_mode;
141854 + params->cscn_en = query_result.cm_query.ctl_cscn_en;
141855 + params->mode = query_result.cm_query.ctl_mode;
141856 +
141857 + return 0;
141858 +}
141859 +EXPORT_SYMBOL(qman_ceetm_ccg_get);
141860 +
141861 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
141862 + u64 *frame_count, u64 *byte_count)
141863 +{
141864 + struct qm_mcr_ceetm_statistics_query result;
141865 + u16 cid, command_type;
141866 + enum qm_dc_portal dcp_idx;
141867 + int ret;
141868 +
141869 + cid = cpu_to_be16((ccg->parent->idx << 4) | ccg->idx);
141870 + dcp_idx = ccg->parent->dcp_idx;
141871 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
141872 + command_type = CEETM_QUERY_REJECT_CLEAR_STATISTICS;
141873 + else
141874 + command_type = CEETM_QUERY_REJECT_STATISTICS;
141875 +
141876 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
141877 + if (ret) {
141878 + pr_err("Can't query the statistics of CCG#%d!\n", ccg->idx);
141879 + return -EINVAL;
141880 + }
141881 +
141882 + *frame_count = be40_to_cpu(result.frm_cnt);
141883 + *byte_count = be48_to_cpu(result.byte_cnt);
141884 + return 0;
141885 +}
141886 +EXPORT_SYMBOL(qman_ceetm_ccg_get_reject_statistics);
141887 +
141888 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
141889 + u16 swp_idx,
141890 + unsigned int *cscn_enabled)
141891 +{
141892 + struct qm_mcc_ceetm_ccgr_query query_opts;
141893 + struct qm_mcr_ceetm_ccgr_query query_result;
141894 + int i;
141895 +
141896 + DPA_ASSERT(swp_idx < 127);
141897 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141898 + (ccg->parent->idx << 4) | ccg->idx);
141899 + query_opts.dcpid = ccg->parent->dcp_idx;
141900 +
141901 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141902 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141903 + return -EINVAL;
141904 + }
141905 +
141906 + i = swp_idx / 32;
141907 + i = 3 - i;
141908 + *cscn_enabled = query_result.cm_query.cscn_targ_swp[i] >>
141909 + (31 - swp_idx % 32);
141910 +
141911 + return 0;
141912 +}
141913 +EXPORT_SYMBOL(qman_ceetm_cscn_swp_get);
141914 +
141915 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
141916 + u16 dcp_idx,
141917 + u8 vcgid,
141918 + unsigned int cscn_enabled,
141919 + u16 we_mask,
141920 + const struct qm_ceetm_ccg_params *params)
141921 +{
141922 + struct qm_mcc_ceetm_ccgr_config config_opts;
141923 + int ret;
141924 +
141925 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141926 + (ccg->parent->idx << 4) | ccg->idx);
141927 + config_opts.dcpid = ccg->parent->dcp_idx;
141928 + config_opts.we_mask = cpu_to_be16(we_mask | QM_CCGR_WE_CSCN_TUPD |
141929 + QM_CCGR_WE_CDV);
141930 + config_opts.cm_config.cdv = vcgid;
141931 + config_opts.cm_config.cscn_tupd = cpu_to_be16((cscn_enabled << 15) |
141932 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_idx);
141933 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141934 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141935 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141936 + config_opts.cm_config.ctl_td_en = params->td_en;
141937 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141938 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141939 + config_opts.cm_config.ctl_mode = params->mode;
141940 + config_opts.cm_config.cs_thres.hword =
141941 + cpu_to_be16(params->cs_thres_in.hword);
141942 + config_opts.cm_config.cs_thres_x.hword =
141943 + cpu_to_be16(params->cs_thres_out.hword);
141944 + config_opts.cm_config.td_thres.hword =
141945 + cpu_to_be16(params->td_thres.hword);
141946 + config_opts.cm_config.wr_parm_g.word =
141947 + cpu_to_be32(params->wr_parm_g.word);
141948 + config_opts.cm_config.wr_parm_y.word =
141949 + cpu_to_be32(params->wr_parm_y.word);
141950 + config_opts.cm_config.wr_parm_r.word =
141951 + cpu_to_be32(params->wr_parm_r.word);
141952 +
141953 + ret = qman_ceetm_configure_ccgr(&config_opts);
141954 + if (ret) {
141955 + pr_err("Configure CSCN_TARG_DCP failed!\n");
141956 + return -EINVAL;
141957 + }
141958 + return 0;
141959 +}
141960 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_set);
141961 +
141962 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
141963 + u16 dcp_idx,
141964 + u8 *vcgid,
141965 + unsigned int *cscn_enabled)
141966 +{
141967 + struct qm_mcc_ceetm_ccgr_query query_opts;
141968 + struct qm_mcr_ceetm_ccgr_query query_result;
141969 +
141970 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141971 + (ccg->parent->idx << 4) | ccg->idx);
141972 + query_opts.dcpid = ccg->parent->dcp_idx;
141973 +
141974 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141975 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141976 + return -EINVAL;
141977 + }
141978 +
141979 + *vcgid = query_result.cm_query.cdv;
141980 + *cscn_enabled = (query_result.cm_query.cscn_targ_dcp >> dcp_idx) & 0x1;
141981 + return 0;
141982 +}
141983 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_get);
141984 +
141985 +int qman_ceetm_querycongestion(struct __qm_mcr_querycongestion *ccg_state,
141986 + unsigned int dcp_idx)
141987 +{
141988 + struct qm_mc_command *mcc;
141989 + struct qm_mc_result *mcr;
141990 + struct qman_portal *p;
141991 + unsigned long irqflags __maybe_unused;
141992 + u8 res;
141993 + int i, j;
141994 +
141995 + p = get_affine_portal();
141996 + PORTAL_IRQ_LOCK(p, irqflags);
141997 +
141998 + mcc = qm_mc_start(&p->p);
141999 + for (i = 0; i < 2; i++) {
142000 + mcc->ccgr_query.ccgrid =
142001 + cpu_to_be16(CEETM_QUERY_CONGESTION_STATE | i);
142002 + mcc->ccgr_query.dcpid = dcp_idx;
142003 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
142004 +
142005 + while (!(mcr = qm_mc_result(&p->p)))
142006 + cpu_relax();
142007 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142008 + QM_CEETM_VERB_CCGR_QUERY);
142009 + res = mcr->result;
142010 + if (res == QM_MCR_RESULT_OK) {
142011 + for (j = 0; j < 8; j++)
142012 + mcr->ccgr_query.congestion_state.state.
142013 + __state[j] = be32_to_cpu(mcr->ccgr_query.
142014 + congestion_state.state.__state[j]);
142015 + *(ccg_state + i) =
142016 + mcr->ccgr_query.congestion_state.state;
142017 + } else {
142018 + pr_err("QUERY CEETM CONGESTION STATE failed\n");
142019 + PORTAL_IRQ_UNLOCK(p, irqflags);
142020 + return -EIO;
142021 + }
142022 + }
142023 + PORTAL_IRQ_UNLOCK(p, irqflags);
142024 + put_affine_portal();
142025 + return 0;
142026 +}
142027 +
142028 +int qman_set_wpm(int wpm_enable)
142029 +{
142030 + return qm_set_wpm(wpm_enable);
142031 +}
142032 +EXPORT_SYMBOL(qman_set_wpm);
142033 +
142034 +int qman_get_wpm(int *wpm_enable)
142035 +{
142036 + return qm_get_wpm(wpm_enable);
142037 +}
142038 +EXPORT_SYMBOL(qman_get_wpm);
142039 +
142040 +int qman_shutdown_fq(u32 fqid)
142041 +{
142042 + struct qman_portal *p;
142043 + unsigned long irqflags __maybe_unused;
142044 + int ret;
142045 + struct qm_portal *low_p;
142046 + p = get_affine_portal();
142047 + PORTAL_IRQ_LOCK(p, irqflags);
142048 + low_p = &p->p;
142049 + ret = qm_shutdown_fq(&low_p, 1, fqid);
142050 + PORTAL_IRQ_UNLOCK(p, irqflags);
142051 + put_affine_portal();
142052 + return ret;
142053 +}
142054 +
142055 +const struct qm_portal_config *qman_get_qm_portal_config(
142056 + struct qman_portal *portal)
142057 +{
142058 + return portal->sharing_redirect ? NULL : portal->config;
142059 +}
142060 diff --git a/drivers/staging/fsl_qbman/qman_low.h b/drivers/staging/fsl_qbman/qman_low.h
142061 new file mode 100644
142062 index 00000000..547b5fa2
142063 --- /dev/null
142064 +++ b/drivers/staging/fsl_qbman/qman_low.h
142065 @@ -0,0 +1,1427 @@
142066 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
142067 + *
142068 + * Redistribution and use in source and binary forms, with or without
142069 + * modification, are permitted provided that the following conditions are met:
142070 + * * Redistributions of source code must retain the above copyright
142071 + * notice, this list of conditions and the following disclaimer.
142072 + * * Redistributions in binary form must reproduce the above copyright
142073 + * notice, this list of conditions and the following disclaimer in the
142074 + * documentation and/or other materials provided with the distribution.
142075 + * * Neither the name of Freescale Semiconductor nor the
142076 + * names of its contributors may be used to endorse or promote products
142077 + * derived from this software without specific prior written permission.
142078 + *
142079 + *
142080 + * ALTERNATIVELY, this software may be distributed under the terms of the
142081 + * GNU General Public License ("GPL") as published by the Free Software
142082 + * Foundation, either version 2 of that License or (at your option) any
142083 + * later version.
142084 + *
142085 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
142086 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
142087 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
142088 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
142089 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
142090 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
142091 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
142092 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
142093 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
142094 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
142095 + */
142096 +
142097 +#include "qman_private.h"
142098 +
142099 +/***************************/
142100 +/* Portal register assists */
142101 +/***************************/
142102 +
142103 +/* Cache-inhibited register offsets */
142104 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142105 +
142106 +#define QM_REG_EQCR_PI_CINH 0x0000
142107 +#define QM_REG_EQCR_CI_CINH 0x0004
142108 +#define QM_REG_EQCR_ITR 0x0008
142109 +#define QM_REG_DQRR_PI_CINH 0x0040
142110 +#define QM_REG_DQRR_CI_CINH 0x0044
142111 +#define QM_REG_DQRR_ITR 0x0048
142112 +#define QM_REG_DQRR_DCAP 0x0050
142113 +#define QM_REG_DQRR_SDQCR 0x0054
142114 +#define QM_REG_DQRR_VDQCR 0x0058
142115 +#define QM_REG_DQRR_PDQCR 0x005c
142116 +#define QM_REG_MR_PI_CINH 0x0080
142117 +#define QM_REG_MR_CI_CINH 0x0084
142118 +#define QM_REG_MR_ITR 0x0088
142119 +#define QM_REG_CFG 0x0100
142120 +#define QM_REG_ISR 0x0e00
142121 +#define QM_REG_IIR 0x0e0c
142122 +#define QM_REG_ITPR 0x0e14
142123 +
142124 +/* Cache-enabled register offsets */
142125 +#define QM_CL_EQCR 0x0000
142126 +#define QM_CL_DQRR 0x1000
142127 +#define QM_CL_MR 0x2000
142128 +#define QM_CL_EQCR_PI_CENA 0x3000
142129 +#define QM_CL_EQCR_CI_CENA 0x3100
142130 +#define QM_CL_DQRR_PI_CENA 0x3200
142131 +#define QM_CL_DQRR_CI_CENA 0x3300
142132 +#define QM_CL_MR_PI_CENA 0x3400
142133 +#define QM_CL_MR_CI_CENA 0x3500
142134 +#define QM_CL_CR 0x3800
142135 +#define QM_CL_RR0 0x3900
142136 +#define QM_CL_RR1 0x3940
142137 +
142138 +#endif
142139 +
142140 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
142141 +
142142 +#define QM_REG_EQCR_PI_CINH 0x3000
142143 +#define QM_REG_EQCR_CI_CINH 0x3040
142144 +#define QM_REG_EQCR_ITR 0x3080
142145 +#define QM_REG_DQRR_PI_CINH 0x3100
142146 +#define QM_REG_DQRR_CI_CINH 0x3140
142147 +#define QM_REG_DQRR_ITR 0x3180
142148 +#define QM_REG_DQRR_DCAP 0x31C0
142149 +#define QM_REG_DQRR_SDQCR 0x3200
142150 +#define QM_REG_DQRR_VDQCR 0x3240
142151 +#define QM_REG_DQRR_PDQCR 0x3280
142152 +#define QM_REG_MR_PI_CINH 0x3300
142153 +#define QM_REG_MR_CI_CINH 0x3340
142154 +#define QM_REG_MR_ITR 0x3380
142155 +#define QM_REG_CFG 0x3500
142156 +#define QM_REG_ISR 0x3600
142157 +#define QM_REG_IIR 0x36C0
142158 +#define QM_REG_ITPR 0x3740
142159 +
142160 +/* Cache-enabled register offsets */
142161 +#define QM_CL_EQCR 0x0000
142162 +#define QM_CL_DQRR 0x1000
142163 +#define QM_CL_MR 0x2000
142164 +#define QM_CL_EQCR_PI_CENA 0x3000
142165 +#define QM_CL_EQCR_CI_CENA 0x3040
142166 +#define QM_CL_DQRR_PI_CENA 0x3100
142167 +#define QM_CL_DQRR_CI_CENA 0x3140
142168 +#define QM_CL_MR_PI_CENA 0x3300
142169 +#define QM_CL_MR_CI_CENA 0x3340
142170 +#define QM_CL_CR 0x3800
142171 +#define QM_CL_RR0 0x3900
142172 +#define QM_CL_RR1 0x3940
142173 +
142174 +#endif
142175 +
142176 +
142177 +/* BTW, the drivers (and h/w programming model) already obtain the required
142178 + * synchronisation for portal accesses via lwsync(), hwsync(), and
142179 + * data-dependencies. Use of barrier()s or other order-preserving primitives
142180 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
142181 + * simply ensure that the compiler treats the portal registers as volatile (ie.
142182 + * non-coherent). */
142183 +
142184 +/* Cache-inhibited register access. */
142185 +#define __qm_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ci + (o)))
142186 +#define __qm_out(qm, o, val) __raw_writel((cpu_to_be32(val)), \
142187 + (qm)->addr_ci + (o));
142188 +#define qm_in(reg) __qm_in(&portal->addr, QM_REG_##reg)
142189 +#define qm_out(reg, val) __qm_out(&portal->addr, QM_REG_##reg, val)
142190 +
142191 +/* Cache-enabled (index) register access */
142192 +#define __qm_cl_touch_ro(qm, o) dcbt_ro((qm)->addr_ce + (o))
142193 +#define __qm_cl_touch_rw(qm, o) dcbt_rw((qm)->addr_ce + (o))
142194 +#define __qm_cl_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ce + (o)))
142195 +#define __qm_cl_out(qm, o, val) \
142196 + do { \
142197 + u32 *__tmpclout = (qm)->addr_ce + (o); \
142198 + __raw_writel(cpu_to_be32(val), __tmpclout); \
142199 + dcbf(__tmpclout); \
142200 + } while (0)
142201 +#define __qm_cl_invalidate(qm, o) dcbi((qm)->addr_ce + (o))
142202 +#define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, QM_CL_##reg##_CENA)
142203 +#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, QM_CL_##reg##_CENA)
142204 +#define qm_cl_in(reg) __qm_cl_in(&portal->addr, QM_CL_##reg##_CENA)
142205 +#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, QM_CL_##reg##_CENA, val)
142206 +#define qm_cl_invalidate(reg)\
142207 + __qm_cl_invalidate(&portal->addr, QM_CL_##reg##_CENA)
142208 +
142209 +/* Cache-enabled ring access */
142210 +#define qm_cl(base, idx) ((void *)base + ((idx) << 6))
142211 +
142212 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
142213 + * analysis, look at using the "extra" bit in the ring index registers to avoid
142214 + * cyclic issues. */
142215 +static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
142216 +{
142217 + /* 'first' is included, 'last' is excluded */
142218 + if (first <= last)
142219 + return last - first;
142220 + return ringsize + last - first;
142221 +}
142222 +
142223 +/* Portal modes.
142224 + * Enum types;
142225 + * pmode == production mode
142226 + * cmode == consumption mode,
142227 + * dmode == h/w dequeue mode.
142228 + * Enum values use 3 letter codes. First letter matches the portal mode,
142229 + * remaining two letters indicate;
142230 + * ci == cache-inhibited portal register
142231 + * ce == cache-enabled portal register
142232 + * vb == in-band valid-bit (cache-enabled)
142233 + * dc == DCA (Discrete Consumption Acknowledgement), DQRR-only
142234 + * As for "enum qm_dqrr_dmode", it should be self-explanatory.
142235 + */
142236 +enum qm_eqcr_pmode { /* matches QCSP_CFG::EPM */
142237 + qm_eqcr_pci = 0, /* PI index, cache-inhibited */
142238 + qm_eqcr_pce = 1, /* PI index, cache-enabled */
142239 + qm_eqcr_pvb = 2 /* valid-bit */
142240 +};
142241 +enum qm_dqrr_dmode { /* matches QCSP_CFG::DP */
142242 + qm_dqrr_dpush = 0, /* SDQCR + VDQCR */
142243 + qm_dqrr_dpull = 1 /* PDQCR */
142244 +};
142245 +enum qm_dqrr_pmode { /* s/w-only */
142246 + qm_dqrr_pci, /* reads DQRR_PI_CINH */
142247 + qm_dqrr_pce, /* reads DQRR_PI_CENA */
142248 + qm_dqrr_pvb /* reads valid-bit */
142249 +};
142250 +enum qm_dqrr_cmode { /* matches QCSP_CFG::DCM */
142251 + qm_dqrr_cci = 0, /* CI index, cache-inhibited */
142252 + qm_dqrr_cce = 1, /* CI index, cache-enabled */
142253 + qm_dqrr_cdc = 2 /* Discrete Consumption Acknowledgement */
142254 +};
142255 +enum qm_mr_pmode { /* s/w-only */
142256 + qm_mr_pci, /* reads MR_PI_CINH */
142257 + qm_mr_pce, /* reads MR_PI_CENA */
142258 + qm_mr_pvb /* reads valid-bit */
142259 +};
142260 +enum qm_mr_cmode { /* matches QCSP_CFG::MM */
142261 + qm_mr_cci = 0, /* CI index, cache-inhibited */
142262 + qm_mr_cce = 1 /* CI index, cache-enabled */
142263 +};
142264 +
142265 +
142266 +/* ------------------------- */
142267 +/* --- Portal structures --- */
142268 +
142269 +#define QM_EQCR_SIZE 8
142270 +#define QM_DQRR_SIZE 16
142271 +#define QM_MR_SIZE 8
142272 +
142273 +struct qm_eqcr {
142274 + struct qm_eqcr_entry *ring, *cursor;
142275 + u8 ci, available, ithresh, vbit;
142276 +#ifdef CONFIG_FSL_DPA_CHECKING
142277 + u32 busy;
142278 + enum qm_eqcr_pmode pmode;
142279 +#endif
142280 +};
142281 +
142282 +struct qm_dqrr {
142283 + const struct qm_dqrr_entry *ring, *cursor;
142284 + u8 pi, ci, fill, ithresh, vbit;
142285 +#ifdef CONFIG_FSL_DPA_CHECKING
142286 + enum qm_dqrr_dmode dmode;
142287 + enum qm_dqrr_pmode pmode;
142288 + enum qm_dqrr_cmode cmode;
142289 +#endif
142290 +};
142291 +
142292 +struct qm_mr {
142293 + const struct qm_mr_entry *ring, *cursor;
142294 + u8 pi, ci, fill, ithresh, vbit;
142295 +#ifdef CONFIG_FSL_DPA_CHECKING
142296 + enum qm_mr_pmode pmode;
142297 + enum qm_mr_cmode cmode;
142298 +#endif
142299 +};
142300 +
142301 +struct qm_mc {
142302 + struct qm_mc_command *cr;
142303 + struct qm_mc_result *rr;
142304 + u8 rridx, vbit;
142305 +#ifdef CONFIG_FSL_DPA_CHECKING
142306 + enum {
142307 + /* Can be _mc_start()ed */
142308 + qman_mc_idle,
142309 + /* Can be _mc_commit()ed or _mc_abort()ed */
142310 + qman_mc_user,
142311 + /* Can only be _mc_retry()ed */
142312 + qman_mc_hw
142313 + } state;
142314 +#endif
142315 +};
142316 +
142317 +#define QM_PORTAL_ALIGNMENT ____cacheline_aligned
142318 +
142319 +struct qm_addr {
142320 + void __iomem *addr_ce; /* cache-enabled */
142321 + void __iomem *addr_ci; /* cache-inhibited */
142322 +};
142323 +
142324 +struct qm_portal {
142325 + /* In the non-CONFIG_FSL_DPA_CHECKING case, the following stuff up to
142326 + * and including 'mc' fits within a cacheline (yay!). The 'config' part
142327 + * is setup-only, so isn't a cause for a concern. In other words, don't
142328 + * rearrange this structure on a whim, there be dragons ... */
142329 + struct qm_addr addr;
142330 + struct qm_eqcr eqcr;
142331 + struct qm_dqrr dqrr;
142332 + struct qm_mr mr;
142333 + struct qm_mc mc;
142334 +} QM_PORTAL_ALIGNMENT;
142335 +
142336 +
142337 +/* ---------------- */
142338 +/* --- EQCR API --- */
142339 +
142340 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
142341 +#define EQCR_CARRYCLEAR(p) \
142342 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_EQCR_SIZE << 6)))
142343 +
142344 +/* Bit-wise logic to convert a ring pointer to a ring index */
142345 +static inline u8 EQCR_PTR2IDX(struct qm_eqcr_entry *e)
142346 +{
142347 + return ((uintptr_t)e >> 6) & (QM_EQCR_SIZE - 1);
142348 +}
142349 +
142350 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
142351 +static inline void EQCR_INC(struct qm_eqcr *eqcr)
142352 +{
142353 + /* NB: this is odd-looking, but experiments show that it generates fast
142354 + * code with essentially no branching overheads. We increment to the
142355 + * next EQCR pointer and handle overflow and 'vbit'. */
142356 + struct qm_eqcr_entry *partial = eqcr->cursor + 1;
142357 + eqcr->cursor = EQCR_CARRYCLEAR(partial);
142358 + if (partial != eqcr->cursor)
142359 + eqcr->vbit ^= QM_EQCR_VERB_VBIT;
142360 +}
142361 +
142362 +static inline int qm_eqcr_init(struct qm_portal *portal,
142363 + enum qm_eqcr_pmode pmode,
142364 + unsigned int eq_stash_thresh,
142365 + int eq_stash_prio)
142366 +{
142367 + /* This use of 'register', as well as all other occurrences, is because
142368 + * it has been observed to generate much faster code with gcc than is
142369 + * otherwise the case. */
142370 + register struct qm_eqcr *eqcr = &portal->eqcr;
142371 + u32 cfg;
142372 + u8 pi;
142373 +
142374 + eqcr->ring = portal->addr.addr_ce + QM_CL_EQCR;
142375 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
142376 + qm_cl_invalidate(EQCR_CI);
142377 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
142378 + eqcr->cursor = eqcr->ring + pi;
142379 + eqcr->vbit = (qm_in(EQCR_PI_CINH) & QM_EQCR_SIZE) ?
142380 + QM_EQCR_VERB_VBIT : 0;
142381 + eqcr->available = QM_EQCR_SIZE - 1 -
142382 + qm_cyc_diff(QM_EQCR_SIZE, eqcr->ci, pi);
142383 + eqcr->ithresh = qm_in(EQCR_ITR);
142384 +#ifdef CONFIG_FSL_DPA_CHECKING
142385 + eqcr->busy = 0;
142386 + eqcr->pmode = pmode;
142387 +#endif
142388 + cfg = (qm_in(CFG) & 0x00ffffff) |
142389 + (eq_stash_thresh << 28) | /* QCSP_CFG: EST */
142390 + (eq_stash_prio << 26) | /* QCSP_CFG: EP */
142391 + ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */
142392 + qm_out(CFG, cfg);
142393 + return 0;
142394 +}
142395 +
142396 +static inline unsigned int qm_eqcr_get_ci_stashing(struct qm_portal *portal)
142397 +{
142398 + return (qm_in(CFG) >> 28) & 0x7;
142399 +}
142400 +
142401 +static inline void qm_eqcr_finish(struct qm_portal *portal)
142402 +{
142403 + register struct qm_eqcr *eqcr = &portal->eqcr;
142404 + u8 pi, ci;
142405 + u32 cfg;
142406 +
142407 + /*
142408 + * Disable EQCI stashing because the QMan only
142409 + * presents the value it previously stashed to
142410 + * maintain coherency. Setting the stash threshold
142411 + * to 1 then 0 ensures that QMan has resyncronized
142412 + * its internal copy so that the portal is clean
142413 + * when it is reinitialized in the future
142414 + */
142415 + cfg = (qm_in(CFG) & 0x0fffffff) |
142416 + (1 << 28); /* QCSP_CFG: EST */
142417 + qm_out(CFG, cfg);
142418 + cfg &= 0x0fffffff; /* stash threshold = 0 */
142419 + qm_out(CFG, cfg);
142420 +
142421 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
142422 + ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
142423 +
142424 + /* Refresh EQCR CI cache value */
142425 + qm_cl_invalidate(EQCR_CI);
142426 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
142427 +
142428 + DPA_ASSERT(!eqcr->busy);
142429 + if (pi != EQCR_PTR2IDX(eqcr->cursor))
142430 + pr_crit("losing uncommited EQCR entries\n");
142431 + if (ci != eqcr->ci)
142432 + pr_crit("missing existing EQCR completions\n");
142433 + if (eqcr->ci != EQCR_PTR2IDX(eqcr->cursor))
142434 + pr_crit("EQCR destroyed unquiesced\n");
142435 +}
142436 +
142437 +static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal
142438 + *portal)
142439 +{
142440 + register struct qm_eqcr *eqcr = &portal->eqcr;
142441 + DPA_ASSERT(!eqcr->busy);
142442 + if (!eqcr->available)
142443 + return NULL;
142444 +
142445 +
142446 +#ifdef CONFIG_FSL_DPA_CHECKING
142447 + eqcr->busy = 1;
142448 +#endif
142449 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142450 + dcbz_64(eqcr->cursor);
142451 +#endif
142452 + return eqcr->cursor;
142453 +}
142454 +
142455 +static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal
142456 + *portal)
142457 +{
142458 + register struct qm_eqcr *eqcr = &portal->eqcr;
142459 + u8 diff, old_ci;
142460 +
142461 + DPA_ASSERT(!eqcr->busy);
142462 + if (!eqcr->available) {
142463 + old_ci = eqcr->ci;
142464 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
142465 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
142466 + eqcr->available += diff;
142467 + if (!diff)
142468 + return NULL;
142469 + }
142470 +#ifdef CONFIG_FSL_DPA_CHECKING
142471 + eqcr->busy = 1;
142472 +#endif
142473 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142474 + dcbz_64(eqcr->cursor);
142475 +#endif
142476 + return eqcr->cursor;
142477 +}
142478 +
142479 +static inline void qm_eqcr_abort(struct qm_portal *portal)
142480 +{
142481 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
142482 + DPA_ASSERT(eqcr->busy);
142483 +#ifdef CONFIG_FSL_DPA_CHECKING
142484 + eqcr->busy = 0;
142485 +#endif
142486 +}
142487 +
142488 +static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next(
142489 + struct qm_portal *portal, u8 myverb)
142490 +{
142491 + register struct qm_eqcr *eqcr = &portal->eqcr;
142492 + DPA_ASSERT(eqcr->busy);
142493 + DPA_ASSERT(eqcr->pmode != qm_eqcr_pvb);
142494 + if (eqcr->available == 1)
142495 + return NULL;
142496 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142497 + dcbf(eqcr->cursor);
142498 + EQCR_INC(eqcr);
142499 + eqcr->available--;
142500 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142501 + dcbz_64(eqcr->cursor);
142502 +#endif
142503 + return eqcr->cursor;
142504 +}
142505 +
142506 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
142507 +#define EQCR_COMMIT_CHECKS(eqcr) \
142508 +do { \
142509 + DPA_ASSERT(eqcr->busy); \
142510 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0xffffff00)); \
142511 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0xffffff00)); \
142512 +} while (0)
142513 +#else
142514 +#define EQCR_COMMIT_CHECKS(eqcr) \
142515 +do { \
142516 + DPA_ASSERT(eqcr->busy); \
142517 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & \
142518 + cpu_to_be32(0x00ffffff))); \
142519 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & \
142520 + cpu_to_be32(0x00ffffff))); \
142521 +} while (0)
142522 +#endif
142523 +
142524 +static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb)
142525 +{
142526 + register struct qm_eqcr *eqcr = &portal->eqcr;
142527 + EQCR_COMMIT_CHECKS(eqcr);
142528 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pci);
142529 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142530 + EQCR_INC(eqcr);
142531 + eqcr->available--;
142532 + dcbf(eqcr->cursor);
142533 + hwsync();
142534 + qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor));
142535 +#ifdef CONFIG_FSL_DPA_CHECKING
142536 + eqcr->busy = 0;
142537 +#endif
142538 +}
142539 +
142540 +static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal)
142541 +{
142542 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
142543 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
142544 + qm_cl_invalidate(EQCR_PI);
142545 + qm_cl_touch_rw(EQCR_PI);
142546 +}
142547 +
142548 +static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb)
142549 +{
142550 + register struct qm_eqcr *eqcr = &portal->eqcr;
142551 + EQCR_COMMIT_CHECKS(eqcr);
142552 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
142553 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142554 + EQCR_INC(eqcr);
142555 + eqcr->available--;
142556 + dcbf(eqcr->cursor);
142557 + lwsync();
142558 + qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor));
142559 +#ifdef CONFIG_FSL_DPA_CHECKING
142560 + eqcr->busy = 0;
142561 +#endif
142562 +}
142563 +
142564 +static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb)
142565 +{
142566 + register struct qm_eqcr *eqcr = &portal->eqcr;
142567 + struct qm_eqcr_entry *eqcursor;
142568 + EQCR_COMMIT_CHECKS(eqcr);
142569 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pvb);
142570 + lwsync();
142571 + eqcursor = eqcr->cursor;
142572 + eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142573 + dcbf(eqcursor);
142574 + EQCR_INC(eqcr);
142575 + eqcr->available--;
142576 +#ifdef CONFIG_FSL_DPA_CHECKING
142577 + eqcr->busy = 0;
142578 +#endif
142579 +}
142580 +
142581 +static inline u8 qm_eqcr_cci_update(struct qm_portal *portal)
142582 +{
142583 + register struct qm_eqcr *eqcr = &portal->eqcr;
142584 + u8 diff, old_ci = eqcr->ci;
142585 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
142586 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
142587 + eqcr->available += diff;
142588 + return diff;
142589 +}
142590 +
142591 +static inline void qm_eqcr_cce_prefetch(struct qm_portal *portal)
142592 +{
142593 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
142594 + qm_cl_touch_ro(EQCR_CI);
142595 +}
142596 +
142597 +static inline u8 qm_eqcr_cce_update(struct qm_portal *portal)
142598 +{
142599 + register struct qm_eqcr *eqcr = &portal->eqcr;
142600 + u8 diff, old_ci = eqcr->ci;
142601 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
142602 + qm_cl_invalidate(EQCR_CI);
142603 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
142604 + eqcr->available += diff;
142605 + return diff;
142606 +}
142607 +
142608 +static inline u8 qm_eqcr_get_ithresh(struct qm_portal *portal)
142609 +{
142610 + register struct qm_eqcr *eqcr = &portal->eqcr;
142611 + return eqcr->ithresh;
142612 +}
142613 +
142614 +static inline void qm_eqcr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142615 +{
142616 + register struct qm_eqcr *eqcr = &portal->eqcr;
142617 + eqcr->ithresh = ithresh;
142618 + qm_out(EQCR_ITR, ithresh);
142619 +}
142620 +
142621 +static inline u8 qm_eqcr_get_avail(struct qm_portal *portal)
142622 +{
142623 + register struct qm_eqcr *eqcr = &portal->eqcr;
142624 + return eqcr->available;
142625 +}
142626 +
142627 +static inline u8 qm_eqcr_get_fill(struct qm_portal *portal)
142628 +{
142629 + register struct qm_eqcr *eqcr = &portal->eqcr;
142630 + return QM_EQCR_SIZE - 1 - eqcr->available;
142631 +}
142632 +
142633 +
142634 +/* ---------------- */
142635 +/* --- DQRR API --- */
142636 +
142637 +/* FIXME: many possible improvements;
142638 + * - look at changing the API to use pointer rather than index parameters now
142639 + * that 'cursor' is a pointer,
142640 + * - consider moving other parameters to pointer if it could help (ci)
142641 + */
142642 +
142643 +#define DQRR_CARRYCLEAR(p) \
142644 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_DQRR_SIZE << 6)))
142645 +
142646 +static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e)
142647 +{
142648 + return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1);
142649 +}
142650 +
142651 +static inline const struct qm_dqrr_entry *DQRR_INC(
142652 + const struct qm_dqrr_entry *e)
142653 +{
142654 + return DQRR_CARRYCLEAR(e + 1);
142655 +}
142656 +
142657 +static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf)
142658 +{
142659 + qm_out(CFG, (qm_in(CFG) & 0xff0fffff) |
142660 + ((mf & (QM_DQRR_SIZE - 1)) << 20));
142661 +}
142662 +
142663 +static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num)
142664 +{
142665 + register struct qm_dqrr *dqrr = &portal->dqrr;
142666 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
142667 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
142668 + qm_out(DQRR_CI_CINH, dqrr->ci);
142669 +}
142670 +
142671 +static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num)
142672 +{
142673 + register struct qm_dqrr *dqrr = &portal->dqrr;
142674 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142675 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
142676 + qm_cl_out(DQRR_CI, dqrr->ci);
142677 +}
142678 +
142679 +static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
142680 +{
142681 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142682 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142683 + qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
142684 + ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
142685 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142686 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
142687 +}
142688 +
142689 +static inline int qm_dqrr_init(struct qm_portal *portal,
142690 + const struct qm_portal_config *config,
142691 + enum qm_dqrr_dmode dmode,
142692 + __maybe_unused enum qm_dqrr_pmode pmode,
142693 + enum qm_dqrr_cmode cmode, u8 max_fill)
142694 +{
142695 + register struct qm_dqrr *dqrr = &portal->dqrr;
142696 + u32 cfg;
142697 +
142698 + /* Make sure the DQRR will be idle when we enable */
142699 + qm_out(DQRR_SDQCR, 0);
142700 + qm_out(DQRR_VDQCR, 0);
142701 + qm_out(DQRR_PDQCR, 0);
142702 + dqrr->ring = portal->addr.addr_ce + QM_CL_DQRR;
142703 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
142704 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142705 + dqrr->cursor = dqrr->ring + dqrr->ci;
142706 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
142707 + dqrr->vbit = (qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ?
142708 + QM_DQRR_VERB_VBIT : 0;
142709 + dqrr->ithresh = qm_in(DQRR_ITR);
142710 +
142711 + /* Free up pending DQRR entries if any as per current DCM */
142712 + if (dqrr->fill) {
142713 + enum qm_dqrr_cmode dcm = (qm_in(CFG) >> 16) & 3;
142714 +
142715 +#ifdef CONFIG_FSL_DPA_CHECKING
142716 + dqrr->cmode = dcm;
142717 +#endif
142718 + switch (dcm) {
142719 + case qm_dqrr_cci:
142720 + qm_dqrr_cci_consume(portal, dqrr->fill);
142721 + break;
142722 + case qm_dqrr_cce:
142723 + qm_dqrr_cce_consume(portal, dqrr->fill);
142724 + break;
142725 + case qm_dqrr_cdc:
142726 + qm_dqrr_cdc_consume_n(portal, (QM_DQRR_SIZE - 1));
142727 + break;
142728 + default:
142729 + DPA_ASSERT(0);
142730 + }
142731 + }
142732 +
142733 +#ifdef CONFIG_FSL_DPA_CHECKING
142734 + dqrr->dmode = dmode;
142735 + dqrr->pmode = pmode;
142736 + dqrr->cmode = cmode;
142737 +#endif
142738 + /* Invalidate every ring entry before beginning */
142739 + for (cfg = 0; cfg < QM_DQRR_SIZE; cfg++)
142740 + dcbi(qm_cl(dqrr->ring, cfg));
142741 + cfg = (qm_in(CFG) & 0xff000f00) |
142742 + ((max_fill & (QM_DQRR_SIZE - 1)) << 20) | /* DQRR_MF */
142743 + ((dmode & 1) << 18) | /* DP */
142744 + ((cmode & 3) << 16) | /* DCM */
142745 + 0xa0 | /* RE+SE */
142746 + (0 ? 0x40 : 0) | /* Ignore RP */
142747 + (0 ? 0x10 : 0); /* Ignore SP */
142748 + qm_out(CFG, cfg);
142749 + qm_dqrr_set_maxfill(portal, max_fill);
142750 + return 0;
142751 +}
142752 +
142753 +static inline void qm_dqrr_finish(struct qm_portal *portal)
142754 +{
142755 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142756 +#ifdef CONFIG_FSL_DPA_CHECKING
142757 + if ((dqrr->cmode != qm_dqrr_cdc) &&
142758 + (dqrr->ci != DQRR_PTR2IDX(dqrr->cursor)))
142759 + pr_crit("Ignoring completed DQRR entries\n");
142760 +#endif
142761 +}
142762 +
142763 +static inline const struct qm_dqrr_entry *qm_dqrr_current(
142764 + struct qm_portal *portal)
142765 +{
142766 + register struct qm_dqrr *dqrr = &portal->dqrr;
142767 + if (!dqrr->fill)
142768 + return NULL;
142769 + return dqrr->cursor;
142770 +}
142771 +
142772 +static inline u8 qm_dqrr_cursor(struct qm_portal *portal)
142773 +{
142774 + register struct qm_dqrr *dqrr = &portal->dqrr;
142775 + return DQRR_PTR2IDX(dqrr->cursor);
142776 +}
142777 +
142778 +static inline u8 qm_dqrr_next(struct qm_portal *portal)
142779 +{
142780 + register struct qm_dqrr *dqrr = &portal->dqrr;
142781 + DPA_ASSERT(dqrr->fill);
142782 + dqrr->cursor = DQRR_INC(dqrr->cursor);
142783 + return --dqrr->fill;
142784 +}
142785 +
142786 +static inline u8 qm_dqrr_pci_update(struct qm_portal *portal)
142787 +{
142788 + register struct qm_dqrr *dqrr = &portal->dqrr;
142789 + u8 diff, old_pi = dqrr->pi;
142790 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pci);
142791 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
142792 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
142793 + dqrr->fill += diff;
142794 + return diff;
142795 +}
142796 +
142797 +static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal)
142798 +{
142799 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142800 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
142801 + qm_cl_invalidate(DQRR_PI);
142802 + qm_cl_touch_ro(DQRR_PI);
142803 +}
142804 +
142805 +static inline u8 qm_dqrr_pce_update(struct qm_portal *portal)
142806 +{
142807 + register struct qm_dqrr *dqrr = &portal->dqrr;
142808 + u8 diff, old_pi = dqrr->pi;
142809 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
142810 + dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1);
142811 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
142812 + dqrr->fill += diff;
142813 + return diff;
142814 +}
142815 +
142816 +static inline void qm_dqrr_pvb_update(struct qm_portal *portal)
142817 +{
142818 + register struct qm_dqrr *dqrr = &portal->dqrr;
142819 + const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi);
142820 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pvb);
142821 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && !defined CONFIG_FSL_PAMU
142822 + /*
142823 + * On PowerPC platforms if PAMU is not available we need to
142824 + * manually invalidate the cache. When PAMU is available the
142825 + * cache is updated by stashing operations generated by QMan
142826 + */
142827 + dcbi(res);
142828 + dcbt_ro(res);
142829 +#endif
142830 +
142831 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
142832 + * inlining doesn't try to optimise out "excess reads". */
142833 + if ((__raw_readb(&res->verb) & QM_DQRR_VERB_VBIT) == dqrr->vbit) {
142834 + dqrr->pi = (dqrr->pi + 1) & (QM_DQRR_SIZE - 1);
142835 + if (!dqrr->pi)
142836 + dqrr->vbit ^= QM_DQRR_VERB_VBIT;
142837 + dqrr->fill++;
142838 + }
142839 +}
142840 +
142841 +
142842 +static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal)
142843 +{
142844 + register struct qm_dqrr *dqrr = &portal->dqrr;
142845 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
142846 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
142847 + qm_out(DQRR_CI_CINH, dqrr->ci);
142848 +}
142849 +
142850 +static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal)
142851 +{
142852 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142853 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142854 + qm_cl_invalidate(DQRR_CI);
142855 + qm_cl_touch_rw(DQRR_CI);
142856 +}
142857 +
142858 +static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal)
142859 +{
142860 + register struct qm_dqrr *dqrr = &portal->dqrr;
142861 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142862 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
142863 + qm_cl_out(DQRR_CI, dqrr->ci);
142864 +}
142865 +
142866 +static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx,
142867 + int park)
142868 +{
142869 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142870 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142871 + DPA_ASSERT(idx < QM_DQRR_SIZE);
142872 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142873 + ((park ? 1 : 0) << 6) | /* PK */
142874 + idx); /* DCAP_CI */
142875 +}
142876 +
142877 +static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal,
142878 + const struct qm_dqrr_entry *dq,
142879 + int park)
142880 +{
142881 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142882 + u8 idx = DQRR_PTR2IDX(dq);
142883 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142884 + DPA_ASSERT((dqrr->ring + idx) == dq);
142885 + DPA_ASSERT(idx < QM_DQRR_SIZE);
142886 + qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */
142887 + ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */
142888 + idx); /* DQRR_DCAP::DCAP_CI */
142889 +}
142890 +
142891 +static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal)
142892 +{
142893 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142894 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142895 + return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142896 +}
142897 +
142898 +static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal)
142899 +{
142900 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142901 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142902 + qm_cl_invalidate(DQRR_CI);
142903 + qm_cl_touch_ro(DQRR_CI);
142904 +}
142905 +
142906 +static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal)
142907 +{
142908 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142909 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142910 + return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1);
142911 +}
142912 +
142913 +static inline u8 qm_dqrr_get_ci(struct qm_portal *portal)
142914 +{
142915 + register struct qm_dqrr *dqrr = &portal->dqrr;
142916 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142917 + return dqrr->ci;
142918 +}
142919 +
142920 +static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx)
142921 +{
142922 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142923 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142924 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142925 + (1 << 6) | /* PK */
142926 + (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */
142927 +}
142928 +
142929 +static inline void qm_dqrr_park_current(struct qm_portal *portal)
142930 +{
142931 + register struct qm_dqrr *dqrr = &portal->dqrr;
142932 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142933 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142934 + (1 << 6) | /* PK */
142935 + DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */
142936 +}
142937 +
142938 +static inline void qm_dqrr_sdqcr_set(struct qm_portal *portal, u32 sdqcr)
142939 +{
142940 + qm_out(DQRR_SDQCR, sdqcr);
142941 +}
142942 +
142943 +static inline u32 qm_dqrr_sdqcr_get(struct qm_portal *portal)
142944 +{
142945 + return qm_in(DQRR_SDQCR);
142946 +}
142947 +
142948 +static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
142949 +{
142950 + qm_out(DQRR_VDQCR, vdqcr);
142951 +}
142952 +
142953 +static inline u32 qm_dqrr_vdqcr_get(struct qm_portal *portal)
142954 +{
142955 + return qm_in(DQRR_VDQCR);
142956 +}
142957 +
142958 +static inline void qm_dqrr_pdqcr_set(struct qm_portal *portal, u32 pdqcr)
142959 +{
142960 + qm_out(DQRR_PDQCR, pdqcr);
142961 +}
142962 +
142963 +static inline u32 qm_dqrr_pdqcr_get(struct qm_portal *portal)
142964 +{
142965 + return qm_in(DQRR_PDQCR);
142966 +}
142967 +
142968 +static inline u8 qm_dqrr_get_ithresh(struct qm_portal *portal)
142969 +{
142970 + register struct qm_dqrr *dqrr = &portal->dqrr;
142971 + return dqrr->ithresh;
142972 +}
142973 +
142974 +static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142975 +{
142976 + qm_out(DQRR_ITR, ithresh);
142977 +}
142978 +
142979 +static inline u8 qm_dqrr_get_maxfill(struct qm_portal *portal)
142980 +{
142981 + return (qm_in(CFG) & 0x00f00000) >> 20;
142982 +}
142983 +
142984 +
142985 +/* -------------- */
142986 +/* --- MR API --- */
142987 +
142988 +#define MR_CARRYCLEAR(p) \
142989 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_MR_SIZE << 6)))
142990 +
142991 +static inline u8 MR_PTR2IDX(const struct qm_mr_entry *e)
142992 +{
142993 + return ((uintptr_t)e >> 6) & (QM_MR_SIZE - 1);
142994 +}
142995 +
142996 +static inline const struct qm_mr_entry *MR_INC(const struct qm_mr_entry *e)
142997 +{
142998 + return MR_CARRYCLEAR(e + 1);
142999 +}
143000 +
143001 +static inline int qm_mr_init(struct qm_portal *portal, enum qm_mr_pmode pmode,
143002 + enum qm_mr_cmode cmode)
143003 +{
143004 + register struct qm_mr *mr = &portal->mr;
143005 + u32 cfg;
143006 +
143007 + mr->ring = portal->addr.addr_ce + QM_CL_MR;
143008 + mr->pi = qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1);
143009 + mr->ci = qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1);
143010 + mr->cursor = mr->ring + mr->ci;
143011 + mr->fill = qm_cyc_diff(QM_MR_SIZE, mr->ci, mr->pi);
143012 + mr->vbit = (qm_in(MR_PI_CINH) & QM_MR_SIZE) ? QM_MR_VERB_VBIT : 0;
143013 + mr->ithresh = qm_in(MR_ITR);
143014 +#ifdef CONFIG_FSL_DPA_CHECKING
143015 + mr->pmode = pmode;
143016 + mr->cmode = cmode;
143017 +#endif
143018 + cfg = (qm_in(CFG) & 0xfffff0ff) |
143019 + ((cmode & 1) << 8); /* QCSP_CFG:MM */
143020 + qm_out(CFG, cfg);
143021 + return 0;
143022 +}
143023 +
143024 +static inline void qm_mr_finish(struct qm_portal *portal)
143025 +{
143026 + register struct qm_mr *mr = &portal->mr;
143027 + if (mr->ci != MR_PTR2IDX(mr->cursor))
143028 + pr_crit("Ignoring completed MR entries\n");
143029 +}
143030 +
143031 +static inline const struct qm_mr_entry *qm_mr_current(struct qm_portal *portal)
143032 +{
143033 + register struct qm_mr *mr = &portal->mr;
143034 + if (!mr->fill)
143035 + return NULL;
143036 + return mr->cursor;
143037 +}
143038 +
143039 +static inline u8 qm_mr_cursor(struct qm_portal *portal)
143040 +{
143041 + register struct qm_mr *mr = &portal->mr;
143042 + return MR_PTR2IDX(mr->cursor);
143043 +}
143044 +
143045 +static inline u8 qm_mr_next(struct qm_portal *portal)
143046 +{
143047 + register struct qm_mr *mr = &portal->mr;
143048 + DPA_ASSERT(mr->fill);
143049 + mr->cursor = MR_INC(mr->cursor);
143050 + return --mr->fill;
143051 +}
143052 +
143053 +static inline u8 qm_mr_pci_update(struct qm_portal *portal)
143054 +{
143055 + register struct qm_mr *mr = &portal->mr;
143056 + u8 diff, old_pi = mr->pi;
143057 + DPA_ASSERT(mr->pmode == qm_mr_pci);
143058 + mr->pi = qm_in(MR_PI_CINH);
143059 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
143060 + mr->fill += diff;
143061 + return diff;
143062 +}
143063 +
143064 +static inline void qm_mr_pce_prefetch(struct qm_portal *portal)
143065 +{
143066 + __maybe_unused register struct qm_mr *mr = &portal->mr;
143067 + DPA_ASSERT(mr->pmode == qm_mr_pce);
143068 + qm_cl_invalidate(MR_PI);
143069 + qm_cl_touch_ro(MR_PI);
143070 +}
143071 +
143072 +static inline u8 qm_mr_pce_update(struct qm_portal *portal)
143073 +{
143074 + register struct qm_mr *mr = &portal->mr;
143075 + u8 diff, old_pi = mr->pi;
143076 + DPA_ASSERT(mr->pmode == qm_mr_pce);
143077 + mr->pi = qm_cl_in(MR_PI) & (QM_MR_SIZE - 1);
143078 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
143079 + mr->fill += diff;
143080 + return diff;
143081 +}
143082 +
143083 +static inline void qm_mr_pvb_update(struct qm_portal *portal)
143084 +{
143085 + register struct qm_mr *mr = &portal->mr;
143086 + const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi);
143087 + DPA_ASSERT(mr->pmode == qm_mr_pvb);
143088 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
143089 + * inlining doesn't try to optimise out "excess reads". */
143090 + if ((__raw_readb(&res->verb) & QM_MR_VERB_VBIT) == mr->vbit) {
143091 + mr->pi = (mr->pi + 1) & (QM_MR_SIZE - 1);
143092 + if (!mr->pi)
143093 + mr->vbit ^= QM_MR_VERB_VBIT;
143094 + mr->fill++;
143095 + res = MR_INC(res);
143096 + }
143097 + dcbit_ro(res);
143098 +}
143099 +
143100 +static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num)
143101 +{
143102 + register struct qm_mr *mr = &portal->mr;
143103 + DPA_ASSERT(mr->cmode == qm_mr_cci);
143104 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
143105 + qm_out(MR_CI_CINH, mr->ci);
143106 +}
143107 +
143108 +static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal)
143109 +{
143110 + register struct qm_mr *mr = &portal->mr;
143111 + DPA_ASSERT(mr->cmode == qm_mr_cci);
143112 + mr->ci = MR_PTR2IDX(mr->cursor);
143113 + qm_out(MR_CI_CINH, mr->ci);
143114 +}
143115 +
143116 +static inline void qm_mr_cce_prefetch(struct qm_portal *portal)
143117 +{
143118 + __maybe_unused register struct qm_mr *mr = &portal->mr;
143119 + DPA_ASSERT(mr->cmode == qm_mr_cce);
143120 + qm_cl_invalidate(MR_CI);
143121 + qm_cl_touch_rw(MR_CI);
143122 +}
143123 +
143124 +static inline void qm_mr_cce_consume(struct qm_portal *portal, u8 num)
143125 +{
143126 + register struct qm_mr *mr = &portal->mr;
143127 + DPA_ASSERT(mr->cmode == qm_mr_cce);
143128 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
143129 + qm_cl_out(MR_CI, mr->ci);
143130 +}
143131 +
143132 +static inline void qm_mr_cce_consume_to_current(struct qm_portal *portal)
143133 +{
143134 + register struct qm_mr *mr = &portal->mr;
143135 + DPA_ASSERT(mr->cmode == qm_mr_cce);
143136 + mr->ci = MR_PTR2IDX(mr->cursor);
143137 + qm_cl_out(MR_CI, mr->ci);
143138 +}
143139 +
143140 +static inline u8 qm_mr_get_ci(struct qm_portal *portal)
143141 +{
143142 + register struct qm_mr *mr = &portal->mr;
143143 + return mr->ci;
143144 +}
143145 +
143146 +static inline u8 qm_mr_get_ithresh(struct qm_portal *portal)
143147 +{
143148 + register struct qm_mr *mr = &portal->mr;
143149 + return mr->ithresh;
143150 +}
143151 +
143152 +static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
143153 +{
143154 + qm_out(MR_ITR, ithresh);
143155 +}
143156 +
143157 +
143158 +/* ------------------------------ */
143159 +/* --- Management command API --- */
143160 +
143161 +static inline int qm_mc_init(struct qm_portal *portal)
143162 +{
143163 + register struct qm_mc *mc = &portal->mc;
143164 + mc->cr = portal->addr.addr_ce + QM_CL_CR;
143165 + mc->rr = portal->addr.addr_ce + QM_CL_RR0;
143166 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
143167 + QM_MCC_VERB_VBIT) ? 0 : 1;
143168 + mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
143169 +#ifdef CONFIG_FSL_DPA_CHECKING
143170 + mc->state = qman_mc_idle;
143171 +#endif
143172 + return 0;
143173 +}
143174 +
143175 +static inline void qm_mc_finish(struct qm_portal *portal)
143176 +{
143177 + __maybe_unused register struct qm_mc *mc = &portal->mc;
143178 + DPA_ASSERT(mc->state == qman_mc_idle);
143179 +#ifdef CONFIG_FSL_DPA_CHECKING
143180 + if (mc->state != qman_mc_idle)
143181 + pr_crit("Losing incomplete MC command\n");
143182 +#endif
143183 +}
143184 +
143185 +static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
143186 +{
143187 + register struct qm_mc *mc = &portal->mc;
143188 + DPA_ASSERT(mc->state == qman_mc_idle);
143189 +#ifdef CONFIG_FSL_DPA_CHECKING
143190 + mc->state = qman_mc_user;
143191 +#endif
143192 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
143193 + dcbz_64(mc->cr);
143194 +#endif
143195 + return mc->cr;
143196 +}
143197 +
143198 +static inline void qm_mc_abort(struct qm_portal *portal)
143199 +{
143200 + __maybe_unused register struct qm_mc *mc = &portal->mc;
143201 + DPA_ASSERT(mc->state == qman_mc_user);
143202 +#ifdef CONFIG_FSL_DPA_CHECKING
143203 + mc->state = qman_mc_idle;
143204 +#endif
143205 +}
143206 +
143207 +static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb)
143208 +{
143209 + register struct qm_mc *mc = &portal->mc;
143210 + struct qm_mc_result *rr = mc->rr + mc->rridx;
143211 + DPA_ASSERT(mc->state == qman_mc_user);
143212 + lwsync();
143213 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
143214 + dcbf(mc->cr);
143215 + dcbit_ro(rr);
143216 +#ifdef CONFIG_FSL_DPA_CHECKING
143217 + mc->state = qman_mc_hw;
143218 +#endif
143219 +}
143220 +
143221 +static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
143222 +{
143223 + register struct qm_mc *mc = &portal->mc;
143224 + struct qm_mc_result *rr = mc->rr + mc->rridx;
143225 + DPA_ASSERT(mc->state == qman_mc_hw);
143226 + /* The inactive response register's verb byte always returns zero until
143227 + * its command is submitted and completed. This includes the valid-bit,
143228 + * in case you were wondering... */
143229 + if (!__raw_readb(&rr->verb)) {
143230 + dcbit_ro(rr);
143231 + return NULL;
143232 + }
143233 + mc->rridx ^= 1;
143234 + mc->vbit ^= QM_MCC_VERB_VBIT;
143235 +#ifdef CONFIG_FSL_DPA_CHECKING
143236 + mc->state = qman_mc_idle;
143237 +#endif
143238 + return rr;
143239 +}
143240 +
143241 +
143242 +/* ------------------------------------- */
143243 +/* --- Portal interrupt register API --- */
143244 +
143245 +static inline int qm_isr_init(__always_unused struct qm_portal *portal)
143246 +{
143247 + return 0;
143248 +}
143249 +
143250 +static inline void qm_isr_finish(__always_unused struct qm_portal *portal)
143251 +{
143252 +}
143253 +
143254 +static inline void qm_isr_set_iperiod(struct qm_portal *portal, u16 iperiod)
143255 +{
143256 + qm_out(ITPR, iperiod);
143257 +}
143258 +
143259 +static inline u32 __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n)
143260 +{
143261 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
143262 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 6));
143263 +#else
143264 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 2));
143265 +#endif
143266 +}
143267 +
143268 +static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n,
143269 + u32 val)
143270 +{
143271 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
143272 + __qm_out(&portal->addr, QM_REG_ISR + (n << 6), val);
143273 +#else
143274 + __qm_out(&portal->addr, QM_REG_ISR + (n << 2), val);
143275 +#endif
143276 +}
143277 +
143278 +/* Cleanup FQs */
143279 +static inline int qm_shutdown_fq(struct qm_portal **portal, int portal_count,
143280 + u32 fqid)
143281 +{
143282 +
143283 + struct qm_mc_command *mcc;
143284 + struct qm_mc_result *mcr;
143285 + u8 state;
143286 + int orl_empty, fq_empty, i, drain = 0;
143287 + u32 result;
143288 + u32 channel, wq;
143289 + u16 dest_wq;
143290 +
143291 + /* Determine the state of the FQID */
143292 + mcc = qm_mc_start(portal[0]);
143293 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
143294 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ_NP);
143295 + while (!(mcr = qm_mc_result(portal[0])))
143296 + cpu_relax();
143297 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
143298 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
143299 + if (state == QM_MCR_NP_STATE_OOS)
143300 + return 0; /* Already OOS, no need to do anymore checks */
143301 +
143302 + /* Query which channel the FQ is using */
143303 + mcc = qm_mc_start(portal[0]);
143304 + mcc->queryfq.fqid = cpu_to_be32(fqid);
143305 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ);
143306 + while (!(mcr = qm_mc_result(portal[0])))
143307 + cpu_relax();
143308 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
143309 +
143310 + /* Need to store these since the MCR gets reused */
143311 + dest_wq = be16_to_cpu(mcr->queryfq.fqd.dest_wq);
143312 + wq = dest_wq & 0x7;
143313 + channel = dest_wq>>3;
143314 +
143315 + switch (state) {
143316 + case QM_MCR_NP_STATE_TEN_SCHED:
143317 + case QM_MCR_NP_STATE_TRU_SCHED:
143318 + case QM_MCR_NP_STATE_ACTIVE:
143319 + case QM_MCR_NP_STATE_PARKED:
143320 + orl_empty = 0;
143321 + mcc = qm_mc_start(portal[0]);
143322 + mcc->alterfq.fqid = cpu_to_be32(fqid);
143323 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_RETIRE);
143324 + while (!(mcr = qm_mc_result(portal[0])))
143325 + cpu_relax();
143326 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
143327 + QM_MCR_VERB_ALTER_RETIRE);
143328 + result = mcr->result; /* Make a copy as we reuse MCR below */
143329 +
143330 + if (result == QM_MCR_RESULT_PENDING) {
143331 + /* Need to wait for the FQRN in the message ring, which
143332 + will only occur once the FQ has been drained. In
143333 + order for the FQ to drain the portal needs to be set
143334 + to dequeue from the channel the FQ is scheduled on */
143335 + const struct qm_mr_entry *msg;
143336 + const struct qm_dqrr_entry *dqrr = NULL;
143337 + int found_fqrn = 0;
143338 + u16 dequeue_wq = 0;
143339 +
143340 + /* Flag that we need to drain FQ */
143341 + drain = 1;
143342 +
143343 + if (channel >= qm_channel_pool1 &&
143344 + channel < (qm_channel_pool1 + 15)) {
143345 + /* Pool channel, enable the bit in the portal */
143346 + dequeue_wq = (channel -
143347 + qm_channel_pool1 + 1)<<4 | wq;
143348 + } else if (channel < qm_channel_pool1) {
143349 + /* Dedicated channel */
143350 + dequeue_wq = wq;
143351 + } else {
143352 + pr_info("Cannot recover FQ 0x%x, it is "
143353 + "scheduled on channel 0x%x",
143354 + fqid, channel);
143355 + return -EBUSY;
143356 + }
143357 + /* Set the sdqcr to drain this channel */
143358 + if (channel < qm_channel_pool1)
143359 + for (i = 0; i < portal_count; i++)
143360 + qm_dqrr_sdqcr_set(portal[i],
143361 + QM_SDQCR_TYPE_ACTIVE |
143362 + QM_SDQCR_CHANNELS_DEDICATED);
143363 + else
143364 + for (i = 0; i < portal_count; i++)
143365 + qm_dqrr_sdqcr_set(
143366 + portal[i],
143367 + QM_SDQCR_TYPE_ACTIVE |
143368 + QM_SDQCR_CHANNELS_POOL_CONV
143369 + (channel));
143370 + while (!found_fqrn) {
143371 + /* Keep draining DQRR while checking the MR*/
143372 + for (i = 0; i < portal_count; i++) {
143373 + qm_dqrr_pvb_update(portal[i]);
143374 + dqrr = qm_dqrr_current(portal[i]);
143375 + while (dqrr) {
143376 + qm_dqrr_cdc_consume_1ptr(
143377 + portal[i], dqrr, 0);
143378 + qm_dqrr_pvb_update(portal[i]);
143379 + qm_dqrr_next(portal[i]);
143380 + dqrr = qm_dqrr_current(
143381 + portal[i]);
143382 + }
143383 + /* Process message ring too */
143384 + qm_mr_pvb_update(portal[i]);
143385 + msg = qm_mr_current(portal[i]);
143386 + while (msg) {
143387 + if ((msg->verb &
143388 + QM_MR_VERB_TYPE_MASK)
143389 + == QM_MR_VERB_FQRN)
143390 + found_fqrn = 1;
143391 + qm_mr_next(portal[i]);
143392 + qm_mr_cci_consume_to_current(
143393 + portal[i]);
143394 + qm_mr_pvb_update(portal[i]);
143395 + msg = qm_mr_current(portal[i]);
143396 + }
143397 + cpu_relax();
143398 + }
143399 + }
143400 + }
143401 + if (result != QM_MCR_RESULT_OK &&
143402 + result != QM_MCR_RESULT_PENDING) {
143403 + /* error */
143404 + pr_err("qman_retire_fq failed on FQ 0x%x, result=0x%x\n",
143405 + fqid, result);
143406 + return -1;
143407 + }
143408 + if (!(mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)) {
143409 + /* ORL had no entries, no need to wait until the
143410 + ERNs come in */
143411 + orl_empty = 1;
143412 + }
143413 + /* Retirement succeeded, check to see if FQ needs
143414 + to be drained */
143415 + if (drain || mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY) {
143416 + /* FQ is Not Empty, drain using volatile DQ commands */
143417 + fq_empty = 0;
143418 + do {
143419 + const struct qm_dqrr_entry *dqrr = NULL;
143420 + u32 vdqcr = fqid | QM_VDQCR_NUMFRAMES_SET(3);
143421 + qm_dqrr_vdqcr_set(portal[0], vdqcr);
143422 +
143423 + /* Wait for a dequeue to occur */
143424 + while (dqrr == NULL) {
143425 + qm_dqrr_pvb_update(portal[0]);
143426 + dqrr = qm_dqrr_current(portal[0]);
143427 + if (!dqrr)
143428 + cpu_relax();
143429 + }
143430 + /* Process the dequeues, making sure to
143431 + empty the ring completely */
143432 + while (dqrr) {
143433 + if (be32_to_cpu(dqrr->fqid) == fqid &&
143434 + dqrr->stat & QM_DQRR_STAT_FQ_EMPTY)
143435 + fq_empty = 1;
143436 + qm_dqrr_cdc_consume_1ptr(portal[0],
143437 + dqrr, 0);
143438 + qm_dqrr_pvb_update(portal[0]);
143439 + qm_dqrr_next(portal[0]);
143440 + dqrr = qm_dqrr_current(portal[0]);
143441 + }
143442 + } while (fq_empty == 0);
143443 + }
143444 + for (i = 0; i < portal_count; i++)
143445 + qm_dqrr_sdqcr_set(portal[i], 0);
143446 +
143447 + /* Wait for the ORL to have been completely drained */
143448 + while (orl_empty == 0) {
143449 + const struct qm_mr_entry *msg;
143450 + qm_mr_pvb_update(portal[0]);
143451 + msg = qm_mr_current(portal[0]);
143452 + while (msg) {
143453 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) ==
143454 + QM_MR_VERB_FQRL)
143455 + orl_empty = 1;
143456 + qm_mr_next(portal[0]);
143457 + qm_mr_cci_consume_to_current(portal[0]);
143458 + qm_mr_pvb_update(portal[0]);
143459 + msg = qm_mr_current(portal[0]);
143460 + }
143461 + cpu_relax();
143462 + }
143463 + mcc = qm_mc_start(portal[0]);
143464 + mcc->alterfq.fqid = cpu_to_be32(fqid);
143465 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
143466 + while (!(mcr = qm_mc_result(portal[0])))
143467 + cpu_relax();
143468 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
143469 + QM_MCR_VERB_ALTER_OOS);
143470 + if (mcr->result != QM_MCR_RESULT_OK) {
143471 + pr_err("OOS after drain Failed on FQID 0x%x, result 0x%x\n",
143472 + fqid, mcr->result);
143473 + return -1;
143474 + }
143475 + return 0;
143476 + case QM_MCR_NP_STATE_RETIRED:
143477 + /* Send OOS Command */
143478 + mcc = qm_mc_start(portal[0]);
143479 + mcc->alterfq.fqid = cpu_to_be32(fqid);
143480 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
143481 + while (!(mcr = qm_mc_result(portal[0])))
143482 + cpu_relax();
143483 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
143484 + QM_MCR_VERB_ALTER_OOS);
143485 + if (mcr->result) {
143486 + pr_err("OOS Failed on FQID 0x%x\n", fqid);
143487 + return -1;
143488 + }
143489 + return 0;
143490 + }
143491 + return -1;
143492 +}
143493 diff --git a/drivers/staging/fsl_qbman/qman_private.h b/drivers/staging/fsl_qbman/qman_private.h
143494 new file mode 100644
143495 index 00000000..ee025cff
143496 --- /dev/null
143497 +++ b/drivers/staging/fsl_qbman/qman_private.h
143498 @@ -0,0 +1,398 @@
143499 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
143500 + *
143501 + * Redistribution and use in source and binary forms, with or without
143502 + * modification, are permitted provided that the following conditions are met:
143503 + * * Redistributions of source code must retain the above copyright
143504 + * notice, this list of conditions and the following disclaimer.
143505 + * * Redistributions in binary form must reproduce the above copyright
143506 + * notice, this list of conditions and the following disclaimer in the
143507 + * documentation and/or other materials provided with the distribution.
143508 + * * Neither the name of Freescale Semiconductor nor the
143509 + * names of its contributors may be used to endorse or promote products
143510 + * derived from this software without specific prior written permission.
143511 + *
143512 + *
143513 + * ALTERNATIVELY, this software may be distributed under the terms of the
143514 + * GNU General Public License ("GPL") as published by the Free Software
143515 + * Foundation, either version 2 of that License or (at your option) any
143516 + * later version.
143517 + *
143518 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143519 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143520 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143521 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143522 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143523 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143524 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143525 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143526 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143527 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143528 + */
143529 +
143530 +#include "dpa_sys.h"
143531 +#include <linux/fsl_qman.h>
143532 +#include <linux/iommu.h>
143533 +
143534 +#if defined(CONFIG_FSL_PAMU)
143535 +#include <asm/fsl_pamu_stash.h>
143536 +#endif
143537 +
143538 +#if !defined(CONFIG_FSL_QMAN_FQ_LOOKUP) && defined(CONFIG_PPC64)
143539 +#error "_PPC64 requires _FSL_QMAN_FQ_LOOKUP"
143540 +#endif
143541 +
143542 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
143543 + /* ----------------- */
143544 + /* Congestion Groups */
143545 + /* ----------------- */
143546 +/* This wrapper represents a bit-array for the state of the 256 Qman congestion
143547 + * groups. Is also used as a *mask* for congestion groups, eg. so we ignore
143548 + * those that don't concern us. We harness the structure and accessor details
143549 + * already used in the management command to query congestion groups. */
143550 +struct qman_cgrs {
143551 + struct __qm_mcr_querycongestion q;
143552 +};
143553 +static inline void qman_cgrs_init(struct qman_cgrs *c)
143554 +{
143555 + memset(c, 0, sizeof(*c));
143556 +}
143557 +static inline void qman_cgrs_fill(struct qman_cgrs *c)
143558 +{
143559 + memset(c, 0xff, sizeof(*c));
143560 +}
143561 +static inline int qman_cgrs_get(struct qman_cgrs *c, int num)
143562 +{
143563 + return QM_MCR_QUERYCONGESTION(&c->q, num);
143564 +}
143565 +static inline void qman_cgrs_set(struct qman_cgrs *c, int num)
143566 +{
143567 + c->q.__state[__CGR_WORD(num)] |= (0x80000000 >> __CGR_SHIFT(num));
143568 +}
143569 +static inline void qman_cgrs_unset(struct qman_cgrs *c, int num)
143570 +{
143571 + c->q.__state[__CGR_WORD(num)] &= ~(0x80000000 >> __CGR_SHIFT(num));
143572 +}
143573 +static inline int qman_cgrs_next(struct qman_cgrs *c, int num)
143574 +{
143575 + while ((++num < __CGR_NUM) && !qman_cgrs_get(c, num))
143576 + ;
143577 + return num;
143578 +}
143579 +static inline void qman_cgrs_cp(struct qman_cgrs *dest,
143580 + const struct qman_cgrs *src)
143581 +{
143582 + *dest = *src;
143583 +}
143584 +static inline void qman_cgrs_and(struct qman_cgrs *dest,
143585 + const struct qman_cgrs *a, const struct qman_cgrs *b)
143586 +{
143587 + int ret;
143588 + u32 *_d = dest->q.__state;
143589 + const u32 *_a = a->q.__state;
143590 + const u32 *_b = b->q.__state;
143591 + for (ret = 0; ret < 8; ret++)
143592 + *(_d++) = *(_a++) & *(_b++);
143593 +}
143594 +static inline void qman_cgrs_xor(struct qman_cgrs *dest,
143595 + const struct qman_cgrs *a, const struct qman_cgrs *b)
143596 +{
143597 + int ret;
143598 + u32 *_d = dest->q.__state;
143599 + const u32 *_a = a->q.__state;
143600 + const u32 *_b = b->q.__state;
143601 + for (ret = 0; ret < 8; ret++)
143602 + *(_d++) = *(_a++) ^ *(_b++);
143603 +}
143604 +
143605 + /* ----------------------- */
143606 + /* CEETM Congestion Groups */
143607 + /* ----------------------- */
143608 +/* This wrapper represents a bit-array for the state of the 512 Qman CEETM
143609 + * congestion groups.
143610 + */
143611 +struct qman_ccgrs {
143612 + struct __qm_mcr_querycongestion q[2];
143613 +};
143614 +static inline void qman_ccgrs_init(struct qman_ccgrs *c)
143615 +{
143616 + memset(c, 0, sizeof(*c));
143617 +}
143618 +static inline void qman_ccgrs_fill(struct qman_ccgrs *c)
143619 +{
143620 + memset(c, 0xff, sizeof(*c));
143621 +}
143622 +static inline int qman_ccgrs_get(struct qman_ccgrs *c, int num)
143623 +{
143624 + if (num < __CGR_NUM)
143625 + return QM_MCR_QUERYCONGESTION(&c->q[0], num);
143626 + else
143627 + return QM_MCR_QUERYCONGESTION(&c->q[1], (num - __CGR_NUM));
143628 +}
143629 +static inline int qman_ccgrs_next(struct qman_ccgrs *c, int num)
143630 +{
143631 + while ((++num < __CGR_NUM) && !qman_ccgrs_get(c, num))
143632 + ;
143633 + return num;
143634 +}
143635 +static inline void qman_ccgrs_cp(struct qman_ccgrs *dest,
143636 + const struct qman_ccgrs *src)
143637 +{
143638 + *dest = *src;
143639 +}
143640 +static inline void qman_ccgrs_and(struct qman_ccgrs *dest,
143641 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
143642 +{
143643 + int ret, i;
143644 + u32 *_d;
143645 + const u32 *_a, *_b;
143646 + for (i = 0; i < 2; i++) {
143647 + _d = dest->q[i].__state;
143648 + _a = a->q[i].__state;
143649 + _b = b->q[i].__state;
143650 + for (ret = 0; ret < 8; ret++)
143651 + *(_d++) = *(_a++) & *(_b++);
143652 + }
143653 +}
143654 +static inline void qman_ccgrs_xor(struct qman_ccgrs *dest,
143655 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
143656 +{
143657 + int ret, i;
143658 + u32 *_d;
143659 + const u32 *_a, *_b;
143660 + for (i = 0; i < 2; i++) {
143661 + _d = dest->q[i].__state;
143662 + _a = a->q[i].__state;
143663 + _b = b->q[i].__state;
143664 + for (ret = 0; ret < 8; ret++)
143665 + *(_d++) = *(_a++) ^ *(_b++);
143666 + }
143667 +}
143668 +
143669 +/* used by CCSR and portal interrupt code */
143670 +enum qm_isr_reg {
143671 + qm_isr_status = 0,
143672 + qm_isr_enable = 1,
143673 + qm_isr_disable = 2,
143674 + qm_isr_inhibit = 3
143675 +};
143676 +
143677 +struct qm_portal_config {
143678 + /* Corenet portal addresses;
143679 + * [0]==cache-enabled, [1]==cache-inhibited. */
143680 + __iomem void *addr_virt[2];
143681 + struct resource addr_phys[2];
143682 + struct device dev;
143683 + struct iommu_domain *iommu_domain;
143684 + /* Allow these to be joined in lists */
143685 + struct list_head list;
143686 + /* User-visible portal configuration settings */
143687 + struct qman_portal_config public_cfg;
143688 + /* power management saved data */
143689 + u32 saved_isdr;
143690 +};
143691 +
143692 +/* Revision info (for errata and feature handling) */
143693 +#define QMAN_REV11 0x0101
143694 +#define QMAN_REV12 0x0102
143695 +#define QMAN_REV20 0x0200
143696 +#define QMAN_REV30 0x0300
143697 +#define QMAN_REV31 0x0301
143698 +#define QMAN_REV32 0x0302
143699 +
143700 +/* QMan REV_2 register contains the Cfg option */
143701 +#define QMAN_REV_CFG_0 0x0
143702 +#define QMAN_REV_CFG_1 0x1
143703 +#define QMAN_REV_CFG_2 0x2
143704 +#define QMAN_REV_CFG_3 0x3
143705 +
143706 +extern u16 qman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
143707 +extern u8 qman_ip_cfg;
143708 +extern u32 qman_clk;
143709 +extern u16 qman_portal_max;
143710 +
143711 +#ifdef CONFIG_FSL_QMAN_CONFIG
143712 +/* Hooks from qman_driver.c to qman_config.c */
143713 +int qman_init_ccsr(struct device_node *node);
143714 +void qman_liodn_fixup(u16 channel);
143715 +int qman_set_sdest(u16 channel, unsigned int cpu_idx);
143716 +size_t get_qman_fqd_size(void);
143717 +#else
143718 +static inline size_t get_qman_fqd_size(void)
143719 +{
143720 + return (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ);
143721 +}
143722 +#endif
143723 +
143724 +int qm_set_wpm(int wpm);
143725 +int qm_get_wpm(int *wpm);
143726 +
143727 +/* Hooks from qman_driver.c in to qman_high.c */
143728 +struct qman_portal *qman_create_portal(
143729 + struct qman_portal *portal,
143730 + const struct qm_portal_config *config,
143731 + const struct qman_cgrs *cgrs);
143732 +
143733 +struct qman_portal *qman_create_affine_portal(
143734 + const struct qm_portal_config *config,
143735 + const struct qman_cgrs *cgrs);
143736 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
143737 + int cpu);
143738 +const struct qm_portal_config *qman_destroy_affine_portal(void);
143739 +void qman_destroy_portal(struct qman_portal *qm);
143740 +
143741 +/* Hooks from fsl_usdpaa.c to qman_driver.c */
143742 +struct qm_portal_config *qm_get_unused_portal(void);
143743 +struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx);
143744 +
143745 +void qm_put_unused_portal(struct qm_portal_config *pcfg);
143746 +void qm_set_liodns(struct qm_portal_config *pcfg);
143747 +
143748 +/* This CGR feature is supported by h/w and required by unit-tests and the
143749 + * debugfs hooks, so is implemented in the driver. However it allows an explicit
143750 + * corruption of h/w fields by s/w that are usually incorruptible (because the
143751 + * counters are usually maintained entirely within h/w). As such, we declare
143752 + * this API internally. */
143753 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
143754 + struct qm_mcr_cgrtestwrite *result);
143755 +
143756 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
143757 +/* If the fq object pointer is greater than the size of context_b field,
143758 + * than a lookup table is required. */
143759 +int qman_setup_fq_lookup_table(size_t num_entries);
143760 +#endif
143761 +
143762 +
143763 +/*************************************************/
143764 +/* QMan s/w corenet portal, low-level i/face */
143765 +/*************************************************/
143766 +
143767 +/* Note: most functions are only used by the high-level interface, so are
143768 + * inlined from qman_low.h. The stuff below is for use by other parts of the
143769 + * driver. */
143770 +
143771 +/* For qm_dqrr_sdqcr_set(); Choose one SOURCE. Choose one COUNT. Choose one
143772 + * dequeue TYPE. Choose TOKEN (8-bit).
143773 + * If SOURCE == CHANNELS,
143774 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL(n).
143775 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
143776 + * priority.
143777 + * If SOURCE == SPECIFICWQ,
143778 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
143779 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
143780 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
143781 + * same value.
143782 + */
143783 +#define QM_SDQCR_SOURCE_CHANNELS 0x0
143784 +#define QM_SDQCR_SOURCE_SPECIFICWQ 0x40000000
143785 +#define QM_SDQCR_COUNT_EXACT1 0x0
143786 +#define QM_SDQCR_COUNT_UPTO3 0x20000000
143787 +#define QM_SDQCR_DEDICATED_PRECEDENCE 0x10000000
143788 +#define QM_SDQCR_TYPE_MASK 0x03000000
143789 +#define QM_SDQCR_TYPE_NULL 0x0
143790 +#define QM_SDQCR_TYPE_PRIO_QOS 0x01000000
143791 +#define QM_SDQCR_TYPE_ACTIVE_QOS 0x02000000
143792 +#define QM_SDQCR_TYPE_ACTIVE 0x03000000
143793 +#define QM_SDQCR_TOKEN_MASK 0x00ff0000
143794 +#define QM_SDQCR_TOKEN_SET(v) (((v) & 0xff) << 16)
143795 +#define QM_SDQCR_TOKEN_GET(v) (((v) >> 16) & 0xff)
143796 +#define QM_SDQCR_CHANNELS_DEDICATED 0x00008000
143797 +#define QM_SDQCR_SPECIFICWQ_MASK 0x000000f7
143798 +#define QM_SDQCR_SPECIFICWQ_DEDICATED 0x00000000
143799 +#define QM_SDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
143800 +#define QM_SDQCR_SPECIFICWQ_WQ(n) (n)
143801 +
143802 +/* For qm_dqrr_vdqcr_set(): use FQID(n) to fill in the frame queue ID */
143803 +#define QM_VDQCR_FQID_MASK 0x00ffffff
143804 +#define QM_VDQCR_FQID(n) ((n) & QM_VDQCR_FQID_MASK)
143805 +
143806 +/* For qm_dqrr_pdqcr_set(); Choose one MODE. Choose one COUNT.
143807 + * If MODE==SCHEDULED
143808 + * Choose SCHEDULED_CHANNELS or SCHEDULED_SPECIFICWQ. Choose one dequeue TYPE.
143809 + * If CHANNELS,
143810 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL() channels.
143811 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
143812 + * priority.
143813 + * If SPECIFICWQ,
143814 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
143815 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
143816 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
143817 + * same value.
143818 + * If MODE==UNSCHEDULED
143819 + * Choose FQID().
143820 + */
143821 +#define QM_PDQCR_MODE_SCHEDULED 0x0
143822 +#define QM_PDQCR_MODE_UNSCHEDULED 0x80000000
143823 +#define QM_PDQCR_SCHEDULED_CHANNELS 0x0
143824 +#define QM_PDQCR_SCHEDULED_SPECIFICWQ 0x40000000
143825 +#define QM_PDQCR_COUNT_EXACT1 0x0
143826 +#define QM_PDQCR_COUNT_UPTO3 0x20000000
143827 +#define QM_PDQCR_DEDICATED_PRECEDENCE 0x10000000
143828 +#define QM_PDQCR_TYPE_MASK 0x03000000
143829 +#define QM_PDQCR_TYPE_NULL 0x0
143830 +#define QM_PDQCR_TYPE_PRIO_QOS 0x01000000
143831 +#define QM_PDQCR_TYPE_ACTIVE_QOS 0x02000000
143832 +#define QM_PDQCR_TYPE_ACTIVE 0x03000000
143833 +#define QM_PDQCR_CHANNELS_DEDICATED 0x00008000
143834 +#define QM_PDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
143835 +#define QM_PDQCR_SPECIFICWQ_MASK 0x000000f7
143836 +#define QM_PDQCR_SPECIFICWQ_DEDICATED 0x00000000
143837 +#define QM_PDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
143838 +#define QM_PDQCR_SPECIFICWQ_WQ(n) (n)
143839 +#define QM_PDQCR_FQID(n) ((n) & 0xffffff)
143840 +
143841 +/* Used by all portal interrupt registers except 'inhibit'
143842 + * Channels with frame availability
143843 + */
143844 +#define QM_PIRQ_DQAVAIL 0x0000ffff
143845 +
143846 +/* The DQAVAIL interrupt fields break down into these bits; */
143847 +#define QM_DQAVAIL_PORTAL 0x8000 /* Portal channel */
143848 +#define QM_DQAVAIL_POOL(n) (0x8000 >> (n)) /* Pool channel, n==[1..15] */
143849 +#define QM_DQAVAIL_MASK 0xffff
143850 +/* This mask contains all the "irqsource" bits visible to API users */
143851 +#define QM_PIRQ_VISIBLE (QM_PIRQ_SLOW | QM_PIRQ_DQRI)
143852 +
143853 +/* These are qm_<reg>_<verb>(). So for example, qm_disable_write() means "write
143854 + * the disable register" rather than "disable the ability to write". */
143855 +#define qm_isr_status_read(qm) __qm_isr_read(qm, qm_isr_status)
143856 +#define qm_isr_status_clear(qm, m) __qm_isr_write(qm, qm_isr_status, m)
143857 +#define qm_isr_enable_read(qm) __qm_isr_read(qm, qm_isr_enable)
143858 +#define qm_isr_enable_write(qm, v) __qm_isr_write(qm, qm_isr_enable, v)
143859 +#define qm_isr_disable_read(qm) __qm_isr_read(qm, qm_isr_disable)
143860 +#define qm_isr_disable_write(qm, v) __qm_isr_write(qm, qm_isr_disable, v)
143861 +/* TODO: unfortunate name-clash here, reword? */
143862 +#define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1)
143863 +#define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0)
143864 +
143865 +#ifdef CONFIG_FSL_QMAN_CONFIG
143866 +int qman_have_ccsr(void);
143867 +#else
143868 +#define qman_have_ccsr 0
143869 +#endif
143870 +
143871 +__init int qman_init(void);
143872 +__init int qman_resource_init(void);
143873 +
143874 +/* CEETM related */
143875 +#define QMAN_CEETM_MAX 2
143876 +extern u8 num_ceetms;
143877 +extern struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
143878 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
143879 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
143880 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal);
143881 +int qman_ceetm_get_prescaler(u16 *pres);
143882 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
143883 + struct qm_mcr_ceetm_cq_query *cq_query);
143884 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
143885 + struct qm_mcr_ceetm_ccgr_query *response);
143886 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num);
143887 +
143888 +extern void *affine_portals[NR_CPUS];
143889 +const struct qm_portal_config *qman_get_qm_portal_config(
143890 + struct qman_portal *portal);
143891 +
143892 +/* power management */
143893 +#ifdef CONFIG_SUSPEND
143894 +void suspend_unused_qportal(void);
143895 +void resume_unused_qportal(void);
143896 +#endif
143897 diff --git a/drivers/staging/fsl_qbman/qman_test.c b/drivers/staging/fsl_qbman/qman_test.c
143898 new file mode 100644
143899 index 00000000..7995dd8c
143900 --- /dev/null
143901 +++ b/drivers/staging/fsl_qbman/qman_test.c
143902 @@ -0,0 +1,57 @@
143903 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143904 + *
143905 + * Redistribution and use in source and binary forms, with or without
143906 + * modification, are permitted provided that the following conditions are met:
143907 + * * Redistributions of source code must retain the above copyright
143908 + * notice, this list of conditions and the following disclaimer.
143909 + * * Redistributions in binary form must reproduce the above copyright
143910 + * notice, this list of conditions and the following disclaimer in the
143911 + * documentation and/or other materials provided with the distribution.
143912 + * * Neither the name of Freescale Semiconductor nor the
143913 + * names of its contributors may be used to endorse or promote products
143914 + * derived from this software without specific prior written permission.
143915 + *
143916 + *
143917 + * ALTERNATIVELY, this software may be distributed under the terms of the
143918 + * GNU General Public License ("GPL") as published by the Free Software
143919 + * Foundation, either version 2 of that License or (at your option) any
143920 + * later version.
143921 + *
143922 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143923 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143924 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143925 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143926 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143927 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143928 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143929 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143930 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143931 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143932 + */
143933 +
143934 +#include "qman_test.h"
143935 +
143936 +MODULE_AUTHOR("Geoff Thorpe");
143937 +MODULE_LICENSE("Dual BSD/GPL");
143938 +MODULE_DESCRIPTION("Qman testing");
143939 +
143940 +static int test_init(void)
143941 +{
143942 + int loop = 1;
143943 + while (loop--) {
143944 +#ifdef CONFIG_FSL_QMAN_TEST_STASH_POTATO
143945 + qman_test_hotpotato();
143946 +#endif
143947 +#ifdef CONFIG_FSL_QMAN_TEST_HIGH
143948 + qman_test_high();
143949 +#endif
143950 + }
143951 + return 0;
143952 +}
143953 +
143954 +static void test_exit(void)
143955 +{
143956 +}
143957 +
143958 +module_init(test_init);
143959 +module_exit(test_exit);
143960 diff --git a/drivers/staging/fsl_qbman/qman_test.h b/drivers/staging/fsl_qbman/qman_test.h
143961 new file mode 100644
143962 index 00000000..8c4181c7
143963 --- /dev/null
143964 +++ b/drivers/staging/fsl_qbman/qman_test.h
143965 @@ -0,0 +1,45 @@
143966 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143967 + *
143968 + * Redistribution and use in source and binary forms, with or without
143969 + * modification, are permitted provided that the following conditions are met:
143970 + * * Redistributions of source code must retain the above copyright
143971 + * notice, this list of conditions and the following disclaimer.
143972 + * * Redistributions in binary form must reproduce the above copyright
143973 + * notice, this list of conditions and the following disclaimer in the
143974 + * documentation and/or other materials provided with the distribution.
143975 + * * Neither the name of Freescale Semiconductor nor the
143976 + * names of its contributors may be used to endorse or promote products
143977 + * derived from this software without specific prior written permission.
143978 + *
143979 + *
143980 + * ALTERNATIVELY, this software may be distributed under the terms of the
143981 + * GNU General Public License ("GPL") as published by the Free Software
143982 + * Foundation, either version 2 of that License or (at your option) any
143983 + * later version.
143984 + *
143985 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143986 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143987 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143988 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143989 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143990 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143991 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143992 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143993 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143994 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143995 + */
143996 +
143997 +#include <linux/kernel.h>
143998 +#include <linux/errno.h>
143999 +#include <linux/io.h>
144000 +#include <linux/slab.h>
144001 +#include <linux/module.h>
144002 +#include <linux/interrupt.h>
144003 +#include <linux/delay.h>
144004 +#include <linux/sched.h>
144005 +
144006 +#include <linux/fsl_qman.h>
144007 +
144008 +void qman_test_hotpotato(void);
144009 +void qman_test_high(void);
144010 +
144011 diff --git a/drivers/staging/fsl_qbman/qman_test_high.c b/drivers/staging/fsl_qbman/qman_test_high.c
144012 new file mode 100644
144013 index 00000000..65ee270e
144014 --- /dev/null
144015 +++ b/drivers/staging/fsl_qbman/qman_test_high.c
144016 @@ -0,0 +1,216 @@
144017 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
144018 + *
144019 + * Redistribution and use in source and binary forms, with or without
144020 + * modification, are permitted provided that the following conditions are met:
144021 + * * Redistributions of source code must retain the above copyright
144022 + * notice, this list of conditions and the following disclaimer.
144023 + * * Redistributions in binary form must reproduce the above copyright
144024 + * notice, this list of conditions and the following disclaimer in the
144025 + * documentation and/or other materials provided with the distribution.
144026 + * * Neither the name of Freescale Semiconductor nor the
144027 + * names of its contributors may be used to endorse or promote products
144028 + * derived from this software without specific prior written permission.
144029 + *
144030 + *
144031 + * ALTERNATIVELY, this software may be distributed under the terms of the
144032 + * GNU General Public License ("GPL") as published by the Free Software
144033 + * Foundation, either version 2 of that License or (at your option) any
144034 + * later version.
144035 + *
144036 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144037 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144038 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144039 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144040 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144041 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144042 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144043 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144044 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144045 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144046 + */
144047 +
144048 +#include "qman_test.h"
144049 +
144050 +/*************/
144051 +/* constants */
144052 +/*************/
144053 +
144054 +#define CGR_ID 27
144055 +#define POOL_ID 2
144056 +#define FQ_FLAGS QMAN_FQ_FLAG_DYNAMIC_FQID
144057 +#define NUM_ENQUEUES 10
144058 +#define NUM_PARTIAL 4
144059 +#define PORTAL_SDQCR (QM_SDQCR_SOURCE_CHANNELS | \
144060 + QM_SDQCR_TYPE_PRIO_QOS | \
144061 + QM_SDQCR_TOKEN_SET(0x98) | \
144062 + QM_SDQCR_CHANNELS_DEDICATED | \
144063 + QM_SDQCR_CHANNELS_POOL(POOL_ID))
144064 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
144065 +#define VDQCR_FLAGS (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH)
144066 +
144067 +/*************************************/
144068 +/* Predeclarations (eg. for fq_base) */
144069 +/*************************************/
144070 +
144071 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
144072 + struct qman_fq *,
144073 + const struct qm_dqrr_entry *);
144074 +static void cb_ern(struct qman_portal *, struct qman_fq *,
144075 + const struct qm_mr_entry *);
144076 +static void cb_fqs(struct qman_portal *, struct qman_fq *,
144077 + const struct qm_mr_entry *);
144078 +
144079 +/***************/
144080 +/* global vars */
144081 +/***************/
144082 +
144083 +static struct qm_fd fd, fd_dq;
144084 +static struct qman_fq fq_base = {
144085 + .cb.dqrr = cb_dqrr,
144086 + .cb.ern = cb_ern,
144087 + .cb.fqs = cb_fqs
144088 +};
144089 +static DECLARE_WAIT_QUEUE_HEAD(waitqueue);
144090 +static int retire_complete, sdqcr_complete;
144091 +
144092 +/**********************/
144093 +/* internal functions */
144094 +/**********************/
144095 +
144096 +/* Helpers for initialising and "incrementing" a frame descriptor */
144097 +static void fd_init(struct qm_fd *__fd)
144098 +{
144099 + qm_fd_addr_set64(__fd, 0xabdeadbeefLLU);
144100 + __fd->format = qm_fd_contig_big;
144101 + __fd->length29 = 0x0000ffff;
144102 + __fd->cmd = 0xfeedf00d;
144103 +}
144104 +
144105 +static void fd_inc(struct qm_fd *__fd)
144106 +{
144107 + u64 t = qm_fd_addr_get64(__fd);
144108 + int z = t >> 40;
144109 + t <<= 1;
144110 + if (z)
144111 + t |= 1;
144112 + qm_fd_addr_set64(__fd, t);
144113 + __fd->length29--;
144114 + __fd->cmd++;
144115 +}
144116 +
144117 +/* The only part of the 'fd' we can't memcmp() is the ppid */
144118 +static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b)
144119 +{
144120 + int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1;
144121 + if (!r)
144122 + r = a->format - b->format;
144123 + if (!r)
144124 + r = a->opaque - b->opaque;
144125 + if (!r)
144126 + r = a->cmd - b->cmd;
144127 + return r;
144128 +}
144129 +
144130 +/********/
144131 +/* test */
144132 +/********/
144133 +
144134 +static void do_enqueues(struct qman_fq *fq)
144135 +{
144136 + unsigned int loop;
144137 + for (loop = 0; loop < NUM_ENQUEUES; loop++) {
144138 + if (qman_enqueue(fq, &fd, QMAN_ENQUEUE_FLAG_WAIT |
144139 + (((loop + 1) == NUM_ENQUEUES) ?
144140 + QMAN_ENQUEUE_FLAG_WAIT_SYNC : 0)))
144141 + panic("qman_enqueue() failed\n");
144142 + fd_inc(&fd);
144143 + }
144144 +}
144145 +
144146 +void qman_test_high(void)
144147 +{
144148 + unsigned int flags;
144149 + int res;
144150 + struct qman_fq *fq = &fq_base;
144151 +
144152 + pr_info("qman_test_high starting\n");
144153 + fd_init(&fd);
144154 + fd_init(&fd_dq);
144155 +
144156 + /* Initialise (parked) FQ */
144157 + if (qman_create_fq(0, FQ_FLAGS, fq))
144158 + panic("qman_create_fq() failed\n");
144159 + if (qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL))
144160 + panic("qman_init_fq() failed\n");
144161 +
144162 + /* Do enqueues + VDQCR, twice. (Parked FQ) */
144163 + do_enqueues(fq);
144164 + pr_info("VDQCR (till-empty);\n");
144165 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
144166 + QM_VDQCR_NUMFRAMES_TILLEMPTY))
144167 + panic("qman_volatile_dequeue() failed\n");
144168 + do_enqueues(fq);
144169 + pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES);
144170 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
144171 + QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL)))
144172 + panic("qman_volatile_dequeue() failed\n");
144173 + pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL,
144174 + NUM_ENQUEUES);
144175 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
144176 + QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL)))
144177 + panic("qman_volatile_dequeue() failed\n");
144178 +
144179 + do_enqueues(fq);
144180 + pr_info("scheduled dequeue (till-empty)\n");
144181 + if (qman_schedule_fq(fq))
144182 + panic("qman_schedule_fq() failed\n");
144183 + wait_event(waitqueue, sdqcr_complete);
144184 +
144185 + /* Retire and OOS the FQ */
144186 + res = qman_retire_fq(fq, &flags);
144187 + if (res < 0)
144188 + panic("qman_retire_fq() failed\n");
144189 + wait_event(waitqueue, retire_complete);
144190 + if (flags & QMAN_FQ_STATE_BLOCKOOS)
144191 + panic("leaking frames\n");
144192 + if (qman_oos_fq(fq))
144193 + panic("qman_oos_fq() failed\n");
144194 + qman_destroy_fq(fq, 0);
144195 + pr_info("qman_test_high finished\n");
144196 +}
144197 +
144198 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
144199 + struct qman_fq *fq,
144200 + const struct qm_dqrr_entry *dq)
144201 +{
144202 + if (fd_cmp(&fd_dq, &dq->fd)) {
144203 + pr_err("BADNESS: dequeued frame doesn't match;\n");
144204 + pr_err("Expected 0x%llx, got 0x%llx\n",
144205 + (unsigned long long)fd_dq.length29,
144206 + (unsigned long long)dq->fd.length29);
144207 + BUG();
144208 + }
144209 + fd_inc(&fd_dq);
144210 + if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) {
144211 + sdqcr_complete = 1;
144212 + wake_up(&waitqueue);
144213 + }
144214 + return qman_cb_dqrr_consume;
144215 +}
144216 +
144217 +static void cb_ern(struct qman_portal *p, struct qman_fq *fq,
144218 + const struct qm_mr_entry *msg)
144219 +{
144220 + panic("cb_ern() unimplemented");
144221 +}
144222 +
144223 +static void cb_fqs(struct qman_portal *p, struct qman_fq *fq,
144224 + const struct qm_mr_entry *msg)
144225 +{
144226 + u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK);
144227 + if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI))
144228 + panic("unexpected FQS message");
144229 + pr_info("Retirement message received\n");
144230 + retire_complete = 1;
144231 + wake_up(&waitqueue);
144232 +}
144233 diff --git a/drivers/staging/fsl_qbman/qman_test_hotpotato.c b/drivers/staging/fsl_qbman/qman_test_hotpotato.c
144234 new file mode 100644
144235 index 00000000..899d2aa9
144236 --- /dev/null
144237 +++ b/drivers/staging/fsl_qbman/qman_test_hotpotato.c
144238 @@ -0,0 +1,502 @@
144239 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
144240 + *
144241 + * Redistribution and use in source and binary forms, with or without
144242 + * modification, are permitted provided that the following conditions are met:
144243 + * * Redistributions of source code must retain the above copyright
144244 + * notice, this list of conditions and the following disclaimer.
144245 + * * Redistributions in binary form must reproduce the above copyright
144246 + * notice, this list of conditions and the following disclaimer in the
144247 + * documentation and/or other materials provided with the distribution.
144248 + * * Neither the name of Freescale Semiconductor nor the
144249 + * names of its contributors may be used to endorse or promote products
144250 + * derived from this software without specific prior written permission.
144251 + *
144252 + *
144253 + * ALTERNATIVELY, this software may be distributed under the terms of the
144254 + * GNU General Public License ("GPL") as published by the Free Software
144255 + * Foundation, either version 2 of that License or (at your option) any
144256 + * later version.
144257 + *
144258 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144259 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144260 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144261 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144262 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144263 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144264 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144265 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144266 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144267 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144268 + */
144269 +
144270 +#include <linux/kthread.h>
144271 +#include <linux/platform_device.h>
144272 +#include <linux/dma-mapping.h>
144273 +#include "qman_test.h"
144274 +
144275 +/* Algorithm:
144276 + *
144277 + * Each cpu will have HP_PER_CPU "handlers" set up, each of which incorporates
144278 + * an rx/tx pair of FQ objects (both of which are stashed on dequeue). The
144279 + * organisation of FQIDs is such that the HP_PER_CPU*NUM_CPUS handlers will
144280 + * shuttle a "hot potato" frame around them such that every forwarding action
144281 + * moves it from one cpu to another. (The use of more than one handler per cpu
144282 + * is to allow enough handlers/FQs to truly test the significance of caching -
144283 + * ie. when cache-expiries are occurring.)
144284 + *
144285 + * The "hot potato" frame content will be HP_NUM_WORDS*4 bytes in size, and the
144286 + * first and last words of the frame data will undergo a transformation step on
144287 + * each forwarding action. To achieve this, each handler will be assigned a
144288 + * 32-bit "mixer", that is produced using a 32-bit LFSR. When a frame is
144289 + * received by a handler, the mixer of the expected sender is XOR'd into all
144290 + * words of the entire frame, which is then validated against the original
144291 + * values. Then, before forwarding, the entire frame is XOR'd with the mixer of
144292 + * the current handler. Apart from validating that the frame is taking the
144293 + * expected path, this also provides some quasi-realistic overheads to each
144294 + * forwarding action - dereferencing *all* the frame data, computation, and
144295 + * conditional branching. There is a "special" handler designated to act as the
144296 + * instigator of the test by creating an enqueuing the "hot potato" frame, and
144297 + * to determine when the test has completed by counting HP_LOOPS iterations.
144298 + *
144299 + * Init phases:
144300 + *
144301 + * 1. prepare each cpu's 'hp_cpu' struct using on_each_cpu(,,1) and link them
144302 + * into 'hp_cpu_list'. Specifically, set processor_id, allocate HP_PER_CPU
144303 + * handlers and link-list them (but do no other handler setup).
144304 + *
144305 + * 2. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
144306 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
144307 + * allocate rx/tx FQIDs and mixer values to the hp_cpu's iterator handler
144308 + * and advance the iterator for the next loop. This includes a final fixup,
144309 + * which connects the last handler to the first (and which is why phase 2
144310 + * and 3 are separate).
144311 + *
144312 + * 3. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
144313 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
144314 + * initialise FQ objects and advance the iterator for the next loop.
144315 + * Moreover, do this initialisation on the cpu it applies to so that Rx FQ
144316 + * initialisation targets the correct cpu.
144317 + */
144318 +
144319 +/* helper to run something on all cpus (can't use on_each_cpu(), as that invokes
144320 + * the fn from irq context, which is too restrictive). */
144321 +struct bstrap {
144322 + void (*fn)(void);
144323 + atomic_t started;
144324 +};
144325 +static int bstrap_fn(void *__bstrap)
144326 +{
144327 + struct bstrap *bstrap = __bstrap;
144328 + atomic_inc(&bstrap->started);
144329 + bstrap->fn();
144330 + while (!kthread_should_stop())
144331 + msleep(1);
144332 + return 0;
144333 +}
144334 +static int on_all_cpus(void (*fn)(void))
144335 +{
144336 + int cpu;
144337 + for_each_cpu(cpu, cpu_online_mask) {
144338 + struct bstrap bstrap = {
144339 + .fn = fn,
144340 + .started = ATOMIC_INIT(0)
144341 + };
144342 + struct task_struct *k = kthread_create(bstrap_fn, &bstrap,
144343 + "hotpotato%d", cpu);
144344 + int ret;
144345 + if (IS_ERR(k))
144346 + return -ENOMEM;
144347 + kthread_bind(k, cpu);
144348 + wake_up_process(k);
144349 + /* If we call kthread_stop() before the "wake up" has had an
144350 + * effect, then the thread may exit with -EINTR without ever
144351 + * running the function. So poll until it's started before
144352 + * requesting it to stop. */
144353 + while (!atomic_read(&bstrap.started))
144354 + msleep(10);
144355 + ret = kthread_stop(k);
144356 + if (ret)
144357 + return ret;
144358 + }
144359 + return 0;
144360 +}
144361 +
144362 +struct hp_handler {
144363 +
144364 + /* The following data is stashed when 'rx' is dequeued; */
144365 + /* -------------- */
144366 + /* The Rx FQ, dequeues of which will stash the entire hp_handler */
144367 + struct qman_fq rx;
144368 + /* The Tx FQ we should forward to */
144369 + struct qman_fq tx;
144370 + /* The value we XOR post-dequeue, prior to validating */
144371 + u32 rx_mixer;
144372 + /* The value we XOR pre-enqueue, after validating */
144373 + u32 tx_mixer;
144374 + /* what the hotpotato address should be on dequeue */
144375 + dma_addr_t addr;
144376 + u32 *frame_ptr;
144377 +
144378 + /* The following data isn't (necessarily) stashed on dequeue; */
144379 + /* -------------- */
144380 + u32 fqid_rx, fqid_tx;
144381 + /* list node for linking us into 'hp_cpu' */
144382 + struct list_head node;
144383 + /* Just to check ... */
144384 + unsigned int processor_id;
144385 +} ____cacheline_aligned;
144386 +
144387 +struct hp_cpu {
144388 + /* identify the cpu we run on; */
144389 + unsigned int processor_id;
144390 + /* root node for the per-cpu list of handlers */
144391 + struct list_head handlers;
144392 + /* list node for linking us into 'hp_cpu_list' */
144393 + struct list_head node;
144394 + /* when repeatedly scanning 'hp_list', each time linking the n'th
144395 + * handlers together, this is used as per-cpu iterator state */
144396 + struct hp_handler *iterator;
144397 +};
144398 +
144399 +/* Each cpu has one of these */
144400 +static DEFINE_PER_CPU(struct hp_cpu, hp_cpus);
144401 +
144402 +/* links together the hp_cpu structs, in first-come first-serve order. */
144403 +static LIST_HEAD(hp_cpu_list);
144404 +static spinlock_t hp_lock = __SPIN_LOCK_UNLOCKED(hp_lock);
144405 +
144406 +static unsigned int hp_cpu_list_length;
144407 +
144408 +/* the "special" handler, that starts and terminates the test. */
144409 +static struct hp_handler *special_handler;
144410 +static int loop_counter;
144411 +
144412 +/* handlers are allocated out of this, so they're properly aligned. */
144413 +static struct kmem_cache *hp_handler_slab;
144414 +
144415 +/* this is the frame data */
144416 +static void *__frame_ptr;
144417 +static u32 *frame_ptr;
144418 +static dma_addr_t frame_dma;
144419 +
144420 +/* the main function waits on this */
144421 +static DECLARE_WAIT_QUEUE_HEAD(queue);
144422 +
144423 +#define HP_PER_CPU 2
144424 +#define HP_LOOPS 8
144425 +/* 80 bytes, like a small ethernet frame, and bleeds into a second cacheline */
144426 +#define HP_NUM_WORDS 80
144427 +/* First word of the LFSR-based frame data */
144428 +#define HP_FIRST_WORD 0xabbaf00d
144429 +
144430 +static inline u32 do_lfsr(u32 prev)
144431 +{
144432 + return (prev >> 1) ^ (-(prev & 1u) & 0xd0000001u);
144433 +}
144434 +
144435 +static void allocate_frame_data(void)
144436 +{
144437 + u32 lfsr = HP_FIRST_WORD;
144438 + int loop;
144439 + struct platform_device *pdev = platform_device_alloc("foobar", -1);
144440 + if (!pdev)
144441 + panic("platform_device_alloc() failed");
144442 + if (platform_device_add(pdev))
144443 + panic("platform_device_add() failed");
144444 + __frame_ptr = kmalloc(4 * HP_NUM_WORDS, GFP_KERNEL);
144445 + if (!__frame_ptr)
144446 + panic("kmalloc() failed");
144447 + frame_ptr = (void *)(((unsigned long)__frame_ptr + 63) &
144448 + ~(unsigned long)63);
144449 + for (loop = 0; loop < HP_NUM_WORDS; loop++) {
144450 + frame_ptr[loop] = lfsr;
144451 + lfsr = do_lfsr(lfsr);
144452 + }
144453 + frame_dma = dma_map_single(&pdev->dev, frame_ptr, 4 * HP_NUM_WORDS,
144454 + DMA_BIDIRECTIONAL);
144455 + platform_device_del(pdev);
144456 + platform_device_put(pdev);
144457 +}
144458 +
144459 +static void deallocate_frame_data(void)
144460 +{
144461 + kfree(__frame_ptr);
144462 +}
144463 +
144464 +static inline void process_frame_data(struct hp_handler *handler,
144465 + const struct qm_fd *fd)
144466 +{
144467 + u32 *p = handler->frame_ptr;
144468 + u32 lfsr = HP_FIRST_WORD;
144469 + int loop;
144470 + if (qm_fd_addr_get64(fd) != (handler->addr & 0xffffffffff)) {
144471 + pr_err("Got 0x%llx expected 0x%llx\n",
144472 + qm_fd_addr_get64(fd), handler->addr);
144473 + panic("bad frame address");
144474 + }
144475 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
144476 + *p ^= handler->rx_mixer;
144477 + if (*p != lfsr)
144478 + panic("corrupt frame data");
144479 + *p ^= handler->tx_mixer;
144480 + lfsr = do_lfsr(lfsr);
144481 + }
144482 +}
144483 +
144484 +static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal,
144485 + struct qman_fq *fq,
144486 + const struct qm_dqrr_entry *dqrr)
144487 +{
144488 + struct hp_handler *handler = (struct hp_handler *)fq;
144489 +
144490 + process_frame_data(handler, &dqrr->fd);
144491 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
144492 + panic("qman_enqueue() failed");
144493 + return qman_cb_dqrr_consume;
144494 +}
144495 +
144496 +static enum qman_cb_dqrr_result special_dqrr(struct qman_portal *portal,
144497 + struct qman_fq *fq,
144498 + const struct qm_dqrr_entry *dqrr)
144499 +{
144500 + struct hp_handler *handler = (struct hp_handler *)fq;
144501 +
144502 + process_frame_data(handler, &dqrr->fd);
144503 + if (++loop_counter < HP_LOOPS) {
144504 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
144505 + panic("qman_enqueue() failed");
144506 + } else {
144507 + pr_info("Received final (%dth) frame\n", loop_counter);
144508 + wake_up(&queue);
144509 + }
144510 + return qman_cb_dqrr_consume;
144511 +}
144512 +
144513 +static void create_per_cpu_handlers(void)
144514 +{
144515 + struct hp_handler *handler;
144516 + int loop;
144517 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
144518 +
144519 + hp_cpu->processor_id = smp_processor_id();
144520 + spin_lock(&hp_lock);
144521 + list_add_tail(&hp_cpu->node, &hp_cpu_list);
144522 + hp_cpu_list_length++;
144523 + spin_unlock(&hp_lock);
144524 + INIT_LIST_HEAD(&hp_cpu->handlers);
144525 + for (loop = 0; loop < HP_PER_CPU; loop++) {
144526 + handler = kmem_cache_alloc(hp_handler_slab, GFP_KERNEL);
144527 + if (!handler)
144528 + panic("kmem_cache_alloc() failed");
144529 + handler->processor_id = hp_cpu->processor_id;
144530 + handler->addr = frame_dma;
144531 + handler->frame_ptr = frame_ptr;
144532 + list_add_tail(&handler->node, &hp_cpu->handlers);
144533 + }
144534 + put_cpu_var(hp_cpus);
144535 +}
144536 +
144537 +static void destroy_per_cpu_handlers(void)
144538 +{
144539 + struct list_head *loop, *tmp;
144540 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
144541 +
144542 + spin_lock(&hp_lock);
144543 + list_del(&hp_cpu->node);
144544 + spin_unlock(&hp_lock);
144545 + list_for_each_safe(loop, tmp, &hp_cpu->handlers) {
144546 + u32 flags;
144547 + struct hp_handler *handler = list_entry(loop, struct hp_handler,
144548 + node);
144549 + if (qman_retire_fq(&handler->rx, &flags))
144550 + panic("qman_retire_fq(rx) failed");
144551 + BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS);
144552 + if (qman_oos_fq(&handler->rx))
144553 + panic("qman_oos_fq(rx) failed");
144554 + qman_destroy_fq(&handler->rx, 0);
144555 + qman_destroy_fq(&handler->tx, 0);
144556 + qman_release_fqid(handler->fqid_rx);
144557 + list_del(&handler->node);
144558 + kmem_cache_free(hp_handler_slab, handler);
144559 + }
144560 + put_cpu_var(hp_cpus);
144561 +}
144562 +
144563 +static inline u8 num_cachelines(u32 offset)
144564 +{
144565 + u8 res = (offset + (L1_CACHE_BYTES - 1))
144566 + / (L1_CACHE_BYTES);
144567 + if (res > 3)
144568 + return 3;
144569 + return res;
144570 +}
144571 +#define STASH_DATA_CL \
144572 + num_cachelines(HP_NUM_WORDS * 4)
144573 +#define STASH_CTX_CL \
144574 + num_cachelines(offsetof(struct hp_handler, fqid_rx))
144575 +
144576 +static void init_handler(void *__handler)
144577 +{
144578 + struct qm_mcc_initfq opts;
144579 + struct hp_handler *handler = __handler;
144580 + BUG_ON(handler->processor_id != smp_processor_id());
144581 + /* Set up rx */
144582 + memset(&handler->rx, 0, sizeof(handler->rx));
144583 + if (handler == special_handler)
144584 + handler->rx.cb.dqrr = special_dqrr;
144585 + else
144586 + handler->rx.cb.dqrr = normal_dqrr;
144587 + if (qman_create_fq(handler->fqid_rx, 0, &handler->rx))
144588 + panic("qman_create_fq(rx) failed");
144589 + memset(&opts, 0, sizeof(opts));
144590 + opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_CONTEXTA;
144591 + opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING;
144592 + opts.fqd.context_a.stashing.data_cl = STASH_DATA_CL;
144593 + opts.fqd.context_a.stashing.context_cl = STASH_CTX_CL;
144594 + if (qman_init_fq(&handler->rx, QMAN_INITFQ_FLAG_SCHED |
144595 + QMAN_INITFQ_FLAG_LOCAL, &opts))
144596 + panic("qman_init_fq(rx) failed");
144597 + /* Set up tx */
144598 + memset(&handler->tx, 0, sizeof(handler->tx));
144599 + if (qman_create_fq(handler->fqid_tx, QMAN_FQ_FLAG_NO_MODIFY,
144600 + &handler->tx))
144601 + panic("qman_create_fq(tx) failed");
144602 +}
144603 +
144604 +static void init_phase2(void)
144605 +{
144606 + int loop;
144607 + u32 fqid = 0;
144608 + u32 lfsr = 0xdeadbeef;
144609 + struct hp_cpu *hp_cpu;
144610 + struct hp_handler *handler;
144611 +
144612 + for (loop = 0; loop < HP_PER_CPU; loop++) {
144613 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
144614 + int ret;
144615 + if (!loop)
144616 + hp_cpu->iterator = list_first_entry(
144617 + &hp_cpu->handlers,
144618 + struct hp_handler, node);
144619 + else
144620 + hp_cpu->iterator = list_entry(
144621 + hp_cpu->iterator->node.next,
144622 + struct hp_handler, node);
144623 + /* Rx FQID is the previous handler's Tx FQID */
144624 + hp_cpu->iterator->fqid_rx = fqid;
144625 + /* Allocate new FQID for Tx */
144626 + ret = qman_alloc_fqid(&fqid);
144627 + if (ret)
144628 + panic("qman_alloc_fqid() failed");
144629 + hp_cpu->iterator->fqid_tx = fqid;
144630 + /* Rx mixer is the previous handler's Tx mixer */
144631 + hp_cpu->iterator->rx_mixer = lfsr;
144632 + /* Get new mixer for Tx */
144633 + lfsr = do_lfsr(lfsr);
144634 + hp_cpu->iterator->tx_mixer = lfsr;
144635 + }
144636 + }
144637 + /* Fix up the first handler (fqid_rx==0, rx_mixer=0xdeadbeef) */
144638 + hp_cpu = list_first_entry(&hp_cpu_list, struct hp_cpu, node);
144639 + handler = list_first_entry(&hp_cpu->handlers, struct hp_handler, node);
144640 + BUG_ON((handler->fqid_rx != 0) || (handler->rx_mixer != 0xdeadbeef));
144641 + handler->fqid_rx = fqid;
144642 + handler->rx_mixer = lfsr;
144643 + /* and tag it as our "special" handler */
144644 + special_handler = handler;
144645 +}
144646 +
144647 +static void init_phase3(void)
144648 +{
144649 + int loop;
144650 + struct hp_cpu *hp_cpu;
144651 +
144652 + for (loop = 0; loop < HP_PER_CPU; loop++) {
144653 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
144654 + if (!loop)
144655 + hp_cpu->iterator = list_first_entry(
144656 + &hp_cpu->handlers,
144657 + struct hp_handler, node);
144658 + else
144659 + hp_cpu->iterator = list_entry(
144660 + hp_cpu->iterator->node.next,
144661 + struct hp_handler, node);
144662 + preempt_disable();
144663 + if (hp_cpu->processor_id == smp_processor_id())
144664 + init_handler(hp_cpu->iterator);
144665 + else
144666 + smp_call_function_single(hp_cpu->processor_id,
144667 + init_handler, hp_cpu->iterator, 1);
144668 + preempt_enable();
144669 + }
144670 + }
144671 +}
144672 +
144673 +static void send_first_frame(void *ignore)
144674 +{
144675 + u32 *p = special_handler->frame_ptr;
144676 + u32 lfsr = HP_FIRST_WORD;
144677 + int loop;
144678 + struct qm_fd fd;
144679 +
144680 + BUG_ON(special_handler->processor_id != smp_processor_id());
144681 + memset(&fd, 0, sizeof(fd));
144682 + qm_fd_addr_set64(&fd, special_handler->addr);
144683 + fd.format = qm_fd_contig_big;
144684 + fd.length29 = HP_NUM_WORDS * 4;
144685 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
144686 + if (*p != lfsr)
144687 + panic("corrupt frame data");
144688 + *p ^= special_handler->tx_mixer;
144689 + lfsr = do_lfsr(lfsr);
144690 + }
144691 + pr_info("Sending first frame\n");
144692 + if (qman_enqueue(&special_handler->tx, &fd, 0))
144693 + panic("qman_enqueue() failed");
144694 +}
144695 +
144696 +void qman_test_hotpotato(void)
144697 +{
144698 + if (cpumask_weight(cpu_online_mask) < 2) {
144699 + pr_info("qman_test_hotpotato, skip - only 1 CPU\n");
144700 + return;
144701 + }
144702 +
144703 + pr_info("qman_test_hotpotato starting\n");
144704 +
144705 + hp_cpu_list_length = 0;
144706 + loop_counter = 0;
144707 + hp_handler_slab = kmem_cache_create("hp_handler_slab",
144708 + sizeof(struct hp_handler), L1_CACHE_BYTES,
144709 + SLAB_HWCACHE_ALIGN, NULL);
144710 + if (!hp_handler_slab)
144711 + panic("kmem_cache_create() failed");
144712 +
144713 + allocate_frame_data();
144714 +
144715 + /* Init phase 1 */
144716 + pr_info("Creating %d handlers per cpu...\n", HP_PER_CPU);
144717 + if (on_all_cpus(create_per_cpu_handlers))
144718 + panic("on_each_cpu() failed");
144719 + pr_info("Number of cpus: %d, total of %d handlers\n",
144720 + hp_cpu_list_length, hp_cpu_list_length * HP_PER_CPU);
144721 +
144722 + init_phase2();
144723 +
144724 + init_phase3();
144725 +
144726 + preempt_disable();
144727 + if (special_handler->processor_id == smp_processor_id())
144728 + send_first_frame(NULL);
144729 + else
144730 + smp_call_function_single(special_handler->processor_id,
144731 + send_first_frame, NULL, 1);
144732 + preempt_enable();
144733 +
144734 + wait_event(queue, loop_counter == HP_LOOPS);
144735 + deallocate_frame_data();
144736 + if (on_all_cpus(destroy_per_cpu_handlers))
144737 + panic("on_each_cpu() failed");
144738 + kmem_cache_destroy(hp_handler_slab);
144739 + pr_info("qman_test_hotpotato finished\n");
144740 +}
144741 diff --git a/drivers/staging/fsl_qbman/qman_utility.c b/drivers/staging/fsl_qbman/qman_utility.c
144742 new file mode 100644
144743 index 00000000..f1e39023
144744 --- /dev/null
144745 +++ b/drivers/staging/fsl_qbman/qman_utility.c
144746 @@ -0,0 +1,129 @@
144747 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
144748 + *
144749 + * Redistribution and use in source and binary forms, with or without
144750 + * modification, are permitted provided that the following conditions are met:
144751 + * * Redistributions of source code must retain the above copyright
144752 + * notice, this list of conditions and the following disclaimer.
144753 + * * Redistributions in binary form must reproduce the above copyright
144754 + * notice, this list of conditions and the following disclaimer in the
144755 + * documentation and/or other materials provided with the distribution.
144756 + * * Neither the name of Freescale Semiconductor nor the
144757 + * names of its contributors may be used to endorse or promote products
144758 + * derived from this software without specific prior written permission.
144759 + *
144760 + *
144761 + * ALTERNATIVELY, this software may be distributed under the terms of the
144762 + * GNU General Public License ("GPL") as published by the Free Software
144763 + * Foundation, either version 2 of that License or (at your option) any
144764 + * later version.
144765 + *
144766 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144767 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144768 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144769 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144770 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144771 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144772 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144773 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144774 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144775 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144776 + */
144777 +
144778 +#include "qman_private.h"
144779 +
144780 +/* ----------------- */
144781 +/* --- FQID Pool --- */
144782 +
144783 +struct qman_fqid_pool {
144784 + /* Base and size of the FQID range */
144785 + u32 fqid_base;
144786 + u32 total;
144787 + /* Number of FQIDs currently "allocated" */
144788 + u32 used;
144789 + /* Allocation optimisation. When 'used<total', it is the index of an
144790 + * available FQID. Otherwise there are no available FQIDs, and this
144791 + * will be set when the next deallocation occurs. */
144792 + u32 next;
144793 + /* A bit-field representation of the FQID range. */
144794 + unsigned long *bits;
144795 +};
144796 +
144797 +#define QLONG_BYTES sizeof(unsigned long)
144798 +#define QLONG_BITS (QLONG_BYTES * 8)
144799 +/* Number of 'longs' required for the given number of bits */
144800 +#define QNUM_LONGS(b) (((b) + QLONG_BITS - 1) / QLONG_BITS)
144801 +/* Shorthand for the number of bytes of same (kmalloc, memset, etc) */
144802 +#define QNUM_BYTES(b) (QNUM_LONGS(b) * QLONG_BYTES)
144803 +/* And in bits */
144804 +#define QNUM_BITS(b) (QNUM_LONGS(b) * QLONG_BITS)
144805 +
144806 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num)
144807 +{
144808 + struct qman_fqid_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
144809 + unsigned int i;
144810 +
144811 + BUG_ON(!num);
144812 + if (!pool)
144813 + return NULL;
144814 + pool->fqid_base = fqid_start;
144815 + pool->total = num;
144816 + pool->used = 0;
144817 + pool->next = 0;
144818 + pool->bits = kzalloc(QNUM_BYTES(num), GFP_KERNEL);
144819 + if (!pool->bits) {
144820 + kfree(pool);
144821 + return NULL;
144822 + }
144823 + /* If num is not an even multiple of QLONG_BITS (or even 8, for
144824 + * byte-oriented searching) then we fill the trailing bits with 1, to
144825 + * make them look allocated (permanently). */
144826 + for (i = num + 1; i < QNUM_BITS(num); i++)
144827 + set_bit(i, pool->bits);
144828 + return pool;
144829 +}
144830 +EXPORT_SYMBOL(qman_fqid_pool_create);
144831 +
144832 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool)
144833 +{
144834 + int ret = pool->used;
144835 + kfree(pool->bits);
144836 + kfree(pool);
144837 + return ret;
144838 +}
144839 +EXPORT_SYMBOL(qman_fqid_pool_destroy);
144840 +
144841 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid)
144842 +{
144843 + int ret;
144844 + if (pool->used == pool->total)
144845 + return -ENOMEM;
144846 + *fqid = pool->fqid_base + pool->next;
144847 + ret = test_and_set_bit(pool->next, pool->bits);
144848 + BUG_ON(ret);
144849 + if (++pool->used == pool->total)
144850 + return 0;
144851 + pool->next = find_next_zero_bit(pool->bits, pool->total, pool->next);
144852 + if (pool->next >= pool->total)
144853 + pool->next = find_first_zero_bit(pool->bits, pool->total);
144854 + BUG_ON(pool->next >= pool->total);
144855 + return 0;
144856 +}
144857 +EXPORT_SYMBOL(qman_fqid_pool_alloc);
144858 +
144859 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid)
144860 +{
144861 + int ret;
144862 +
144863 + fqid -= pool->fqid_base;
144864 + ret = test_and_clear_bit(fqid, pool->bits);
144865 + BUG_ON(!ret);
144866 + if (pool->used-- == pool->total)
144867 + pool->next = fqid;
144868 +}
144869 +EXPORT_SYMBOL(qman_fqid_pool_free);
144870 +
144871 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool)
144872 +{
144873 + return pool->used;
144874 +}
144875 +EXPORT_SYMBOL(qman_fqid_pool_used);
144876 diff --git a/include/linux/fsl_bman.h b/include/linux/fsl_bman.h
144877 new file mode 100644
144878 index 00000000..43942221
144879 --- /dev/null
144880 +++ b/include/linux/fsl_bman.h
144881 @@ -0,0 +1,532 @@
144882 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144883 + *
144884 + * Redistribution and use in source and binary forms, with or without
144885 + * modification, are permitted provided that the following conditions are met:
144886 + * * Redistributions of source code must retain the above copyright
144887 + * notice, this list of conditions and the following disclaimer.
144888 + * * Redistributions in binary form must reproduce the above copyright
144889 + * notice, this list of conditions and the following disclaimer in the
144890 + * documentation and/or other materials provided with the distribution.
144891 + * * Neither the name of Freescale Semiconductor nor the
144892 + * names of its contributors may be used to endorse or promote products
144893 + * derived from this software without specific prior written permission.
144894 + *
144895 + *
144896 + * ALTERNATIVELY, this software may be distributed under the terms of the
144897 + * GNU General Public License ("GPL") as published by the Free Software
144898 + * Foundation, either version 2 of that License or (at your option) any
144899 + * later version.
144900 + *
144901 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144902 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144903 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144904 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144905 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144906 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144907 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144908 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144909 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144910 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144911 + */
144912 +
144913 +#ifndef FSL_BMAN_H
144914 +#define FSL_BMAN_H
144915 +
144916 +#ifdef __cplusplus
144917 +extern "C" {
144918 +#endif
144919 +
144920 +/* Last updated for v00.79 of the BG */
144921 +
144922 +/* Portal processing (interrupt) sources */
144923 +#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */
144924 +#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */
144925 +
144926 +/* This wrapper represents a bit-array for the depletion state of the 64 Bman
144927 + * buffer pools. */
144928 +struct bman_depletion {
144929 + u32 __state[2];
144930 +};
144931 +#define BMAN_DEPLETION_EMPTY { { 0x00000000, 0x00000000 } }
144932 +#define BMAN_DEPLETION_FULL { { 0xffffffff, 0xffffffff } }
144933 +#define __bmdep_word(x) ((x) >> 5)
144934 +#define __bmdep_shift(x) ((x) & 0x1f)
144935 +#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x))
144936 +static inline void bman_depletion_init(struct bman_depletion *c)
144937 +{
144938 + c->__state[0] = c->__state[1] = 0;
144939 +}
144940 +static inline void bman_depletion_fill(struct bman_depletion *c)
144941 +{
144942 + c->__state[0] = c->__state[1] = ~0;
144943 +}
144944 +static inline int bman_depletion_get(const struct bman_depletion *c, u8 bpid)
144945 +{
144946 + return c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid);
144947 +}
144948 +static inline void bman_depletion_set(struct bman_depletion *c, u8 bpid)
144949 +{
144950 + c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid);
144951 +}
144952 +static inline void bman_depletion_unset(struct bman_depletion *c, u8 bpid)
144953 +{
144954 + c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid);
144955 +}
144956 +
144957 +/* ------------------------------------------------------- */
144958 +/* --- Bman data structures (and associated constants) --- */
144959 +
144960 +/* Represents s/w corenet portal mapped data structures */
144961 +struct bm_rcr_entry; /* RCR (Release Command Ring) entries */
144962 +struct bm_mc_command; /* MC (Management Command) command */
144963 +struct bm_mc_result; /* MC result */
144964 +
144965 +/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer
144966 + * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
144967 + * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */
144968 +struct bm_buffer {
144969 + union {
144970 + struct {
144971 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144972 + u8 __reserved1;
144973 + u8 bpid;
144974 + u16 hi; /* High 16-bits of 48-bit address */
144975 + u32 lo; /* Low 32-bits of 48-bit address */
144976 +#else
144977 + u32 lo;
144978 + u16 hi;
144979 + u8 bpid;
144980 + u8 __reserved;
144981 +#endif
144982 + };
144983 + struct {
144984 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144985 + u64 __notaddress:16;
144986 + u64 addr:48;
144987 +#else
144988 + u64 addr:48;
144989 + u64 __notaddress:16;
144990 +#endif
144991 + };
144992 + u64 opaque;
144993 + };
144994 +} __aligned(8);
144995 +static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
144996 +{
144997 + return buf->addr;
144998 +}
144999 +static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
145000 +{
145001 + return (dma_addr_t)buf->addr;
145002 +}
145003 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145004 +#define bm_buffer_set64(buf, v) \
145005 + do { \
145006 + struct bm_buffer *__buf931 = (buf); \
145007 + __buf931->hi = upper_32_bits(v); \
145008 + __buf931->lo = lower_32_bits(v); \
145009 + } while (0)
145010 +
145011 +/* See 1.5.3.5.4: "Release Command" */
145012 +struct bm_rcr_entry {
145013 + union {
145014 + struct {
145015 + u8 __dont_write_directly__verb;
145016 + u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
145017 + u8 __reserved1[62];
145018 + };
145019 + struct bm_buffer bufs[8];
145020 + };
145021 +} __packed;
145022 +#define BM_RCR_VERB_VBIT 0x80
145023 +#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */
145024 +#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20
145025 +#define BM_RCR_VERB_CMD_BPID_MULTI 0x30
145026 +#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */
145027 +
145028 +/* See 1.5.3.1: "Acquire Command" */
145029 +/* See 1.5.3.2: "Query Command" */
145030 +struct bm_mcc_acquire {
145031 + u8 bpid;
145032 + u8 __reserved1[62];
145033 +} __packed;
145034 +struct bm_mcc_query {
145035 + u8 __reserved2[63];
145036 +} __packed;
145037 +struct bm_mc_command {
145038 + u8 __dont_write_directly__verb;
145039 + union {
145040 + struct bm_mcc_acquire acquire;
145041 + struct bm_mcc_query query;
145042 + };
145043 +} __packed;
145044 +#define BM_MCC_VERB_VBIT 0x80
145045 +#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */
145046 +#define BM_MCC_VERB_CMD_ACQUIRE 0x10
145047 +#define BM_MCC_VERB_CMD_QUERY 0x40
145048 +#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */
145049 +
145050 +/* See 1.5.3.3: "Acquire Response" */
145051 +/* See 1.5.3.4: "Query Response" */
145052 +struct bm_pool_state {
145053 + u8 __reserved1[32];
145054 + /* "availability state" and "depletion state" */
145055 + struct {
145056 + u8 __reserved1[8];
145057 + /* Access using bman_depletion_***() */
145058 + struct bman_depletion state;
145059 + } as, ds;
145060 +};
145061 +struct bm_mc_result {
145062 + union {
145063 + struct {
145064 + u8 verb;
145065 + u8 __reserved1[63];
145066 + };
145067 + union {
145068 + struct {
145069 + u8 __reserved1;
145070 + u8 bpid;
145071 + u8 __reserved2[62];
145072 + };
145073 + struct bm_buffer bufs[8];
145074 + } acquire;
145075 + struct bm_pool_state query;
145076 + };
145077 +} __packed;
145078 +#define BM_MCR_VERB_VBIT 0x80
145079 +#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK
145080 +#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE
145081 +#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY
145082 +#define BM_MCR_VERB_CMD_ERR_INVALID 0x60
145083 +#define BM_MCR_VERB_CMD_ERR_ECC 0x70
145084 +#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */
145085 +/* Determine the "availability state" of pool 'p' from a query result 'r' */
145086 +#define BM_MCR_QUERY_AVAILABILITY(r, p) \
145087 + bman_depletion_get(&r->query.as.state, p)
145088 +/* Determine the "depletion state" of pool 'p' from a query result 'r' */
145089 +#define BM_MCR_QUERY_DEPLETION(r, p) \
145090 + bman_depletion_get(&r->query.ds.state, p)
145091 +
145092 +/*******************************************************************/
145093 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
145094 +/*******************************************************************/
145095 +
145096 + /* Portal and Buffer Pools */
145097 + /* ----------------------- */
145098 +/* Represents a managed portal */
145099 +struct bman_portal;
145100 +
145101 +/* This object type represents Bman buffer pools. */
145102 +struct bman_pool;
145103 +
145104 +struct bman_portal_config {
145105 + /* This is used for any "core-affine" portals, ie. default portals
145106 + * associated to the corresponding cpu. -1 implies that there is no core
145107 + * affinity configured. */
145108 + int cpu;
145109 + /* portal interrupt line */
145110 + int irq;
145111 + /* the unique index of this portal */
145112 + u32 index;
145113 + /* Is this portal shared? (If so, it has coarser locking and demuxes
145114 + * processing on behalf of other CPUs.) */
145115 + int is_shared;
145116 + /* These are the buffer pool IDs that may be used via this portal. */
145117 + struct bman_depletion mask;
145118 +};
145119 +
145120 +/* This callback type is used when handling pool depletion entry/exit. The
145121 + * 'cb_ctx' value is the opaque value associated with the pool object in
145122 + * bman_new_pool(). 'depleted' is non-zero on depletion-entry, and zero on
145123 + * depletion-exit. */
145124 +typedef void (*bman_cb_depletion)(struct bman_portal *bm,
145125 + struct bman_pool *pool, void *cb_ctx, int depleted);
145126 +
145127 +/* This struct specifies parameters for a bman_pool object. */
145128 +struct bman_pool_params {
145129 + /* index of the buffer pool to encapsulate (0-63), ignored if
145130 + * BMAN_POOL_FLAG_DYNAMIC_BPID is set. */
145131 + u32 bpid;
145132 + /* bit-mask of BMAN_POOL_FLAG_*** options */
145133 + u32 flags;
145134 + /* depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */
145135 + bman_cb_depletion cb;
145136 + /* opaque user value passed as a parameter to 'cb' */
145137 + void *cb_ctx;
145138 + /* depletion-entry/exit thresholds, if BMAN_POOL_FLAG_THRESH is set. NB:
145139 + * this is only allowed if BMAN_POOL_FLAG_DYNAMIC_BPID is used *and*
145140 + * when run in the control plane (which controls Bman CCSR). This array
145141 + * matches the definition of bm_pool_set(). */
145142 + u32 thresholds[4];
145143 +};
145144 +
145145 +/* Flags to bman_new_pool() */
145146 +#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */
145147 +#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */
145148 +#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */
145149 +#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */
145150 +#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */
145151 +#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */
145152 +
145153 +/* Flags to bman_release() */
145154 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
145155 +#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */
145156 +#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */
145157 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
145158 +#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
145159 +#endif
145160 +#endif
145161 +#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */
145162 +
145163 +/* Flags to bman_acquire() */
145164 +#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */
145165 +
145166 + /* Portal Management */
145167 + /* ----------------- */
145168 +/**
145169 + * bman_get_portal_config - get portal configuration settings
145170 + *
145171 + * This returns a read-only view of the current cpu's affine portal settings.
145172 + */
145173 +const struct bman_portal_config *bman_get_portal_config(void);
145174 +
145175 +/**
145176 + * bman_irqsource_get - return the portal work that is interrupt-driven
145177 + *
145178 + * Returns a bitmask of BM_PIRQ_**I processing sources that are currently
145179 + * enabled for interrupt handling on the current cpu's affine portal. These
145180 + * sources will trigger the portal interrupt and the interrupt handler (or a
145181 + * tasklet/bottom-half it defers to) will perform the corresponding processing
145182 + * work. The bman_poll_***() functions will only process sources that are not in
145183 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
145184 + * this always returns zero.
145185 + */
145186 +u32 bman_irqsource_get(void);
145187 +
145188 +/**
145189 + * bman_irqsource_add - add processing sources to be interrupt-driven
145190 + * @bits: bitmask of BM_PIRQ_**I processing sources
145191 + *
145192 + * Adds processing sources that should be interrupt-driven (rather than
145193 + * processed via bman_poll_***() functions). Returns zero for success, or
145194 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
145195 +int bman_irqsource_add(u32 bits);
145196 +
145197 +/**
145198 + * bman_irqsource_remove - remove processing sources from being interrupt-driven
145199 + * @bits: bitmask of BM_PIRQ_**I processing sources
145200 + *
145201 + * Removes processing sources from being interrupt-driven, so that they will
145202 + * instead be processed via bman_poll_***() functions. Returns zero for success,
145203 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
145204 +int bman_irqsource_remove(u32 bits);
145205 +
145206 +/**
145207 + * bman_affine_cpus - return a mask of cpus that have affine portals
145208 + */
145209 +const cpumask_t *bman_affine_cpus(void);
145210 +
145211 +/**
145212 + * bman_poll_slow - process anything that isn't interrupt-driven.
145213 + *
145214 + * This function does any portal processing that isn't interrupt-driven. If the
145215 + * current CPU is sharing a portal hosted on another CPU, this function will
145216 + * return -EINVAL, otherwise the return value is a bitmask of BM_PIRQ_* sources
145217 + * indicating what interrupt sources were actually processed by the call.
145218 + *
145219 + * NB, unlike the legacy wrapper bman_poll(), this function will
145220 + * deterministically check for the presence of portal processing work and do it,
145221 + * which implies some latency even if there's nothing to do. The bman_poll()
145222 + * wrapper on the other hand (like the qman_poll() wrapper) attenuates this by
145223 + * checking for (and doing) portal processing infrequently. Ie. such that
145224 + * qman_poll() and bman_poll() can be called from core-processing loops. Use
145225 + * bman_poll_slow() when you yourself are deciding when to incur the overhead of
145226 + * processing.
145227 + */
145228 +u32 bman_poll_slow(void);
145229 +
145230 +/**
145231 + * bman_poll - process anything that isn't interrupt-driven.
145232 + *
145233 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
145234 + * affine portal. This function does whatever processing is not triggered by
145235 + * interrupts. This is a legacy wrapper that can be used in core-processing
145236 + * loops but mitigates the performance overhead of portal processing by
145237 + * adaptively bypassing true portal processing most of the time. (Processing is
145238 + * done once every 10 calls if the previous processing revealed that work needed
145239 + * to be done, or once very 1000 calls if the previous processing revealed no
145240 + * work needed doing.) If you wish to control this yourself, call
145241 + * bman_poll_slow() instead, which always checks for portal processing work.
145242 + */
145243 +void bman_poll(void);
145244 +
145245 +/**
145246 + * bman_rcr_is_empty - Determine if portal's RCR is empty
145247 + *
145248 + * For use in situations where a cpu-affine caller needs to determine when all
145249 + * releases for the local portal have been processed by Bman but can't use the
145250 + * BMAN_RELEASE_FLAG_WAIT_SYNC flag to do this from the final bman_release().
145251 + * The function forces tracking of RCR consumption (which normally doesn't
145252 + * happen until release processing needs to find space to put new release
145253 + * commands), and returns zero if the ring still has unprocessed entries,
145254 + * non-zero if it is empty.
145255 + */
145256 +int bman_rcr_is_empty(void);
145257 +
145258 +/**
145259 + * bman_alloc_bpid_range - Allocate a contiguous range of BPIDs
145260 + * @result: is set by the API to the base BPID of the allocated range
145261 + * @count: the number of BPIDs required
145262 + * @align: required alignment of the allocated range
145263 + * @partial: non-zero if the API can return fewer than @count BPIDs
145264 + *
145265 + * Returns the number of buffer pools allocated, or a negative error code. If
145266 + * @partial is non zero, the allocation request may return a smaller range of
145267 + * BPs than requested (though alignment will be as requested). If @partial is
145268 + * zero, the return value will either be 'count' or negative.
145269 + */
145270 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial);
145271 +static inline int bman_alloc_bpid(u32 *result)
145272 +{
145273 + int ret = bman_alloc_bpid_range(result, 1, 0, 0);
145274 + return (ret > 0) ? 0 : ret;
145275 +}
145276 +
145277 +/**
145278 + * bman_release_bpid_range - Release the specified range of buffer pool IDs
145279 + * @bpid: the base BPID of the range to deallocate
145280 + * @count: the number of BPIDs in the range
145281 + *
145282 + * This function can also be used to seed the allocator with ranges of BPIDs
145283 + * that it can subsequently allocate from.
145284 + */
145285 +void bman_release_bpid_range(u32 bpid, unsigned int count);
145286 +static inline void bman_release_bpid(u32 bpid)
145287 +{
145288 + bman_release_bpid_range(bpid, 1);
145289 +}
145290 +
145291 +int bman_reserve_bpid_range(u32 bpid, unsigned int count);
145292 +static inline int bman_reserve_bpid(u32 bpid)
145293 +{
145294 + return bman_reserve_bpid_range(bpid, 1);
145295 +}
145296 +
145297 +void bman_seed_bpid_range(u32 bpid, unsigned int count);
145298 +
145299 +
145300 +int bman_shutdown_pool(u32 bpid);
145301 +
145302 + /* Pool management */
145303 + /* --------------- */
145304 +/**
145305 + * bman_new_pool - Allocates a Buffer Pool object
145306 + * @params: parameters specifying the buffer pool ID and behaviour
145307 + *
145308 + * Creates a pool object for the given @params. A portal and the depletion
145309 + * callback field of @params are only used if the BMAN_POOL_FLAG_DEPLETION flag
145310 + * is set. NB, the fields from @params are copied into the new pool object, so
145311 + * the structure provided by the caller can be released or reused after the
145312 + * function returns.
145313 + */
145314 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
145315 +
145316 +/**
145317 + * bman_free_pool - Deallocates a Buffer Pool object
145318 + * @pool: the pool object to release
145319 + *
145320 + */
145321 +void bman_free_pool(struct bman_pool *pool);
145322 +
145323 +/**
145324 + * bman_get_params - Returns a pool object's parameters.
145325 + * @pool: the pool object
145326 + *
145327 + * The returned pointer refers to state within the pool object so must not be
145328 + * modified and can no longer be read once the pool object is destroyed.
145329 + */
145330 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool);
145331 +
145332 +/**
145333 + * bman_release - Release buffer(s) to the buffer pool
145334 + * @pool: the buffer pool object to release to
145335 + * @bufs: an array of buffers to release
145336 + * @num: the number of buffers in @bufs (1-8)
145337 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
145338 + *
145339 + * Adds the given buffers to RCR entries. If the portal @p was created with the
145340 + * "COMPACT" flag, then it will be using a compaction algorithm to improve
145341 + * utilisation of RCR. As such, these buffers may join an existing ring entry
145342 + * and/or it may not be issued right away so as to allow future releases to join
145343 + * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
145344 + * behaviour by committing the RCR entry (or entries) right away. If the RCR
145345 + * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
145346 + * is selected, in which case it will sleep waiting for space to become
145347 + * available in RCR. If the function receives a signal before such time (and
145348 + * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
145349 + * it returns zero.
145350 + */
145351 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
145352 + u32 flags);
145353 +
145354 +/**
145355 + * bman_acquire - Acquire buffer(s) from a buffer pool
145356 + * @pool: the buffer pool object to acquire from
145357 + * @bufs: array for storing the acquired buffers
145358 + * @num: the number of buffers desired (@bufs is at least this big)
145359 + *
145360 + * Issues an "Acquire" command via the portal's management command interface.
145361 + * The return value will be the number of buffers obtained from the pool, or a
145362 + * negative error code if a h/w error or pool starvation was encountered. In
145363 + * the latter case, the content of @bufs is undefined.
145364 + */
145365 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
145366 + u32 flags);
145367 +
145368 +/**
145369 + * bman_flush_stockpile - Flush stockpile buffer(s) to the buffer pool
145370 + * @pool: the buffer pool object the stockpile belongs
145371 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
145372 + *
145373 + * Adds stockpile buffers to RCR entries until the stockpile is empty.
145374 + * The return value will be a negative error code if a h/w error occurred.
145375 + * If BMAN_RELEASE_FLAG_NOW flag is passed and RCR ring is full,
145376 + * -EAGAIN will be returned.
145377 + */
145378 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags);
145379 +
145380 +/**
145381 + * bman_query_pools - Query all buffer pool states
145382 + * @state: storage for the queried availability and depletion states
145383 + */
145384 +int bman_query_pools(struct bm_pool_state *state);
145385 +
145386 +#ifdef CONFIG_FSL_BMAN_CONFIG
145387 +/**
145388 + * bman_query_free_buffers - Query how many free buffers are in buffer pool
145389 + * @pool: the buffer pool object to query
145390 + *
145391 + * Return the number of the free buffers
145392 + */
145393 +u32 bman_query_free_buffers(struct bman_pool *pool);
145394 +
145395 +/**
145396 + * bman_update_pool_thresholds - Change the buffer pool's depletion thresholds
145397 + * @pool: the buffer pool object to which the thresholds will be set
145398 + * @thresholds: the new thresholds
145399 + */
145400 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds);
145401 +#endif
145402 +
145403 +/**
145404 + * The below bman_p_***() variant might be called in a situation that the cpu
145405 + * which the portal affine to is not online yet.
145406 + * @bman_portal specifies which portal the API will use.
145407 +*/
145408 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits);
145409 +#ifdef __cplusplus
145410 +}
145411 +#endif
145412 +
145413 +#endif /* FSL_BMAN_H */
145414 diff --git a/include/linux/fsl_qman.h b/include/linux/fsl_qman.h
145415 new file mode 100644
145416 index 00000000..4e4b21d5
145417 --- /dev/null
145418 +++ b/include/linux/fsl_qman.h
145419 @@ -0,0 +1,3888 @@
145420 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
145421 + *
145422 + * Redistribution and use in source and binary forms, with or without
145423 + * modification, are permitted provided that the following conditions are met:
145424 + * * Redistributions of source code must retain the above copyright
145425 + * notice, this list of conditions and the following disclaimer.
145426 + * * Redistributions in binary form must reproduce the above copyright
145427 + * notice, this list of conditions and the following disclaimer in the
145428 + * documentation and/or other materials provided with the distribution.
145429 + * * Neither the name of Freescale Semiconductor nor the
145430 + * names of its contributors may be used to endorse or promote products
145431 + * derived from this software without specific prior written permission.
145432 + *
145433 + *
145434 + * ALTERNATIVELY, this software may be distributed under the terms of the
145435 + * GNU General Public License ("GPL") as published by the Free Software
145436 + * Foundation, either version 2 of that License or (at your option) any
145437 + * later version.
145438 + *
145439 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
145440 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145441 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145442 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
145443 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
145444 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
145445 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
145446 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
145447 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145448 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145449 + */
145450 +
145451 +#ifndef FSL_QMAN_H
145452 +#define FSL_QMAN_H
145453 +
145454 +#ifdef __cplusplus
145455 +extern "C" {
145456 +#endif
145457 +
145458 +/* Last updated for v00.800 of the BG */
145459 +
145460 +/* Hardware constants */
145461 +#define QM_CHANNEL_SWPORTAL0 0
145462 +#define QMAN_CHANNEL_POOL1 0x21
145463 +#define QMAN_CHANNEL_CAAM 0x80
145464 +#define QMAN_CHANNEL_PME 0xa0
145465 +#define QMAN_CHANNEL_POOL1_REV3 0x401
145466 +#define QMAN_CHANNEL_CAAM_REV3 0x840
145467 +#define QMAN_CHANNEL_PME_REV3 0x860
145468 +#define QMAN_CHANNEL_DCE 0x8a0
145469 +#define QMAN_CHANNEL_DCE_QMANREV312 0x880
145470 +extern u16 qm_channel_pool1;
145471 +extern u16 qm_channel_caam;
145472 +extern u16 qm_channel_pme;
145473 +extern u16 qm_channel_dce;
145474 +enum qm_dc_portal {
145475 + qm_dc_portal_fman0 = 0,
145476 + qm_dc_portal_fman1 = 1,
145477 + qm_dc_portal_caam = 2,
145478 + qm_dc_portal_pme = 3,
145479 + qm_dc_portal_rman = 4,
145480 + qm_dc_portal_dce = 5
145481 +};
145482 +
145483 +/* Portal processing (interrupt) sources */
145484 +#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */
145485 +#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */
145486 +#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */
145487 +#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */
145488 +#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */
145489 +#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */
145490 +/* This mask contains all the interrupt sources that need handling except DQRI,
145491 + * ie. that if present should trigger slow-path processing. */
145492 +#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \
145493 + QM_PIRQ_MRI | QM_PIRQ_CCSCI)
145494 +
145495 +/* --- Clock speed --- */
145496 +/* A qman driver instance may or may not know the current qman clock speed.
145497 + * However, certain CEETM calculations may not be possible if this is not known.
145498 + * The 'set' function will only succeed (return zero) if the driver did not
145499 + * already know the clock speed. Likewise, the 'get' function will only succeed
145500 + * if the driver does know the clock speed (either because it knew when booting,
145501 + * or was told via 'set'). In cases where software is running on a driver
145502 + * instance that does not know the clock speed (eg. on a hypervised data-plane),
145503 + * and the user can obtain the current qman clock speed by other means (eg. from
145504 + * a message sent from the control-plane), then the 'set' function can be used
145505 + * to enable rate-calculations in a driver where it would otherwise not be
145506 + * possible. */
145507 +int qm_get_clock(u64 *clock_hz);
145508 +int qm_set_clock(u64 clock_hz);
145509 +
145510 +/* For qman_static_dequeue_*** APIs */
145511 +#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff
145512 +/* for n in [1,15] */
145513 +#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
145514 +/* for conversion from n of qm_channel */
145515 +static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel)
145516 +{
145517 + return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1);
145518 +}
145519 +
145520 +/* For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use
145521 + * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use
145522 + * FQID(n) to fill in the frame queue ID. */
145523 +#define QM_VDQCR_PRECEDENCE_VDQCR 0x0
145524 +#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000
145525 +#define QM_VDQCR_EXACT 0x40000000
145526 +#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000
145527 +#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24)
145528 +#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f)
145529 +#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0)
145530 +
145531 +
145532 +/* ------------------------------------------------------- */
145533 +/* --- Qman data structures (and associated constants) --- */
145534 +
145535 +/* Represents s/w corenet portal mapped data structures */
145536 +struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */
145537 +struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */
145538 +struct qm_mr_entry; /* MR (Message Ring) entries */
145539 +struct qm_mc_command; /* MC (Management Command) command */
145540 +struct qm_mc_result; /* MC result */
145541 +
145542 +/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */
145543 +#define QM_FD_FORMAT_SG 0x4
145544 +#define QM_FD_FORMAT_LONG 0x2
145545 +#define QM_FD_FORMAT_COMPOUND 0x1
145546 +enum qm_fd_format {
145547 + /* 'contig' implies a contiguous buffer, whereas 'sg' implies a
145548 + * scatter-gather table. 'big' implies a 29-bit length with no offset
145549 + * field, otherwise length is 20-bit and offset is 9-bit. 'compound'
145550 + * implies a s/g-like table, where each entry itself represents a frame
145551 + * (contiguous or scatter-gather) and the 29-bit "length" is
145552 + * interpreted purely for congestion calculations, ie. a "congestion
145553 + * weight". */
145554 + qm_fd_contig = 0,
145555 + qm_fd_contig_big = QM_FD_FORMAT_LONG,
145556 + qm_fd_sg = QM_FD_FORMAT_SG,
145557 + qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG,
145558 + qm_fd_compound = QM_FD_FORMAT_COMPOUND
145559 +};
145560 +
145561 +/* Capitalised versions are un-typed but can be used in static expressions */
145562 +#define QM_FD_CONTIG 0
145563 +#define QM_FD_CONTIG_BIG QM_FD_FORMAT_LONG
145564 +#define QM_FD_SG QM_FD_FORMAT_SG
145565 +#define QM_FD_SG_BIG (QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG)
145566 +#define QM_FD_COMPOUND QM_FD_FORMAT_COMPOUND
145567 +
145568 +/* See 1.5.1.1: "Frame Descriptor (FD)" */
145569 +struct qm_fd {
145570 + union {
145571 + struct {
145572 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145573 + u8 dd:2; /* dynamic debug */
145574 + u8 liodn_offset:6;
145575 + u8 bpid:8; /* Buffer Pool ID */
145576 + u8 eliodn_offset:4;
145577 + u8 __reserved:4;
145578 + u8 addr_hi; /* high 8-bits of 40-bit address */
145579 + u32 addr_lo; /* low 32-bits of 40-bit address */
145580 +#else
145581 + u32 addr_lo; /* low 32-bits of 40-bit address */
145582 + u8 addr_hi; /* high 8-bits of 40-bit address */
145583 + u8 __reserved:4;
145584 + u8 eliodn_offset:4;
145585 + u8 bpid:8; /* Buffer Pool ID */
145586 + u8 liodn_offset:6;
145587 + u8 dd:2; /* dynamic debug */
145588 +#endif
145589 + };
145590 + struct {
145591 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145592 + u64 __notaddress:24;
145593 + u64 addr:40;
145594 +#else
145595 + u64 addr:40;
145596 + u64 __notaddress:24;
145597 +#endif
145598 + };
145599 + u64 opaque_addr;
145600 + };
145601 + /* The 'format' field indicates the interpretation of the remaining 29
145602 + * bits of the 32-bit word. For packing reasons, it is duplicated in the
145603 + * other union elements. Note, union'd structs are difficult to use with
145604 + * static initialisation under gcc, in which case use the "opaque" form
145605 + * with one of the macros. */
145606 + union {
145607 + /* For easier/faster copying of this part of the fd (eg. from a
145608 + * DQRR entry to an EQCR entry) copy 'opaque' */
145609 + u32 opaque;
145610 + /* If 'format' is _contig or _sg, 20b length and 9b offset */
145611 + struct {
145612 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145613 + enum qm_fd_format format:3;
145614 + u16 offset:9;
145615 + u32 length20:20;
145616 +#else
145617 + u32 length20:20;
145618 + u16 offset:9;
145619 + enum qm_fd_format format:3;
145620 +#endif
145621 + };
145622 + /* If 'format' is _contig_big or _sg_big, 29b length */
145623 + struct {
145624 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145625 + enum qm_fd_format _format1:3;
145626 + u32 length29:29;
145627 +#else
145628 + u32 length29:29;
145629 + enum qm_fd_format _format1:3;
145630 +#endif
145631 + };
145632 + /* If 'format' is _compound, 29b "congestion weight" */
145633 + struct {
145634 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145635 + enum qm_fd_format _format2:3;
145636 + u32 cong_weight:29;
145637 +#else
145638 + u32 cong_weight:29;
145639 + enum qm_fd_format _format2:3;
145640 +#endif
145641 + };
145642 + };
145643 + union {
145644 + u32 cmd;
145645 + u32 status;
145646 + };
145647 +} __aligned(8);
145648 +#define QM_FD_DD_NULL 0x00
145649 +#define QM_FD_PID_MASK 0x3f
145650 +static inline u64 qm_fd_addr_get64(const struct qm_fd *fd)
145651 +{
145652 + return fd->addr;
145653 +}
145654 +
145655 +static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd)
145656 +{
145657 + return (dma_addr_t)fd->addr;
145658 +}
145659 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145660 +#define qm_fd_addr_set64(fd, v) \
145661 + do { \
145662 + struct qm_fd *__fd931 = (fd); \
145663 + __fd931->addr = v; \
145664 + } while (0)
145665 +
145666 +/* For static initialisation of FDs (which is complicated by the use of unions
145667 + * in "struct qm_fd"), use the following macros. Note that;
145668 + * - 'dd', 'pid' and 'bpid' are ignored because there's no static initialisation
145669 + * use-case),
145670 + * - use capitalised QM_FD_*** formats for static initialisation.
145671 + */
145672 +#define QM_FD_FMT_20(cmd, addr_hi, addr_lo, fmt, off, len) \
145673 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
145674 + { (((fmt)&0x7) << 29) | (((off)&0x1ff) << 20) | ((len)&0xfffff) }, \
145675 + { cmd } }
145676 +#define QM_FD_FMT_29(cmd, addr_hi, addr_lo, fmt, len) \
145677 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
145678 + { (((fmt)&0x7) << 29) | ((len)&0x1fffffff) }, \
145679 + { cmd } }
145680 +
145681 +/* See 2.2.1.3 Multi-Core Datapath Acceleration Architecture */
145682 +#define QM_SG_OFFSET_MASK 0x1FFF
145683 +struct qm_sg_entry {
145684 + union {
145685 + struct {
145686 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145687 + u8 __reserved1[3];
145688 + u8 addr_hi; /* high 8-bits of 40-bit address */
145689 + u32 addr_lo; /* low 32-bits of 40-bit address */
145690 +#else
145691 + u32 addr_lo; /* low 32-bits of 40-bit address */
145692 + u8 addr_hi; /* high 8-bits of 40-bit address */
145693 + u8 __reserved1[3];
145694 +#endif
145695 + };
145696 + struct {
145697 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145698 + u64 __notaddress:24;
145699 + u64 addr:40;
145700 +#else
145701 + u64 addr:40;
145702 + u64 __notaddress:24;
145703 +#endif
145704 + };
145705 + u64 opaque;
145706 + };
145707 + union {
145708 + struct {
145709 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145710 + u32 extension:1; /* Extension bit */
145711 + u32 final:1; /* Final bit */
145712 + u32 length:30;
145713 +#else
145714 + u32 length:30;
145715 + u32 final:1; /* Final bit */
145716 + u32 extension:1; /* Extension bit */
145717 +#endif
145718 + };
145719 + u32 sgt_efl;
145720 + };
145721 + u8 __reserved2;
145722 + u8 bpid;
145723 + union {
145724 + struct {
145725 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145726 + u16 __reserved3:3;
145727 + u16 offset:13;
145728 +#else
145729 + u16 offset:13;
145730 + u16 __reserved3:3;
145731 +#endif
145732 + };
145733 + u16 opaque_offset;
145734 + };
145735 +} __packed;
145736 +union qm_sg_efl {
145737 + struct {
145738 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145739 + u32 extension:1; /* Extension bit */
145740 + u32 final:1; /* Final bit */
145741 + u32 length:30;
145742 +#else
145743 + u32 length:30;
145744 + u32 final:1; /* Final bit */
145745 + u32 extension:1; /* Extension bit */
145746 +#endif
145747 + };
145748 + u32 efl;
145749 +};
145750 +static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg)
145751 +{
145752 + return (dma_addr_t)be64_to_cpu(sg->opaque) & 0xffffffffffULL;
145753 +}
145754 +static inline u8 qm_sg_entry_get_ext(const struct qm_sg_entry *sg)
145755 +{
145756 + union qm_sg_efl u;
145757 +
145758 + u.efl = be32_to_cpu(sg->sgt_efl);
145759 + return u.extension;
145760 +}
145761 +static inline u8 qm_sg_entry_get_final(const struct qm_sg_entry *sg)
145762 +{
145763 + union qm_sg_efl u;
145764 +
145765 + u.efl = be32_to_cpu(sg->sgt_efl);
145766 + return u.final;
145767 +}
145768 +static inline u32 qm_sg_entry_get_len(const struct qm_sg_entry *sg)
145769 +{
145770 + union qm_sg_efl u;
145771 +
145772 + u.efl = be32_to_cpu(sg->sgt_efl);
145773 + return u.length;
145774 +}
145775 +static inline u8 qm_sg_entry_get_bpid(const struct qm_sg_entry *sg)
145776 +{
145777 + return sg->bpid;
145778 +}
145779 +static inline u16 qm_sg_entry_get_offset(const struct qm_sg_entry *sg)
145780 +{
145781 + u32 opaque_offset = be16_to_cpu(sg->opaque_offset);
145782 +
145783 + return opaque_offset & 0x1fff;
145784 +}
145785 +
145786 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145787 +#define qm_sg_entry_set64(sg, v) \
145788 + do { \
145789 + struct qm_sg_entry *__sg931 = (sg); \
145790 + __sg931->opaque = cpu_to_be64(v); \
145791 + } while (0)
145792 +#define qm_sg_entry_set_ext(sg, v) \
145793 + do { \
145794 + union qm_sg_efl __u932; \
145795 + __u932.efl = be32_to_cpu((sg)->sgt_efl); \
145796 + __u932.extension = v; \
145797 + (sg)->sgt_efl = cpu_to_be32(__u932.efl); \
145798 + } while (0)
145799 +#define qm_sg_entry_set_final(sg, v) \
145800 + do { \
145801 + union qm_sg_efl __u933; \
145802 + __u933.efl = be32_to_cpu((sg)->sgt_efl); \
145803 + __u933.final = v; \
145804 + (sg)->sgt_efl = cpu_to_be32(__u933.efl); \
145805 + } while (0)
145806 +#define qm_sg_entry_set_len(sg, v) \
145807 + do { \
145808 + union qm_sg_efl __u934; \
145809 + __u934.efl = be32_to_cpu((sg)->sgt_efl); \
145810 + __u934.length = v; \
145811 + (sg)->sgt_efl = cpu_to_be32(__u934.efl); \
145812 + } while (0)
145813 +#define qm_sg_entry_set_bpid(sg, v) \
145814 + do { \
145815 + struct qm_sg_entry *__u935 = (sg); \
145816 + __u935->bpid = v; \
145817 + } while (0)
145818 +#define qm_sg_entry_set_offset(sg, v) \
145819 + do { \
145820 + struct qm_sg_entry *__u936 = (sg); \
145821 + __u936->opaque_offset = cpu_to_be16(v); \
145822 + } while (0)
145823 +
145824 +/* See 1.5.8.1: "Enqueue Command" */
145825 +struct qm_eqcr_entry {
145826 + u8 __dont_write_directly__verb;
145827 + u8 dca;
145828 + u16 seqnum;
145829 + u32 orp; /* 24-bit */
145830 + u32 fqid; /* 24-bit */
145831 + u32 tag;
145832 + struct qm_fd fd;
145833 + u8 __reserved3[32];
145834 +} __packed;
145835 +#define QM_EQCR_VERB_VBIT 0x80
145836 +#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */
145837 +#define QM_EQCR_VERB_CMD_ENQUEUE 0x01
145838 +#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */
145839 +#define QM_EQCR_VERB_COLOUR_GREEN 0x00
145840 +#define QM_EQCR_VERB_COLOUR_YELLOW 0x08
145841 +#define QM_EQCR_VERB_COLOUR_RED 0x10
145842 +#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18
145843 +#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */
145844 +#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */
145845 +#define QM_EQCR_DCA_ENABLE 0x80
145846 +#define QM_EQCR_DCA_PARK 0x40
145847 +#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */
145848 +#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */
145849 +#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */
145850 +#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */
145851 +#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */
145852 +
145853 +/* See 1.5.8.2: "Frame Dequeue Response" */
145854 +struct qm_dqrr_entry {
145855 + u8 verb;
145856 + u8 stat;
145857 + u16 seqnum; /* 15-bit */
145858 + u8 tok;
145859 + u8 __reserved2[3];
145860 + u32 fqid; /* 24-bit */
145861 + u32 contextB;
145862 + struct qm_fd fd;
145863 + u8 __reserved4[32];
145864 +};
145865 +#define QM_DQRR_VERB_VBIT 0x80
145866 +#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */
145867 +#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */
145868 +#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */
145869 +#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */
145870 +#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */
145871 +#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */
145872 +#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */
145873 +#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/
145874 +
145875 +/* See 1.5.8.3: "ERN Message Response" */
145876 +/* See 1.5.8.4: "FQ State Change Notification" */
145877 +struct qm_mr_entry {
145878 + u8 verb;
145879 + union {
145880 + struct {
145881 + u8 dca;
145882 + u16 seqnum;
145883 + u8 rc; /* Rejection Code */
145884 + u32 orp:24;
145885 + u32 fqid; /* 24-bit */
145886 + u32 tag;
145887 + struct qm_fd fd;
145888 + } __packed ern;
145889 + struct {
145890 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145891 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
145892 + u8 __reserved1:3;
145893 + enum qm_dc_portal portal:3;
145894 +#else
145895 + enum qm_dc_portal portal:3;
145896 + u8 __reserved1:3;
145897 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
145898 +#endif
145899 + u16 __reserved2;
145900 + u8 rc; /* Rejection Code */
145901 + u32 __reserved3:24;
145902 + u32 fqid; /* 24-bit */
145903 + u32 tag;
145904 + struct qm_fd fd;
145905 + } __packed dcern;
145906 + struct {
145907 + u8 fqs; /* Frame Queue Status */
145908 + u8 __reserved1[6];
145909 + u32 fqid; /* 24-bit */
145910 + u32 contextB;
145911 + u8 __reserved2[16];
145912 + } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */
145913 + };
145914 + u8 __reserved2[32];
145915 +} __packed;
145916 +#define QM_MR_VERB_VBIT 0x80
145917 +/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs
145918 + * originating from direct-connect portals ("dcern") use 0x20 as a verb which
145919 + * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from
145920 + * the other MR types by noting if the 0x20 bit is unset. */
145921 +#define QM_MR_VERB_TYPE_MASK 0x27
145922 +#define QM_MR_VERB_DC_ERN 0x20
145923 +#define QM_MR_VERB_FQRN 0x21
145924 +#define QM_MR_VERB_FQRNI 0x22
145925 +#define QM_MR_VERB_FQRL 0x23
145926 +#define QM_MR_VERB_FQPN 0x24
145927 +#define QM_MR_RC_MASK 0xf0 /* contains one of; */
145928 +#define QM_MR_RC_CGR_TAILDROP 0x00
145929 +#define QM_MR_RC_WRED 0x10
145930 +#define QM_MR_RC_ERROR 0x20
145931 +#define QM_MR_RC_ORPWINDOW_EARLY 0x30
145932 +#define QM_MR_RC_ORPWINDOW_LATE 0x40
145933 +#define QM_MR_RC_FQ_TAILDROP 0x50
145934 +#define QM_MR_RC_ORPWINDOW_RETIRED 0x60
145935 +#define QM_MR_RC_ORP_ZERO 0x70
145936 +#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
145937 +#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
145938 +#define QM_MR_DCERN_COLOUR_GREEN 0x00
145939 +#define QM_MR_DCERN_COLOUR_YELLOW 0x01
145940 +#define QM_MR_DCERN_COLOUR_RED 0x02
145941 +#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03
145942 +
145943 +/* An identical structure of FQD fields is present in the "Init FQ" command and
145944 + * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type.
145945 + * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the
145946 + * latter has two inlines to assist with converting to/from the mant+exp
145947 + * representation. */
145948 +struct qm_fqd_stashing {
145949 + /* See QM_STASHING_EXCL_<...> */
145950 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145951 + u8 exclusive;
145952 + u8 __reserved1:2;
145953 + /* Numbers of cachelines */
145954 + u8 annotation_cl:2;
145955 + u8 data_cl:2;
145956 + u8 context_cl:2;
145957 +#else
145958 + u8 context_cl:2;
145959 + u8 data_cl:2;
145960 + u8 annotation_cl:2;
145961 + u8 __reserved1:2;
145962 + u8 exclusive;
145963 +#endif
145964 +} __packed;
145965 +struct qm_fqd_taildrop {
145966 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145967 + u16 __reserved1:3;
145968 + u16 mant:8;
145969 + u16 exp:5;
145970 +#else
145971 + u16 exp:5;
145972 + u16 mant:8;
145973 + u16 __reserved1:3;
145974 +#endif
145975 +} __packed;
145976 +struct qm_fqd_oac {
145977 + /* See QM_OAC_<...> */
145978 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145979 + u8 oac:2; /* "Overhead Accounting Control" */
145980 + u8 __reserved1:6;
145981 +#else
145982 + u8 __reserved1:6;
145983 + u8 oac:2; /* "Overhead Accounting Control" */
145984 +#endif
145985 + /* Two's-complement value (-128 to +127) */
145986 + signed char oal; /* "Overhead Accounting Length" */
145987 +} __packed;
145988 +struct qm_fqd {
145989 + union {
145990 + u8 orpc;
145991 + struct {
145992 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145993 + u8 __reserved1:2;
145994 + u8 orprws:3;
145995 + u8 oa:1;
145996 + u8 olws:2;
145997 +#else
145998 + u8 olws:2;
145999 + u8 oa:1;
146000 + u8 orprws:3;
146001 + u8 __reserved1:2;
146002 +#endif
146003 + } __packed;
146004 + };
146005 + u8 cgid;
146006 + u16 fq_ctrl; /* See QM_FQCTRL_<...> */
146007 + union {
146008 + u16 dest_wq;
146009 + struct {
146010 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146011 + u16 channel:13; /* qm_channel */
146012 + u16 wq:3;
146013 +#else
146014 + u16 wq:3;
146015 + u16 channel:13; /* qm_channel */
146016 +#endif
146017 + } __packed dest;
146018 + };
146019 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146020 + u16 __reserved2:1;
146021 + u16 ics_cred:15;
146022 +#else
146023 + u16 __reserved2:1;
146024 + u16 ics_cred:15;
146025 +#endif
146026 + /* For "Initialize Frame Queue" commands, the write-enable mask
146027 + * determines whether 'td' or 'oac_init' is observed. For query
146028 + * commands, this field is always 'td', and 'oac_query' (below) reflects
146029 + * the Overhead ACcounting values. */
146030 + union {
146031 + struct qm_fqd_taildrop td;
146032 + struct qm_fqd_oac oac_init;
146033 + };
146034 + u32 context_b;
146035 + union {
146036 + /* Treat it as 64-bit opaque */
146037 + u64 opaque;
146038 + struct {
146039 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146040 + u32 hi;
146041 + u32 lo;
146042 +#else
146043 + u32 lo;
146044 + u32 hi;
146045 +#endif
146046 + };
146047 + /* Treat it as s/w portal stashing config */
146048 + /* See 1.5.6.7.1: "FQD Context_A field used for [...] */
146049 + struct {
146050 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146051 + struct qm_fqd_stashing stashing;
146052 + /* 48-bit address of FQ context to
146053 + * stash, must be cacheline-aligned */
146054 + u16 context_hi;
146055 + u32 context_lo;
146056 +#else
146057 + u32 context_lo;
146058 + u16 context_hi;
146059 + struct qm_fqd_stashing stashing;
146060 +#endif
146061 + } __packed;
146062 + } context_a;
146063 + struct qm_fqd_oac oac_query;
146064 +} __packed;
146065 +/* 64-bit converters for context_hi/lo */
146066 +static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd)
146067 +{
146068 + return ((u64)fqd->context_a.context_hi << 32) |
146069 + (u64)fqd->context_a.context_lo;
146070 +}
146071 +static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd)
146072 +{
146073 + return (dma_addr_t)qm_fqd_stashing_get64(fqd);
146074 +}
146075 +static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd)
146076 +{
146077 + return ((u64)fqd->context_a.hi << 32) |
146078 + (u64)fqd->context_a.lo;
146079 +}
146080 +/* Macro, so we compile better when 'v' isn't necessarily 64-bit */
146081 +#define qm_fqd_stashing_set64(fqd, v) \
146082 + do { \
146083 + struct qm_fqd *__fqd931 = (fqd); \
146084 + __fqd931->context_a.context_hi = upper_32_bits(v); \
146085 + __fqd931->context_a.context_lo = lower_32_bits(v); \
146086 + } while (0)
146087 +#define qm_fqd_context_a_set64(fqd, v) \
146088 + do { \
146089 + struct qm_fqd *__fqd931 = (fqd); \
146090 + __fqd931->context_a.hi = upper_32_bits(v); \
146091 + __fqd931->context_a.lo = lower_32_bits(v); \
146092 + } while (0)
146093 +/* convert a threshold value into mant+exp representation */
146094 +static inline int qm_fqd_taildrop_set(struct qm_fqd_taildrop *td, u32 val,
146095 + int roundup)
146096 +{
146097 + u32 e = 0;
146098 + int oddbit = 0;
146099 + if (val > 0xe0000000)
146100 + return -ERANGE;
146101 + while (val > 0xff) {
146102 + oddbit = val & 1;
146103 + val >>= 1;
146104 + e++;
146105 + if (roundup && oddbit)
146106 + val++;
146107 + }
146108 + td->exp = e;
146109 + td->mant = val;
146110 + return 0;
146111 +}
146112 +/* and the other direction */
146113 +static inline u32 qm_fqd_taildrop_get(const struct qm_fqd_taildrop *td)
146114 +{
146115 + return (u32)td->mant << td->exp;
146116 +}
146117 +
146118 +/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */
146119 +/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */
146120 +#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */
146121 +#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */
146122 +#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */
146123 +#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */
146124 +#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */
146125 +#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */
146126 +#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */
146127 +#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */
146128 +#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */
146129 +#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */
146130 +#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */
146131 +
146132 +/* See 1.5.6.7.1: "FQD Context_A field used for [...] */
146133 +/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */
146134 +#define QM_STASHING_EXCL_ANNOTATION 0x04
146135 +#define QM_STASHING_EXCL_DATA 0x02
146136 +#define QM_STASHING_EXCL_CTX 0x01
146137 +
146138 +/* See 1.5.5.3: "Intra Class Scheduling" */
146139 +/* FQD field 'OAC' (Overhead ACcounting) uses these constants */
146140 +#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */
146141 +#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */
146142 +
146143 +/* See 1.5.8.4: "FQ State Change Notification" */
146144 +/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields
146145 + * and associated commands/responses. The WRED parameters are calculated from
146146 + * these fields as follows;
146147 + * MaxTH = MA * (2 ^ Mn)
146148 + * Slope = SA / (2 ^ Sn)
146149 + * MaxP = 4 * (Pn + 1)
146150 + */
146151 +struct qm_cgr_wr_parm {
146152 + union {
146153 + u32 word;
146154 + struct {
146155 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146156 + u32 MA:8;
146157 + u32 Mn:5;
146158 + u32 SA:7; /* must be between 64-127 */
146159 + u32 Sn:6;
146160 + u32 Pn:6;
146161 +#else
146162 + u32 Pn:6;
146163 + u32 Sn:6;
146164 + u32 SA:7; /* must be between 64-127 */
146165 + u32 Mn:5;
146166 + u32 MA:8;
146167 +#endif
146168 + } __packed;
146169 + };
146170 +} __packed;
146171 +/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding
146172 + * management commands, this is padded to a 16-bit structure field, so that's
146173 + * how we represent it here. The congestion state threshold is calculated from
146174 + * these fields as follows;
146175 + * CS threshold = TA * (2 ^ Tn)
146176 + */
146177 +struct qm_cgr_cs_thres {
146178 + union {
146179 + u16 hword;
146180 + struct {
146181 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146182 + u16 __reserved:3;
146183 + u16 TA:8;
146184 + u16 Tn:5;
146185 +#else
146186 + u16 Tn:5;
146187 + u16 TA:8;
146188 + u16 __reserved:3;
146189 +#endif
146190 + } __packed;
146191 + };
146192 +} __packed;
146193 +/* This identical structure of CGR fields is present in the "Init/Modify CGR"
146194 + * commands and the "Query CGR" result. It's suctioned out here into its own
146195 + * struct. */
146196 +struct __qm_mc_cgr {
146197 + struct qm_cgr_wr_parm wr_parm_g;
146198 + struct qm_cgr_wr_parm wr_parm_y;
146199 + struct qm_cgr_wr_parm wr_parm_r;
146200 + u8 wr_en_g; /* boolean, use QM_CGR_EN */
146201 + u8 wr_en_y; /* boolean, use QM_CGR_EN */
146202 + u8 wr_en_r; /* boolean, use QM_CGR_EN */
146203 + u8 cscn_en; /* boolean, use QM_CGR_EN */
146204 + union {
146205 + struct {
146206 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146207 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
146208 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
146209 +#else
146210 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
146211 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
146212 +#endif
146213 + };
146214 + u32 cscn_targ; /* use QM_CGR_TARG_* */
146215 + };
146216 + u8 cstd_en; /* boolean, use QM_CGR_EN */
146217 + u8 cs; /* boolean, only used in query response */
146218 + union {
146219 + /* use qm_cgr_cs_thres_set64() */
146220 + struct qm_cgr_cs_thres cs_thres;
146221 + u16 __cs_thres;
146222 + };
146223 + u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */
146224 +} __packed;
146225 +#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */
146226 +#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/
146227 +#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */
146228 +#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */
146229 +#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */
146230 +#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */
146231 +/* Convert CGR thresholds to/from "cs_thres" format */
146232 +static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th)
146233 +{
146234 + return (u64)th->TA << th->Tn;
146235 +}
146236 +static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val,
146237 + int roundup)
146238 +{
146239 + u32 e = 0;
146240 + int oddbit = 0;
146241 + while (val > 0xff) {
146242 + oddbit = val & 1;
146243 + val >>= 1;
146244 + e++;
146245 + if (roundup && oddbit)
146246 + val++;
146247 + }
146248 + th->Tn = e;
146249 + th->TA = val;
146250 + return 0;
146251 +}
146252 +
146253 +/* See 1.5.8.5.1: "Initialize FQ" */
146254 +/* See 1.5.8.5.2: "Query FQ" */
146255 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
146256 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
146257 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
146258 +/* See 1.5.8.6.2: "CGR Test Write" */
146259 +/* See 1.5.8.6.3: "Query CGR" */
146260 +/* See 1.5.8.6.4: "Query Congestion Group State" */
146261 +struct qm_mcc_initfq {
146262 + u8 __reserved1;
146263 + u16 we_mask; /* Write Enable Mask */
146264 + u32 fqid; /* 24-bit */
146265 + u16 count; /* Initialises 'count+1' FQDs */
146266 + struct qm_fqd fqd; /* the FQD fields go here */
146267 + u8 __reserved3[30];
146268 +} __packed;
146269 +struct qm_mcc_queryfq {
146270 + u8 __reserved1[3];
146271 + u32 fqid; /* 24-bit */
146272 + u8 __reserved2[56];
146273 +} __packed;
146274 +struct qm_mcc_queryfq_np {
146275 + u8 __reserved1[3];
146276 + u32 fqid; /* 24-bit */
146277 + u8 __reserved2[56];
146278 +} __packed;
146279 +struct qm_mcc_alterfq {
146280 + u8 __reserved1[3];
146281 + u32 fqid; /* 24-bit */
146282 + u8 __reserved2;
146283 + u8 count; /* number of consecutive FQID */
146284 + u8 __reserved3[10];
146285 + u32 context_b; /* frame queue context b */
146286 + u8 __reserved4[40];
146287 +} __packed;
146288 +struct qm_mcc_initcgr {
146289 + u8 __reserved1;
146290 + u16 we_mask; /* Write Enable Mask */
146291 + struct __qm_mc_cgr cgr; /* CGR fields */
146292 + u8 __reserved2[2];
146293 + u8 cgid;
146294 + u8 __reserved4[32];
146295 +} __packed;
146296 +struct qm_mcc_cgrtestwrite {
146297 + u8 __reserved1[2];
146298 + u8 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146299 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146300 + u8 __reserved2[23];
146301 + u8 cgid;
146302 + u8 __reserved3[32];
146303 +} __packed;
146304 +struct qm_mcc_querycgr {
146305 + u8 __reserved1[30];
146306 + u8 cgid;
146307 + u8 __reserved2[32];
146308 +} __packed;
146309 +struct qm_mcc_querycongestion {
146310 + u8 __reserved[63];
146311 +} __packed;
146312 +struct qm_mcc_querywq {
146313 + u8 __reserved;
146314 + /* select channel if verb != QUERYWQ_DEDICATED */
146315 + union {
146316 + u16 channel_wq; /* ignores wq (3 lsbits) */
146317 + struct {
146318 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146319 + u16 id:13; /* qm_channel */
146320 + u16 __reserved1:3;
146321 +#else
146322 + u16 __reserved1:3;
146323 + u16 id:13; /* qm_channel */
146324 +#endif
146325 + } __packed channel;
146326 + };
146327 + u8 __reserved2[60];
146328 +} __packed;
146329 +
146330 +struct qm_mcc_ceetm_lfqmt_config {
146331 + u8 __reserved1[4];
146332 + u32 lfqid:24;
146333 + u8 __reserved2[2];
146334 + u16 cqid;
146335 + u8 __reserved3[2];
146336 + u16 dctidx;
146337 + u8 __reserved4[48];
146338 +} __packed;
146339 +
146340 +struct qm_mcc_ceetm_lfqmt_query {
146341 + u8 __reserved1[4];
146342 + u32 lfqid:24;
146343 + u8 __reserved2[56];
146344 +} __packed;
146345 +
146346 +struct qm_mcc_ceetm_cq_config {
146347 + u8 __reserved1;
146348 + u16 cqid;
146349 + u8 dcpid;
146350 + u8 __reserved2;
146351 + u16 ccgid;
146352 + u8 __reserved3[56];
146353 +} __packed;
146354 +
146355 +struct qm_mcc_ceetm_cq_query {
146356 + u8 __reserved1;
146357 + u16 cqid;
146358 + u8 dcpid;
146359 + u8 __reserved2[59];
146360 +} __packed;
146361 +
146362 +struct qm_mcc_ceetm_dct_config {
146363 + u8 __reserved1;
146364 + u16 dctidx;
146365 + u8 dcpid;
146366 + u8 __reserved2[15];
146367 + u32 context_b;
146368 + u64 context_a;
146369 + u8 __reserved3[32];
146370 +} __packed;
146371 +
146372 +struct qm_mcc_ceetm_dct_query {
146373 + u8 __reserved1;
146374 + u16 dctidx;
146375 + u8 dcpid;
146376 + u8 __reserved2[59];
146377 +} __packed;
146378 +
146379 +struct qm_mcc_ceetm_class_scheduler_config {
146380 + u8 __reserved1;
146381 + u16 cqcid;
146382 + u8 dcpid;
146383 + u8 __reserved2[6];
146384 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146385 + u8 gpc_reserved:1;
146386 + u8 gpc_combine_flag:1;
146387 + u8 gpc_prio_b:3;
146388 + u8 gpc_prio_a:3;
146389 +#else
146390 + u8 gpc_prio_a:3;
146391 + u8 gpc_prio_b:3;
146392 + u8 gpc_combine_flag:1;
146393 + u8 gpc_reserved:1;
146394 +#endif
146395 + u16 crem;
146396 + u16 erem;
146397 + u8 w[8];
146398 + u8 __reserved3[40];
146399 +} __packed;
146400 +
146401 +struct qm_mcc_ceetm_class_scheduler_query {
146402 + u8 __reserved1;
146403 + u16 cqcid;
146404 + u8 dcpid;
146405 + u8 __reserved2[59];
146406 +} __packed;
146407 +
146408 +#define CEETM_COMMAND_CHANNEL_MAPPING (0 << 12)
146409 +#define CEETM_COMMAND_SP_MAPPING (1 << 12)
146410 +#define CEETM_COMMAND_CHANNEL_SHAPER (2 << 12)
146411 +#define CEETM_COMMAND_LNI_SHAPER (3 << 12)
146412 +#define CEETM_COMMAND_TCFC (4 << 12)
146413 +
146414 +#define CEETM_CCGRID_MASK 0x01FF
146415 +#define CEETM_CCGR_CM_CONFIGURE (0 << 14)
146416 +#define CEETM_CCGR_DN_CONFIGURE (1 << 14)
146417 +#define CEETM_CCGR_TEST_WRITE (2 << 14)
146418 +#define CEETM_CCGR_CM_QUERY (0 << 14)
146419 +#define CEETM_CCGR_DN_QUERY (1 << 14)
146420 +#define CEETM_CCGR_DN_QUERY_FLUSH (2 << 14)
146421 +#define CEETM_QUERY_CONGESTION_STATE (3 << 14)
146422 +
146423 +struct qm_mcc_ceetm_mapping_shaper_tcfc_config {
146424 + u8 __reserved1;
146425 + u16 cid;
146426 + u8 dcpid;
146427 + union {
146428 + struct {
146429 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146430 + u8 map_shaped:1;
146431 + u8 map_reserved:4;
146432 + u8 map_lni_id:3;
146433 +#else
146434 + u8 map_lni_id:3;
146435 + u8 map_reserved:4;
146436 + u8 map_shaped:1;
146437 +#endif
146438 + u8 __reserved2[58];
146439 + } __packed channel_mapping;
146440 + struct {
146441 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146442 + u8 map_reserved:5;
146443 + u8 map_lni_id:3;
146444 +#else
146445 + u8 map_lni_id:3;
146446 + u8 map_reserved:5;
146447 +#endif
146448 + u8 __reserved2[58];
146449 + } __packed sp_mapping;
146450 + struct {
146451 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146452 + u8 cpl:1;
146453 + u8 cpl_reserved:2;
146454 + u8 oal:5;
146455 +#else
146456 + u8 oal:5;
146457 + u8 cpl_reserved:2;
146458 + u8 cpl:1;
146459 +#endif
146460 + u32 crtcr:24;
146461 + u32 ertcr:24;
146462 + u16 crtbl;
146463 + u16 ertbl;
146464 + u8 mps; /* This will be hardcoded by driver with 60 */
146465 + u8 __reserved2[47];
146466 + } __packed shaper_config;
146467 + struct {
146468 + u8 __reserved2[11];
146469 + u64 lnitcfcc;
146470 + u8 __reserved3[40];
146471 + } __packed tcfc_config;
146472 + };
146473 +} __packed;
146474 +
146475 +struct qm_mcc_ceetm_mapping_shaper_tcfc_query {
146476 + u8 __reserved1;
146477 + u16 cid;
146478 + u8 dcpid;
146479 + u8 __reserved2[59];
146480 +} __packed;
146481 +
146482 +struct qm_mcc_ceetm_ccgr_config {
146483 + u8 __reserved1;
146484 + u16 ccgrid;
146485 + u8 dcpid;
146486 + u8 __reserved2;
146487 + u16 we_mask;
146488 + union {
146489 + struct {
146490 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146491 + u8 ctl_reserved:1;
146492 + u8 ctl_wr_en_g:1;
146493 + u8 ctl_wr_en_y:1;
146494 + u8 ctl_wr_en_r:1;
146495 + u8 ctl_td_en:1;
146496 + u8 ctl_td_mode:1;
146497 + u8 ctl_cscn_en:1;
146498 + u8 ctl_mode:1;
146499 +#else
146500 + u8 ctl_mode:1;
146501 + u8 ctl_cscn_en:1;
146502 + u8 ctl_td_mode:1;
146503 + u8 ctl_td_en:1;
146504 + u8 ctl_wr_en_r:1;
146505 + u8 ctl_wr_en_y:1;
146506 + u8 ctl_wr_en_g:1;
146507 + u8 ctl_reserved:1;
146508 +#endif
146509 + u8 cdv;
146510 + u16 cscn_tupd;
146511 + u8 oal;
146512 + u8 __reserved3;
146513 + struct qm_cgr_cs_thres cs_thres;
146514 + struct qm_cgr_cs_thres cs_thres_x;
146515 + struct qm_cgr_cs_thres td_thres;
146516 + struct qm_cgr_wr_parm wr_parm_g;
146517 + struct qm_cgr_wr_parm wr_parm_y;
146518 + struct qm_cgr_wr_parm wr_parm_r;
146519 + } __packed cm_config;
146520 + struct {
146521 + u8 dnc;
146522 + u8 dn0;
146523 + u8 dn1;
146524 + u64 dnba:40;
146525 + u8 __reserved3[2];
146526 + u16 dnth_0;
146527 + u8 __reserved4[2];
146528 + u16 dnth_1;
146529 + u8 __reserved5[8];
146530 + } __packed dn_config;
146531 + struct {
146532 + u8 __reserved3[3];
146533 + u64 i_cnt:40;
146534 + u8 __reserved4[16];
146535 + } __packed test_write;
146536 + };
146537 + u8 __reserved5[32];
146538 +} __packed;
146539 +
146540 +struct qm_mcc_ceetm_ccgr_query {
146541 + u8 __reserved1;
146542 + u16 ccgrid;
146543 + u8 dcpid;
146544 + u8 __reserved2[59];
146545 +} __packed;
146546 +
146547 +struct qm_mcc_ceetm_cq_peek_pop_xsfdrread {
146548 + u8 __reserved1;
146549 + u16 cqid;
146550 + u8 dcpid;
146551 + u8 ct;
146552 + u16 xsfdr;
146553 + u8 __reserved2[56];
146554 +} __packed;
146555 +
146556 +#define CEETM_QUERY_DEQUEUE_STATISTICS 0x00
146557 +#define CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS 0x01
146558 +#define CEETM_WRITE_DEQUEUE_STATISTICS 0x02
146559 +#define CEETM_QUERY_REJECT_STATISTICS 0x03
146560 +#define CEETM_QUERY_REJECT_CLEAR_STATISTICS 0x04
146561 +#define CEETM_WRITE_REJECT_STATISTICS 0x05
146562 +struct qm_mcc_ceetm_statistics_query_write {
146563 + u8 __reserved1;
146564 + u16 cid;
146565 + u8 dcpid;
146566 + u8 ct;
146567 + u8 __reserved2[13];
146568 + u64 frm_cnt:40;
146569 + u8 __reserved3[2];
146570 + u64 byte_cnt:48;
146571 + u8 __reserved[32];
146572 +} __packed;
146573 +
146574 +struct qm_mc_command {
146575 + u8 __dont_write_directly__verb;
146576 + union {
146577 + struct qm_mcc_initfq initfq;
146578 + struct qm_mcc_queryfq queryfq;
146579 + struct qm_mcc_queryfq_np queryfq_np;
146580 + struct qm_mcc_alterfq alterfq;
146581 + struct qm_mcc_initcgr initcgr;
146582 + struct qm_mcc_cgrtestwrite cgrtestwrite;
146583 + struct qm_mcc_querycgr querycgr;
146584 + struct qm_mcc_querycongestion querycongestion;
146585 + struct qm_mcc_querywq querywq;
146586 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
146587 + struct qm_mcc_ceetm_lfqmt_query lfqmt_query;
146588 + struct qm_mcc_ceetm_cq_config cq_config;
146589 + struct qm_mcc_ceetm_cq_query cq_query;
146590 + struct qm_mcc_ceetm_dct_config dct_config;
146591 + struct qm_mcc_ceetm_dct_query dct_query;
146592 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
146593 + struct qm_mcc_ceetm_class_scheduler_query csch_query;
146594 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config mst_config;
146595 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query mst_query;
146596 + struct qm_mcc_ceetm_ccgr_config ccgr_config;
146597 + struct qm_mcc_ceetm_ccgr_query ccgr_query;
146598 + struct qm_mcc_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
146599 + struct qm_mcc_ceetm_statistics_query_write stats_query_write;
146600 + };
146601 +} __packed;
146602 +#define QM_MCC_VERB_VBIT 0x80
146603 +#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */
146604 +#define QM_MCC_VERB_INITFQ_PARKED 0x40
146605 +#define QM_MCC_VERB_INITFQ_SCHED 0x41
146606 +#define QM_MCC_VERB_QUERYFQ 0x44
146607 +#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */
146608 +#define QM_MCC_VERB_QUERYWQ 0x46
146609 +#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47
146610 +#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */
146611 +#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */
146612 +#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */
146613 +#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */
146614 +#define QM_MCC_VERB_ALTER_FQXON 0x4d /* FQ XON */
146615 +#define QM_MCC_VERB_ALTER_FQXOFF 0x4e /* FQ XOFF */
146616 +#define QM_MCC_VERB_INITCGR 0x50
146617 +#define QM_MCC_VERB_MODIFYCGR 0x51
146618 +#define QM_MCC_VERB_CGRTESTWRITE 0x52
146619 +#define QM_MCC_VERB_QUERYCGR 0x58
146620 +#define QM_MCC_VERB_QUERYCONGESTION 0x59
146621 +/* INITFQ-specific flags */
146622 +#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */
146623 +#define QM_INITFQ_WE_OAC 0x0100
146624 +#define QM_INITFQ_WE_ORPC 0x0080
146625 +#define QM_INITFQ_WE_CGID 0x0040
146626 +#define QM_INITFQ_WE_FQCTRL 0x0020
146627 +#define QM_INITFQ_WE_DESTWQ 0x0010
146628 +#define QM_INITFQ_WE_ICSCRED 0x0008
146629 +#define QM_INITFQ_WE_TDTHRESH 0x0004
146630 +#define QM_INITFQ_WE_CONTEXTB 0x0002
146631 +#define QM_INITFQ_WE_CONTEXTA 0x0001
146632 +/* INITCGR/MODIFYCGR-specific flags */
146633 +#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */
146634 +#define QM_CGR_WE_WR_PARM_G 0x0400
146635 +#define QM_CGR_WE_WR_PARM_Y 0x0200
146636 +#define QM_CGR_WE_WR_PARM_R 0x0100
146637 +#define QM_CGR_WE_WR_EN_G 0x0080
146638 +#define QM_CGR_WE_WR_EN_Y 0x0040
146639 +#define QM_CGR_WE_WR_EN_R 0x0020
146640 +#define QM_CGR_WE_CSCN_EN 0x0010
146641 +#define QM_CGR_WE_CSCN_TARG 0x0008
146642 +#define QM_CGR_WE_CSTD_EN 0x0004
146643 +#define QM_CGR_WE_CS_THRES 0x0002
146644 +#define QM_CGR_WE_MODE 0x0001
146645 +
146646 +/* See 1.5.9.7 CEETM Management Commands */
146647 +#define QM_CEETM_VERB_LFQMT_CONFIG 0x70
146648 +#define QM_CEETM_VERB_LFQMT_QUERY 0x71
146649 +#define QM_CEETM_VERB_CQ_CONFIG 0x72
146650 +#define QM_CEETM_VERB_CQ_QUERY 0x73
146651 +#define QM_CEETM_VERB_DCT_CONFIG 0x74
146652 +#define QM_CEETM_VERB_DCT_QUERY 0x75
146653 +#define QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG 0x76
146654 +#define QM_CEETM_VERB_CLASS_SCHEDULER_QUERY 0x77
146655 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG 0x78
146656 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY 0x79
146657 +#define QM_CEETM_VERB_CCGR_CONFIG 0x7A
146658 +#define QM_CEETM_VERB_CCGR_QUERY 0x7B
146659 +#define QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD 0x7C
146660 +#define QM_CEETM_VERB_STATISTICS_QUERY_WRITE 0x7D
146661 +
146662 +/* See 1.5.8.5.1: "Initialize FQ" */
146663 +/* See 1.5.8.5.2: "Query FQ" */
146664 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
146665 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
146666 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
146667 +/* See 1.5.8.6.2: "CGR Test Write" */
146668 +/* See 1.5.8.6.3: "Query CGR" */
146669 +/* See 1.5.8.6.4: "Query Congestion Group State" */
146670 +struct qm_mcr_initfq {
146671 + u8 __reserved1[62];
146672 +} __packed;
146673 +struct qm_mcr_queryfq {
146674 + u8 __reserved1[8];
146675 + struct qm_fqd fqd; /* the FQD fields are here */
146676 + u8 __reserved2[30];
146677 +} __packed;
146678 +struct qm_mcr_queryfq_np {
146679 + u8 __reserved1;
146680 + u8 state; /* QM_MCR_NP_STATE_*** */
146681 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146682 + u8 __reserved2;
146683 + u32 fqd_link:24;
146684 + u16 __reserved3:2;
146685 + u16 odp_seq:14;
146686 + u16 __reserved4:2;
146687 + u16 orp_nesn:14;
146688 + u16 __reserved5:1;
146689 + u16 orp_ea_hseq:15;
146690 + u16 __reserved6:1;
146691 + u16 orp_ea_tseq:15;
146692 + u8 __reserved7;
146693 + u32 orp_ea_hptr:24;
146694 + u8 __reserved8;
146695 + u32 orp_ea_tptr:24;
146696 + u8 __reserved9;
146697 + u32 pfdr_hptr:24;
146698 + u8 __reserved10;
146699 + u32 pfdr_tptr:24;
146700 + u8 __reserved11[5];
146701 + u8 __reserved12:7;
146702 + u8 is:1;
146703 + u16 ics_surp;
146704 + u32 byte_cnt;
146705 + u8 __reserved13;
146706 + u32 frm_cnt:24;
146707 + u32 __reserved14;
146708 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
146709 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
146710 + u16 __reserved15;
146711 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
146712 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
146713 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
146714 +#else
146715 + u8 __reserved2;
146716 + u32 fqd_link:24;
146717 +
146718 + u16 odp_seq:14;
146719 + u16 __reserved3:2;
146720 +
146721 + u16 orp_nesn:14;
146722 + u16 __reserved4:2;
146723 +
146724 + u16 orp_ea_hseq:15;
146725 + u16 __reserved5:1;
146726 +
146727 + u16 orp_ea_tseq:15;
146728 + u16 __reserved6:1;
146729 +
146730 + u8 __reserved7;
146731 + u32 orp_ea_hptr:24;
146732 +
146733 + u8 __reserved8;
146734 + u32 orp_ea_tptr:24;
146735 +
146736 + u8 __reserved9;
146737 + u32 pfdr_hptr:24;
146738 +
146739 + u8 __reserved10;
146740 + u32 pfdr_tptr:24;
146741 +
146742 + u8 __reserved11[5];
146743 + u8 is:1;
146744 + u8 __reserved12:7;
146745 + u16 ics_surp;
146746 + u32 byte_cnt;
146747 + u8 __reserved13;
146748 + u32 frm_cnt:24;
146749 + u32 __reserved14;
146750 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
146751 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
146752 + u16 __reserved15;
146753 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
146754 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
146755 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
146756 +#endif
146757 +} __packed;
146758 +
146759 +
146760 +struct qm_mcr_alterfq {
146761 + u8 fqs; /* Frame Queue Status */
146762 + u8 __reserved1[61];
146763 +} __packed;
146764 +struct qm_mcr_initcgr {
146765 + u8 __reserved1[62];
146766 +} __packed;
146767 +struct qm_mcr_cgrtestwrite {
146768 + u16 __reserved1;
146769 + struct __qm_mc_cgr cgr; /* CGR fields */
146770 + u8 __reserved2[3];
146771 + u32 __reserved3:24;
146772 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146773 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146774 + u32 __reserved4:24;
146775 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146776 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146777 + u16 lgt; /* Last Group Tick */
146778 + u16 wr_prob_g;
146779 + u16 wr_prob_y;
146780 + u16 wr_prob_r;
146781 + u8 __reserved5[8];
146782 +} __packed;
146783 +struct qm_mcr_querycgr {
146784 + u16 __reserved1;
146785 + struct __qm_mc_cgr cgr; /* CGR fields */
146786 + u8 __reserved2[3];
146787 + union {
146788 + struct {
146789 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146790 + u32 __reserved3:24;
146791 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146792 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146793 +#else
146794 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146795 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146796 + u32 __reserved3:24;
146797 +#endif
146798 + };
146799 + u64 i_bcnt;
146800 + };
146801 + union {
146802 + struct {
146803 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146804 + u32 __reserved4:24;
146805 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146806 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146807 +#else
146808 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146809 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146810 + u32 __reserved4:24;
146811 +#endif
146812 + };
146813 + u64 a_bcnt;
146814 + };
146815 + union {
146816 + u32 cscn_targ_swp[4];
146817 + u8 __reserved5[16];
146818 + };
146819 +} __packed;
146820 +static inline u64 qm_mcr_querycgr_i_get64(const struct qm_mcr_querycgr *q)
146821 +{
146822 + return be64_to_cpu(q->i_bcnt);
146823 +}
146824 +static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q)
146825 +{
146826 + return be64_to_cpu(q->a_bcnt);
146827 +}
146828 +static inline u64 qm_mcr_cgrtestwrite_i_get64(
146829 + const struct qm_mcr_cgrtestwrite *q)
146830 +{
146831 + return be64_to_cpu(((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo);
146832 +}
146833 +static inline u64 qm_mcr_cgrtestwrite_a_get64(
146834 + const struct qm_mcr_cgrtestwrite *q)
146835 +{
146836 + return be64_to_cpu(((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo);
146837 +}
146838 +/* Macro, so we compile better if 'v' isn't always 64-bit */
146839 +#define qm_mcr_querycgr_i_set64(q, v) \
146840 + do { \
146841 + struct qm_mcr_querycgr *__q931 = (fd); \
146842 + __q931->i_bcnt_hi = upper_32_bits(v); \
146843 + __q931->i_bcnt_lo = lower_32_bits(v); \
146844 + } while (0)
146845 +#define qm_mcr_querycgr_a_set64(q, v) \
146846 + do { \
146847 + struct qm_mcr_querycgr *__q931 = (fd); \
146848 + __q931->a_bcnt_hi = upper_32_bits(v); \
146849 + __q931->a_bcnt_lo = lower_32_bits(v); \
146850 + } while (0)
146851 +struct __qm_mcr_querycongestion {
146852 + u32 __state[8];
146853 +};
146854 +struct qm_mcr_querycongestion {
146855 + u8 __reserved[30];
146856 + /* Access this struct using QM_MCR_QUERYCONGESTION() */
146857 + struct __qm_mcr_querycongestion state;
146858 +} __packed;
146859 +struct qm_mcr_querywq {
146860 + union {
146861 + u16 channel_wq; /* ignores wq (3 lsbits) */
146862 + struct {
146863 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146864 + u16 id:13; /* qm_channel */
146865 + u16 __reserved:3;
146866 +#else
146867 + u16 __reserved:3;
146868 + u16 id:13; /* qm_channel */
146869 +#endif
146870 + } __packed channel;
146871 + };
146872 + u8 __reserved[28];
146873 + u32 wq_len[8];
146874 +} __packed;
146875 +
146876 +/* QMAN CEETM Management Command Response */
146877 +struct qm_mcr_ceetm_lfqmt_config {
146878 + u8 __reserved1[62];
146879 +} __packed;
146880 +struct qm_mcr_ceetm_lfqmt_query {
146881 + u8 __reserved1[8];
146882 + u16 cqid;
146883 + u8 __reserved2[2];
146884 + u16 dctidx;
146885 + u8 __reserved3[2];
146886 + u16 ccgid;
146887 + u8 __reserved4[44];
146888 +} __packed;
146889 +
146890 +struct qm_mcr_ceetm_cq_config {
146891 + u8 __reserved1[62];
146892 +} __packed;
146893 +
146894 +struct qm_mcr_ceetm_cq_query {
146895 + u8 __reserved1[4];
146896 + u16 ccgid;
146897 + u16 state;
146898 + u32 pfdr_hptr:24;
146899 + u32 pfdr_tptr:24;
146900 + u16 od1_xsfdr;
146901 + u16 od2_xsfdr;
146902 + u16 od3_xsfdr;
146903 + u16 od4_xsfdr;
146904 + u16 od5_xsfdr;
146905 + u16 od6_xsfdr;
146906 + u16 ra1_xsfdr;
146907 + u16 ra2_xsfdr;
146908 + u8 __reserved2;
146909 + u32 frm_cnt:24;
146910 + u8 __reserved333[28];
146911 +} __packed;
146912 +
146913 +struct qm_mcr_ceetm_dct_config {
146914 + u8 __reserved1[62];
146915 +} __packed;
146916 +
146917 +struct qm_mcr_ceetm_dct_query {
146918 + u8 __reserved1[18];
146919 + u32 context_b;
146920 + u64 context_a;
146921 + u8 __reserved2[32];
146922 +} __packed;
146923 +
146924 +struct qm_mcr_ceetm_class_scheduler_config {
146925 + u8 __reserved1[62];
146926 +} __packed;
146927 +
146928 +struct qm_mcr_ceetm_class_scheduler_query {
146929 + u8 __reserved1[9];
146930 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146931 + u8 gpc_reserved:1;
146932 + u8 gpc_combine_flag:1;
146933 + u8 gpc_prio_b:3;
146934 + u8 gpc_prio_a:3;
146935 +#else
146936 + u8 gpc_prio_a:3;
146937 + u8 gpc_prio_b:3;
146938 + u8 gpc_combine_flag:1;
146939 + u8 gpc_reserved:1;
146940 +#endif
146941 + u16 crem;
146942 + u16 erem;
146943 + u8 w[8];
146944 + u8 __reserved2[5];
146945 + u32 wbfslist:24;
146946 + u32 d8;
146947 + u32 d9;
146948 + u32 d10;
146949 + u32 d11;
146950 + u32 d12;
146951 + u32 d13;
146952 + u32 d14;
146953 + u32 d15;
146954 +} __packed;
146955 +
146956 +struct qm_mcr_ceetm_mapping_shaper_tcfc_config {
146957 + u16 cid;
146958 + u8 __reserved2[60];
146959 +} __packed;
146960 +
146961 +struct qm_mcr_ceetm_mapping_shaper_tcfc_query {
146962 + u16 cid;
146963 + u8 __reserved1;
146964 + union {
146965 + struct {
146966 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146967 + u8 map_shaped:1;
146968 + u8 map_reserved:4;
146969 + u8 map_lni_id:3;
146970 +#else
146971 + u8 map_lni_id:3;
146972 + u8 map_reserved:4;
146973 + u8 map_shaped:1;
146974 +#endif
146975 + u8 __reserved2[58];
146976 + } __packed channel_mapping_query;
146977 + struct {
146978 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146979 + u8 map_reserved:5;
146980 + u8 map_lni_id:3;
146981 +#else
146982 + u8 map_lni_id:3;
146983 + u8 map_reserved:5;
146984 +#endif
146985 + u8 __reserved2[58];
146986 + } __packed sp_mapping_query;
146987 + struct {
146988 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146989 + u8 cpl:1;
146990 + u8 cpl_reserved:2;
146991 + u8 oal:5;
146992 +#else
146993 + u8 oal:5;
146994 + u8 cpl_reserved:2;
146995 + u8 cpl:1;
146996 +#endif
146997 + u32 crtcr:24;
146998 + u32 ertcr:24;
146999 + u16 crtbl;
147000 + u16 ertbl;
147001 + u8 mps;
147002 + u8 __reserved2[15];
147003 + u32 crat;
147004 + u32 erat;
147005 + u8 __reserved3[24];
147006 + } __packed shaper_query;
147007 + struct {
147008 + u8 __reserved1[11];
147009 + u64 lnitcfcc;
147010 + u8 __reserved3[40];
147011 + } __packed tcfc_query;
147012 + };
147013 +} __packed;
147014 +
147015 +struct qm_mcr_ceetm_ccgr_config {
147016 + u8 __reserved1[46];
147017 + union {
147018 + u8 __reserved2[8];
147019 + struct {
147020 + u16 timestamp;
147021 + u16 wr_porb_g;
147022 + u16 wr_prob_y;
147023 + u16 wr_prob_r;
147024 + } __packed test_write;
147025 + };
147026 + u8 __reserved3[8];
147027 +} __packed;
147028 +
147029 +struct qm_mcr_ceetm_ccgr_query {
147030 + u8 __reserved1[6];
147031 + union {
147032 + struct {
147033 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147034 + u8 ctl_reserved:1;
147035 + u8 ctl_wr_en_g:1;
147036 + u8 ctl_wr_en_y:1;
147037 + u8 ctl_wr_en_r:1;
147038 + u8 ctl_td_en:1;
147039 + u8 ctl_td_mode:1;
147040 + u8 ctl_cscn_en:1;
147041 + u8 ctl_mode:1;
147042 +#else
147043 + u8 ctl_mode:1;
147044 + u8 ctl_cscn_en:1;
147045 + u8 ctl_td_mode:1;
147046 + u8 ctl_td_en:1;
147047 + u8 ctl_wr_en_r:1;
147048 + u8 ctl_wr_en_y:1;
147049 + u8 ctl_wr_en_g:1;
147050 + u8 ctl_reserved:1;
147051 +#endif
147052 + u8 cdv;
147053 + u8 __reserved2[2];
147054 + u8 oal;
147055 + u8 __reserved3;
147056 + struct qm_cgr_cs_thres cs_thres;
147057 + struct qm_cgr_cs_thres cs_thres_x;
147058 + struct qm_cgr_cs_thres td_thres;
147059 + struct qm_cgr_wr_parm wr_parm_g;
147060 + struct qm_cgr_wr_parm wr_parm_y;
147061 + struct qm_cgr_wr_parm wr_parm_r;
147062 + u16 cscn_targ_dcp;
147063 + u8 dcp_lsn;
147064 + u64 i_cnt:40;
147065 + u8 __reserved4[3];
147066 + u64 a_cnt:40;
147067 + u32 cscn_targ_swp[4];
147068 + } __packed cm_query;
147069 + struct {
147070 + u8 dnc;
147071 + u8 dn0;
147072 + u8 dn1;
147073 + u64 dnba:40;
147074 + u8 __reserved2[2];
147075 + u16 dnth_0;
147076 + u8 __reserved3[2];
147077 + u16 dnth_1;
147078 + u8 __reserved4[10];
147079 + u16 dnacc_0;
147080 + u8 __reserved5[2];
147081 + u16 dnacc_1;
147082 + u8 __reserved6[24];
147083 + } __packed dn_query;
147084 + struct {
147085 + u8 __reserved2[24];
147086 + struct __qm_mcr_querycongestion state;
147087 + } __packed congestion_state;
147088 +
147089 + };
147090 +} __packed;
147091 +
147092 +struct qm_mcr_ceetm_cq_peek_pop_xsfdrread {
147093 + u8 stat;
147094 + u8 __reserved1[11];
147095 + u16 dctidx;
147096 + struct qm_fd fd;
147097 + u8 __reserved2[32];
147098 +} __packed;
147099 +
147100 +struct qm_mcr_ceetm_statistics_query {
147101 + u8 __reserved1[17];
147102 + u64 frm_cnt:40;
147103 + u8 __reserved2[2];
147104 + u64 byte_cnt:48;
147105 + u8 __reserved3[32];
147106 +} __packed;
147107 +
147108 +struct qm_mc_result {
147109 + u8 verb;
147110 + u8 result;
147111 + union {
147112 + struct qm_mcr_initfq initfq;
147113 + struct qm_mcr_queryfq queryfq;
147114 + struct qm_mcr_queryfq_np queryfq_np;
147115 + struct qm_mcr_alterfq alterfq;
147116 + struct qm_mcr_initcgr initcgr;
147117 + struct qm_mcr_cgrtestwrite cgrtestwrite;
147118 + struct qm_mcr_querycgr querycgr;
147119 + struct qm_mcr_querycongestion querycongestion;
147120 + struct qm_mcr_querywq querywq;
147121 + struct qm_mcr_ceetm_lfqmt_config lfqmt_config;
147122 + struct qm_mcr_ceetm_lfqmt_query lfqmt_query;
147123 + struct qm_mcr_ceetm_cq_config cq_config;
147124 + struct qm_mcr_ceetm_cq_query cq_query;
147125 + struct qm_mcr_ceetm_dct_config dct_config;
147126 + struct qm_mcr_ceetm_dct_query dct_query;
147127 + struct qm_mcr_ceetm_class_scheduler_config csch_config;
147128 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
147129 + struct qm_mcr_ceetm_mapping_shaper_tcfc_config mst_config;
147130 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query mst_query;
147131 + struct qm_mcr_ceetm_ccgr_config ccgr_config;
147132 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
147133 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
147134 + struct qm_mcr_ceetm_statistics_query stats_query;
147135 + };
147136 +} __packed;
147137 +
147138 +#define QM_MCR_VERB_RRID 0x80
147139 +#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK
147140 +#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED
147141 +#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED
147142 +#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ
147143 +#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP
147144 +#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ
147145 +#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED
147146 +#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED
147147 +#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE
147148 +#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE
147149 +#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS
147150 +#define QM_MCR_RESULT_NULL 0x00
147151 +#define QM_MCR_RESULT_OK 0xf0
147152 +#define QM_MCR_RESULT_ERR_FQID 0xf1
147153 +#define QM_MCR_RESULT_ERR_FQSTATE 0xf2
147154 +#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */
147155 +#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4
147156 +#define QM_MCR_RESULT_PENDING 0xf8
147157 +#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff
147158 +#define QM_MCR_NP_STATE_FE 0x10
147159 +#define QM_MCR_NP_STATE_R 0x08
147160 +#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */
147161 +#define QM_MCR_NP_STATE_OOS 0x00
147162 +#define QM_MCR_NP_STATE_RETIRED 0x01
147163 +#define QM_MCR_NP_STATE_TEN_SCHED 0x02
147164 +#define QM_MCR_NP_STATE_TRU_SCHED 0x03
147165 +#define QM_MCR_NP_STATE_PARKED 0x04
147166 +#define QM_MCR_NP_STATE_ACTIVE 0x05
147167 +#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */
147168 +#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */
147169 +#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */
147170 +#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */
147171 +#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */
147172 +#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
147173 +#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
147174 +/* This extracts the state for congestion group 'n' from a query response.
147175 + * Eg.
147176 + * u8 cgr = [...];
147177 + * struct qm_mc_result *res = [...];
147178 + * printf("congestion group %d congestion state: %d\n", cgr,
147179 + * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr));
147180 + */
147181 +#define __CGR_WORD(num) (num >> 5)
147182 +#define __CGR_SHIFT(num) (num & 0x1f)
147183 +#define __CGR_NUM (sizeof(struct __qm_mcr_querycongestion) << 3)
147184 +static inline int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p,
147185 + u8 cgr)
147186 +{
147187 + return p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr));
147188 +}
147189 +
147190 +
147191 +/*********************/
147192 +/* Utility interface */
147193 +/*********************/
147194 +
147195 +/* Represents an allocator over a range of FQIDs. NB, accesses are not locked,
147196 + * spinlock them yourself if needed. */
147197 +struct qman_fqid_pool;
147198 +
147199 +/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy()
147200 + * always succeeds, but returns non-zero if there were "leaked" FQID
147201 + * allocations. */
147202 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num);
147203 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool);
147204 +/* Alloc/free a FQID from the range. _alloc() returns zero for success. */
147205 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid);
147206 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid);
147207 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool);
147208 +
147209 +/*******************************************************************/
147210 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
147211 +/*******************************************************************/
147212 +
147213 + /* Portal and Frame Queues */
147214 + /* ----------------------- */
147215 +/* Represents a managed portal */
147216 +struct qman_portal;
147217 +
147218 +/* This object type represents Qman frame queue descriptors (FQD), it is
147219 + * cacheline-aligned, and initialised by qman_create_fq(). The structure is
147220 + * defined further down. */
147221 +struct qman_fq;
147222 +
147223 +/* This object type represents a Qman congestion group, it is defined further
147224 + * down. */
147225 +struct qman_cgr;
147226 +
147227 +struct qman_portal_config {
147228 + /* If the caller enables DQRR stashing (and thus wishes to operate the
147229 + * portal from only one cpu), this is the logical CPU that the portal
147230 + * will stash to. Whether stashing is enabled or not, this setting is
147231 + * also used for any "core-affine" portals, ie. default portals
147232 + * associated to the corresponding cpu. -1 implies that there is no core
147233 + * affinity configured. */
147234 + int cpu;
147235 + /* portal interrupt line */
147236 + int irq;
147237 + /* the unique index of this portal */
147238 + u32 index;
147239 + /* Is this portal shared? (If so, it has coarser locking and demuxes
147240 + * processing on behalf of other CPUs.) */
147241 + int is_shared;
147242 + /* The portal's dedicated channel id, use this value for initialising
147243 + * frame queues to target this portal when scheduled. */
147244 + u16 channel;
147245 + /* A mask of which pool channels this portal has dequeue access to
147246 + * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */
147247 + u32 pools;
147248 +};
147249 +
147250 +/* This enum, and the callback type that returns it, are used when handling
147251 + * dequeued frames via DQRR. Note that for "null" callbacks registered with the
147252 + * portal object (for handling dequeues that do not demux because contextB is
147253 + * NULL), the return value *MUST* be qman_cb_dqrr_consume. */
147254 +enum qman_cb_dqrr_result {
147255 + /* DQRR entry can be consumed */
147256 + qman_cb_dqrr_consume,
147257 + /* Like _consume, but requests parking - FQ must be held-active */
147258 + qman_cb_dqrr_park,
147259 + /* Does not consume, for DCA mode only. This allows out-of-order
147260 + * consumes by explicit calls to qman_dca() and/or the use of implicit
147261 + * DCA via EQCR entries. */
147262 + qman_cb_dqrr_defer,
147263 + /* Stop processing without consuming this ring entry. Exits the current
147264 + * qman_poll_dqrr() or interrupt-handling, as appropriate. If within an
147265 + * interrupt handler, the callback would typically call
147266 + * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value,
147267 + * otherwise the interrupt will reassert immediately. */
147268 + qman_cb_dqrr_stop,
147269 + /* Like qman_cb_dqrr_stop, but consumes the current entry. */
147270 + qman_cb_dqrr_consume_stop
147271 +};
147272 +typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm,
147273 + struct qman_fq *fq,
147274 + const struct qm_dqrr_entry *dqrr);
147275 +
147276 +/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
147277 + * are always consumed after the callback returns. */
147278 +typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq,
147279 + const struct qm_mr_entry *msg);
147280 +
147281 +/* This callback type is used when handling DCP ERNs */
147282 +typedef void (*qman_cb_dc_ern)(struct qman_portal *qm,
147283 + const struct qm_mr_entry *msg);
147284 +
147285 +/* s/w-visible states. Ie. tentatively scheduled + truly scheduled + active +
147286 + * held-active + held-suspended are just "sched". Things like "retired" will not
147287 + * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until
147288 + * then, to indicate it's completing and to gate attempts to retry the retire
147289 + * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's
147290 + * technically impossible in the case of enqueue DCAs (which refer to DQRR ring
147291 + * index rather than the FQ that ring entry corresponds to), so repeated park
147292 + * commands are allowed (if you're silly enough to try) but won't change FQ
147293 + * state, and the resulting park notifications move FQs from "sched" to
147294 + * "parked". */
147295 +enum qman_fq_state {
147296 + qman_fq_state_oos,
147297 + qman_fq_state_parked,
147298 + qman_fq_state_sched,
147299 + qman_fq_state_retired
147300 +};
147301 +
147302 +/* Frame queue objects (struct qman_fq) are stored within memory passed to
147303 + * qman_create_fq(), as this allows stashing of caller-provided demux callback
147304 + * pointers at no extra cost to stashing of (driver-internal) FQ state. If the
147305 + * caller wishes to add per-FQ state and have it benefit from dequeue-stashing,
147306 + * they should;
147307 + *
147308 + * (a) extend the qman_fq structure with their state; eg.
147309 + *
147310 + * // myfq is allocated and driver_fq callbacks filled in;
147311 + * struct my_fq {
147312 + * struct qman_fq base;
147313 + * int an_extra_field;
147314 + * [ ... add other fields to be associated with each FQ ...]
147315 + * } *myfq = some_my_fq_allocator();
147316 + * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base);
147317 + *
147318 + * // in a dequeue callback, access extra fields from 'fq' via a cast;
147319 + * struct my_fq *myfq = (struct my_fq *)fq;
147320 + * do_something_with(myfq->an_extra_field);
147321 + * [...]
147322 + *
147323 + * (b) when and if configuring the FQ for context stashing, specify how ever
147324 + * many cachelines are required to stash 'struct my_fq', to accelerate not
147325 + * only the Qman driver but the callback as well.
147326 + */
147327 +
147328 +struct qman_fq_cb {
147329 + qman_cb_dqrr dqrr; /* for dequeued frames */
147330 + qman_cb_mr ern; /* for s/w ERNs */
147331 + qman_cb_mr fqs; /* frame-queue state changes*/
147332 +};
147333 +
147334 +struct qman_fq {
147335 + /* Caller of qman_create_fq() provides these demux callbacks */
147336 + struct qman_fq_cb cb;
147337 + /* These are internal to the driver, don't touch. In particular, they
147338 + * may change, be removed, or extended (so you shouldn't rely on
147339 + * sizeof(qman_fq) being a constant). */
147340 + spinlock_t fqlock;
147341 + u32 fqid;
147342 + volatile unsigned long flags;
147343 + enum qman_fq_state state;
147344 + int cgr_groupid;
147345 + struct rb_node node;
147346 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
147347 + u32 key;
147348 +#endif
147349 +};
147350 +
147351 +/* This callback type is used when handling congestion group entry/exit.
147352 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. */
147353 +typedef void (*qman_cb_cgr)(struct qman_portal *qm,
147354 + struct qman_cgr *cgr, int congested);
147355 +
147356 +struct qman_cgr {
147357 + /* Set these prior to qman_create_cgr() */
147358 + u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/
147359 + qman_cb_cgr cb;
147360 + /* These are private to the driver */
147361 + u16 chan; /* portal channel this object is created on */
147362 + struct list_head node;
147363 +};
147364 +
147365 +/* Flags to qman_create_fq() */
147366 +#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */
147367 +#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */
147368 +#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */
147369 +#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */
147370 +#define QMAN_FQ_FLAG_AS_IS 0x00000010 /* query h/w state */
147371 +#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */
147372 +
147373 +/* Flags to qman_destroy_fq() */
147374 +#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */
147375 +
147376 +/* Flags from qman_fq_state() */
147377 +#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */
147378 +#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */
147379 +#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */
147380 +#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */
147381 +#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */
147382 +#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */
147383 +
147384 +/* Flags to qman_init_fq() */
147385 +#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */
147386 +#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */
147387 +
147388 +/* Flags to qman_volatile_dequeue() */
147389 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
147390 +#define QMAN_VOLATILE_FLAG_WAIT 0x00000001 /* wait if VDQCR is in use */
147391 +#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000002 /* if wait, interruptible? */
147392 +#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */
147393 +#endif
147394 +
147395 +/* Flags to qman_enqueue(). NB, the strange numbering is to align with hardware,
147396 + * bit-wise. (NB: the PME API is sensitive to these precise numberings too, so
147397 + * any change here should be audited in PME.) */
147398 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
147399 +#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */
147400 +#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */
147401 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
147402 +#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
147403 +#endif
147404 +#endif
147405 +#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */
147406 +#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */
147407 +#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */
147408 +#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \
147409 + (((u32)(p) << 2) & 0x00000f00)
147410 +#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */
147411 +#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008
147412 +#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010
147413 +#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018
147414 +/* For the ORP-specific qman_enqueue_orp() variant;
147415 + * - this flag indicates "Not Last In Sequence", ie. all but the final fragment
147416 + * of a frame. */
147417 +#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000
147418 +/* - this flag performs no enqueue but fills in an ORP sequence number that
147419 + * would otherwise block it (eg. if a frame has been dropped). */
147420 +#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000
147421 +/* - this flag performs no enqueue but advances NESN to the given sequence
147422 + * number. */
147423 +#define QMAN_ENQUEUE_FLAG_NESN 0x04000000
147424 +
147425 +/* Flags to qman_modify_cgr() */
147426 +#define QMAN_CGR_FLAG_USE_INIT 0x00000001
147427 +#define QMAN_CGR_MODE_FRAME 0x00000001
147428 +
147429 + /* Portal Management */
147430 + /* ----------------- */
147431 +/**
147432 + * qman_get_portal_config - get portal configuration settings
147433 + *
147434 + * This returns a read-only view of the current cpu's affine portal settings.
147435 + */
147436 +const struct qman_portal_config *qman_get_portal_config(void);
147437 +
147438 +/**
147439 + * qman_irqsource_get - return the portal work that is interrupt-driven
147440 + *
147441 + * Returns a bitmask of QM_PIRQ_**I processing sources that are currently
147442 + * enabled for interrupt handling on the current cpu's affine portal. These
147443 + * sources will trigger the portal interrupt and the interrupt handler (or a
147444 + * tasklet/bottom-half it defers to) will perform the corresponding processing
147445 + * work. The qman_poll_***() functions will only process sources that are not in
147446 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
147447 + * this always returns zero.
147448 + */
147449 +u32 qman_irqsource_get(void);
147450 +
147451 +/**
147452 + * qman_irqsource_add - add processing sources to be interrupt-driven
147453 + * @bits: bitmask of QM_PIRQ_**I processing sources
147454 + *
147455 + * Adds processing sources that should be interrupt-driven (rather than
147456 + * processed via qman_poll_***() functions). Returns zero for success, or
147457 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU.
147458 + */
147459 +int qman_irqsource_add(u32 bits);
147460 +
147461 +/**
147462 + * qman_irqsource_remove - remove processing sources from being interrupt-driven
147463 + * @bits: bitmask of QM_PIRQ_**I processing sources
147464 + *
147465 + * Removes processing sources from being interrupt-driven, so that they will
147466 + * instead be processed via qman_poll_***() functions. Returns zero for success,
147467 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU.
147468 + */
147469 +int qman_irqsource_remove(u32 bits);
147470 +
147471 +/**
147472 + * qman_affine_cpus - return a mask of cpus that have affine portals
147473 + */
147474 +const cpumask_t *qman_affine_cpus(void);
147475 +
147476 +/**
147477 + * qman_affine_channel - return the channel ID of an portal
147478 + * @cpu: the cpu whose affine portal is the subject of the query
147479 + *
147480 + * If @cpu is -1, the affine portal for the current CPU will be used. It is a
147481 + * bug to call this function for any value of @cpu (other than -1) that is not a
147482 + * member of the mask returned from qman_affine_cpus().
147483 + */
147484 +u16 qman_affine_channel(int cpu);
147485 +
147486 +/**
147487 + * qman_get_affine_portal - return the portal pointer affine to cpu
147488 + * @cpu: the cpu whose affine portal is the subject of the query
147489 + *
147490 + */
147491 +void *qman_get_affine_portal(int cpu);
147492 +
147493 +/**
147494 + * qman_poll_dqrr - process DQRR (fast-path) entries
147495 + * @limit: the maximum number of DQRR entries to process
147496 + *
147497 + * Use of this function requires that DQRR processing not be interrupt-driven.
147498 + * Ie. the value returned by qman_irqsource_get() should not include
147499 + * QM_PIRQ_DQRI. If the current CPU is sharing a portal hosted on another CPU,
147500 + * this function will return -EINVAL, otherwise the return value is >=0 and
147501 + * represents the number of DQRR entries processed.
147502 + */
147503 +int qman_poll_dqrr(unsigned int limit);
147504 +
147505 +/**
147506 + * qman_poll_slow - process anything (except DQRR) that isn't interrupt-driven.
147507 + *
147508 + * This function does any portal processing that isn't interrupt-driven. If the
147509 + * current CPU is sharing a portal hosted on another CPU, this function will
147510 + * return (u32)-1, otherwise the return value is a bitmask of QM_PIRQ_* sources
147511 + * indicating what interrupt sources were actually processed by the call.
147512 + */
147513 +u32 qman_poll_slow(void);
147514 +
147515 +/**
147516 + * qman_poll - legacy wrapper for qman_poll_dqrr() and qman_poll_slow()
147517 + *
147518 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
147519 + * affine portal. There are two classes of portal processing in question;
147520 + * fast-path (which involves demuxing dequeue ring (DQRR) entries and tracking
147521 + * enqueue ring (EQCR) consumption), and slow-path (which involves EQCR
147522 + * thresholds, congestion state changes, etc). This function does whatever
147523 + * processing is not triggered by interrupts.
147524 + *
147525 + * Note, if DQRR and some slow-path processing are poll-driven (rather than
147526 + * interrupt-driven) then this function uses a heuristic to determine how often
147527 + * to run slow-path processing - as slow-path processing introduces at least a
147528 + * minimum latency each time it is run, whereas fast-path (DQRR) processing is
147529 + * close to zero-cost if there is no work to be done. Applications can tune this
147530 + * behaviour themselves by using qman_poll_dqrr() and qman_poll_slow() directly
147531 + * rather than going via this wrapper.
147532 + */
147533 +void qman_poll(void);
147534 +
147535 +/**
147536 + * qman_stop_dequeues - Stop h/w dequeuing to the s/w portal
147537 + *
147538 + * Disables DQRR processing of the portal. This is reference-counted, so
147539 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
147540 + * truly re-enable dequeuing.
147541 + */
147542 +void qman_stop_dequeues(void);
147543 +
147544 +/**
147545 + * qman_start_dequeues - (Re)start h/w dequeuing to the s/w portal
147546 + *
147547 + * Enables DQRR processing of the portal. This is reference-counted, so
147548 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
147549 + * truly re-enable dequeuing.
147550 + */
147551 +void qman_start_dequeues(void);
147552 +
147553 +/**
147554 + * qman_static_dequeue_add - Add pool channels to the portal SDQCR
147555 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
147556 + *
147557 + * Adds a set of pool channels to the portal's static dequeue command register
147558 + * (SDQCR). The requested pools are limited to those the portal has dequeue
147559 + * access to.
147560 + */
147561 +void qman_static_dequeue_add(u32 pools);
147562 +
147563 +/**
147564 + * qman_static_dequeue_del - Remove pool channels from the portal SDQCR
147565 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
147566 + *
147567 + * Removes a set of pool channels from the portal's static dequeue command
147568 + * register (SDQCR). The requested pools are limited to those the portal has
147569 + * dequeue access to.
147570 + */
147571 +void qman_static_dequeue_del(u32 pools);
147572 +
147573 +/**
147574 + * qman_static_dequeue_get - return the portal's current SDQCR
147575 + *
147576 + * Returns the portal's current static dequeue command register (SDQCR). The
147577 + * entire register is returned, so if only the currently-enabled pool channels
147578 + * are desired, mask the return value with QM_SDQCR_CHANNELS_POOL_MASK.
147579 + */
147580 +u32 qman_static_dequeue_get(void);
147581 +
147582 +/**
147583 + * qman_dca - Perform a Discrete Consumption Acknowledgement
147584 + * @dq: the DQRR entry to be consumed
147585 + * @park_request: indicates whether the held-active @fq should be parked
147586 + *
147587 + * Only allowed in DCA-mode portals, for DQRR entries whose handler callback had
147588 + * previously returned 'qman_cb_dqrr_defer'. NB, as with the other APIs, this
147589 + * does not take a 'portal' argument but implies the core affine portal from the
147590 + * cpu that is currently executing the function. For reasons of locking, this
147591 + * function must be called from the same CPU as that which processed the DQRR
147592 + * entry in the first place.
147593 + */
147594 +void qman_dca(struct qm_dqrr_entry *dq, int park_request);
147595 +
147596 +/**
147597 + * qman_eqcr_is_empty - Determine if portal's EQCR is empty
147598 + *
147599 + * For use in situations where a cpu-affine caller needs to determine when all
147600 + * enqueues for the local portal have been processed by Qman but can't use the
147601 + * QMAN_ENQUEUE_FLAG_WAIT_SYNC flag to do this from the final qman_enqueue().
147602 + * The function forces tracking of EQCR consumption (which normally doesn't
147603 + * happen until enqueue processing needs to find space to put new enqueue
147604 + * commands), and returns zero if the ring still has unprocessed entries,
147605 + * non-zero if it is empty.
147606 + */
147607 +int qman_eqcr_is_empty(void);
147608 +
147609 +/**
147610 + * qman_set_dc_ern - Set the handler for DCP enqueue rejection notifications
147611 + * @handler: callback for processing DCP ERNs
147612 + * @affine: whether this handler is specific to the locally affine portal
147613 + *
147614 + * If a hardware block's interface to Qman (ie. its direct-connect portal, or
147615 + * DCP) is configured not to receive enqueue rejections, then any enqueues
147616 + * through that DCP that are rejected will be sent to a given software portal.
147617 + * If @affine is non-zero, then this handler will only be used for DCP ERNs
147618 + * received on the portal affine to the current CPU. If multiple CPUs share a
147619 + * portal and they all call this function, they will be setting the handler for
147620 + * the same portal! If @affine is zero, then this handler will be global to all
147621 + * portals handled by this instance of the driver. Only those portals that do
147622 + * not have their own affine handler will use the global handler.
147623 + */
147624 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine);
147625 +
147626 + /* FQ management */
147627 + /* ------------- */
147628 +/**
147629 + * qman_create_fq - Allocates a FQ
147630 + * @fqid: the index of the FQD to encapsulate, must be "Out of Service"
147631 + * @flags: bit-mask of QMAN_FQ_FLAG_*** options
147632 + * @fq: memory for storing the 'fq', with callbacks filled in
147633 + *
147634 + * Creates a frame queue object for the given @fqid, unless the
147635 + * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is
147636 + * dynamically allocated (or the function fails if none are available). Once
147637 + * created, the caller should not touch the memory at 'fq' except as extended to
147638 + * adjacent memory for user-defined fields (see the definition of "struct
147639 + * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to
147640 + * pre-existing frame-queues that aren't to be otherwise interfered with, it
147641 + * prevents all other modifications to the frame queue. The TO_DCPORTAL flag
147642 + * causes the driver to honour any contextB modifications requested in the
147643 + * qm_init_fq() API, as this indicates the frame queue will be consumed by a
147644 + * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by
147645 + * software portals, the contextB field is controlled by the driver and can't be
147646 + * modified by the caller. If the AS_IS flag is specified, management commands
147647 + * will be used on portal @p to query state for frame queue @fqid and construct
147648 + * a frame queue object based on that, rather than assuming/requiring that it be
147649 + * Out of Service.
147650 + */
147651 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq);
147652 +
147653 +/**
147654 + * qman_destroy_fq - Deallocates a FQ
147655 + * @fq: the frame queue object to release
147656 + * @flags: bit-mask of QMAN_FQ_FREE_*** options
147657 + *
147658 + * The memory for this frame queue object ('fq' provided in qman_create_fq()) is
147659 + * not deallocated but the caller regains ownership, to do with as desired. The
147660 + * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag
147661 + * is specified, in which case it may also be in the 'parked' state.
147662 + */
147663 +void qman_destroy_fq(struct qman_fq *fq, u32 flags);
147664 +
147665 +/**
147666 + * qman_fq_fqid - Queries the frame queue ID of a FQ object
147667 + * @fq: the frame queue object to query
147668 + */
147669 +u32 qman_fq_fqid(struct qman_fq *fq);
147670 +
147671 +/**
147672 + * qman_fq_state - Queries the state of a FQ object
147673 + * @fq: the frame queue object to query
147674 + * @state: pointer to state enum to return the FQ scheduling state
147675 + * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask
147676 + *
147677 + * Queries the state of the FQ object, without performing any h/w commands.
147678 + * This captures the state, as seen by the driver, at the time the function
147679 + * executes.
147680 + */
147681 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags);
147682 +
147683 +/**
147684 + * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled"
147685 + * @fq: the frame queue object to modify, must be 'parked' or new.
147686 + * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options
147687 + * @opts: the FQ-modification settings, as defined in the low-level API
147688 + *
147689 + * The @opts parameter comes from the low-level portal API. Select
147690 + * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled
147691 + * rather than parked. NB, @opts can be NULL.
147692 + *
147693 + * Note that some fields and options within @opts may be ignored or overwritten
147694 + * by the driver;
147695 + * 1. the 'count' and 'fqid' fields are always ignored (this operation only
147696 + * affects one frame queue: @fq).
147697 + * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated
147698 + * 'fqd' structure's 'context_b' field are sometimes overwritten;
147699 + * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is
147700 + * initialised to a value used by the driver for demux.
147701 + * - if context_b is initialised for demux, so is context_a in case stashing
147702 + * is requested (see item 4).
147703 + * (So caller control of context_b is only possible for TO_DCPORTAL frame queue
147704 + * objects.)
147705 + * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's
147706 + * 'dest::channel' field will be overwritten to match the portal used to issue
147707 + * the command. If the WE_DESTWQ write-enable bit had already been set by the
147708 + * caller, the channel workqueue will be left as-is, otherwise the write-enable
147709 + * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag
147710 + * isn't set, the destination channel/workqueue fields and the write-enable bit
147711 + * are left as-is.
147712 + * 4. if the driver overwrites context_a/b for demux, then if
147713 + * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite
147714 + * context_a.address fields and will leave the stashing fields provided by the
147715 + * user alone, otherwise it will zero out the context_a.stashing fields.
147716 + */
147717 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts);
147718 +
147719 +/**
147720 + * qman_schedule_fq - Schedules a FQ
147721 + * @fq: the frame queue object to schedule, must be 'parked'
147722 + *
147723 + * Schedules the frame queue, which must be Parked, which takes it to
147724 + * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level.
147725 + */
147726 +int qman_schedule_fq(struct qman_fq *fq);
147727 +
147728 +/**
147729 + * qman_retire_fq - Retires a FQ
147730 + * @fq: the frame queue object to retire
147731 + * @flags: FQ flags (as per qman_fq_state) if retirement completes immediately
147732 + *
147733 + * Retires the frame queue. This returns zero if it succeeds immediately, +1 if
147734 + * the retirement was started asynchronously, otherwise it returns negative for
147735 + * failure. When this function returns zero, @flags is set to indicate whether
147736 + * the retired FQ is empty and/or whether it has any ORL fragments (to show up
147737 + * as ERNs). Otherwise the corresponding flags will be known when a subsequent
147738 + * FQRN message shows up on the portal's message ring.
147739 + *
147740 + * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or
147741 + * Active state), the completion will be via the message ring as a FQRN - but
147742 + * the corresponding callback may occur before this function returns!! Ie. the
147743 + * caller should be prepared to accept the callback as the function is called,
147744 + * not only once it has returned.
147745 + */
147746 +int qman_retire_fq(struct qman_fq *fq, u32 *flags);
147747 +
147748 +/**
147749 + * qman_oos_fq - Puts a FQ "out of service"
147750 + * @fq: the frame queue object to be put out-of-service, must be 'retired'
147751 + *
147752 + * The frame queue must be retired and empty, and if any order restoration list
147753 + * was released as ERNs at the time of retirement, they must all be consumed.
147754 + */
147755 +int qman_oos_fq(struct qman_fq *fq);
147756 +
147757 +/**
147758 + * qman_fq_flow_control - Set the XON/XOFF state of a FQ
147759 + * @fq: the frame queue object to be set to XON/XOFF state, must not be 'oos',
147760 + * or 'retired' or 'parked' state
147761 + * @xon: boolean to set fq in XON or XOFF state
147762 + *
147763 + * The frame should be in Tentatively Scheduled state or Truly Schedule sate,
147764 + * otherwise the IFSI interrupt will be asserted.
147765 + */
147766 +int qman_fq_flow_control(struct qman_fq *fq, int xon);
147767 +
147768 +/**
147769 + * qman_query_fq - Queries FQD fields (via h/w query command)
147770 + * @fq: the frame queue object to be queried
147771 + * @fqd: storage for the queried FQD fields
147772 + */
147773 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd);
147774 +
147775 +/**
147776 + * qman_query_fq_np - Queries non-programmable FQD fields
147777 + * @fq: the frame queue object to be queried
147778 + * @np: storage for the queried FQD fields
147779 + */
147780 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np);
147781 +
147782 +/**
147783 + * qman_query_wq - Queries work queue lengths
147784 + * @query_dedicated: If non-zero, query length of WQs in the channel dedicated
147785 + * to this software portal. Otherwise, query length of WQs in a
147786 + * channel specified in wq.
147787 + * @wq: storage for the queried WQs lengths. Also specified the channel to
147788 + * to query if query_dedicated is zero.
147789 + */
147790 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq);
147791 +
147792 +/**
147793 + * qman_volatile_dequeue - Issue a volatile dequeue command
147794 + * @fq: the frame queue object to dequeue from
147795 + * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options
147796 + * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set()
147797 + *
147798 + * Attempts to lock access to the portal's VDQCR volatile dequeue functionality.
147799 + * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and
147800 + * the VDQCR is already in use, otherwise returns non-zero for failure. If
147801 + * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once
147802 + * the VDQCR command has finished executing (ie. once the callback for the last
147803 + * DQRR entry resulting from the VDQCR command has been called). If not using
147804 + * the FINISH flag, completion can be determined either by detecting the
147805 + * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits
147806 + * in the "stat" field of the "struct qm_dqrr_entry" passed to the FQ's dequeue
147807 + * callback, or by waiting for the QMAN_FQ_STATE_VDQCR bit to disappear from the
147808 + * "flags" retrieved from qman_fq_state().
147809 + */
147810 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr);
147811 +
147812 +/**
147813 + * qman_enqueue - Enqueue a frame to a frame queue
147814 + * @fq: the frame queue object to enqueue to
147815 + * @fd: a descriptor of the frame to be enqueued
147816 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147817 + *
147818 + * Fills an entry in the EQCR of portal @qm to enqueue the frame described by
147819 + * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid'
147820 + * field is ignored. The return value is non-zero on error, such as ring full
147821 + * (and FLAG_WAIT not specified), congestion avoidance (FLAG_WATCH_CGR
147822 + * specified), etc. If the ring is full and FLAG_WAIT is specified, this
147823 + * function will block. If FLAG_INTERRUPT is set, the EQCI bit of the portal
147824 + * interrupt will assert when Qman consumes the EQCR entry (subject to "status
147825 + * disable", "enable", and "inhibit" registers). If FLAG_DCA is set, Qman will
147826 + * perform an implied "discrete consumption acknowledgement" on the dequeue
147827 + * ring's (DQRR) entry, at the ring index specified by the FLAG_DCA_IDX(x)
147828 + * macro. (As an alternative to issuing explicit DCA actions on DQRR entries,
147829 + * this implicit DCA can delay the release of a "held active" frame queue
147830 + * corresponding to a DQRR entry until Qman consumes the EQCR entry - providing
147831 + * order-preservation semantics in packet-forwarding scenarios.) If FLAG_DCA is
147832 + * set, then FLAG_DCA_PARK can also be set to imply that the DQRR consumption
147833 + * acknowledgement should "park request" the "held active" frame queue. Ie.
147834 + * when the portal eventually releases that frame queue, it will be left in the
147835 + * Parked state rather than Tentatively Scheduled or Truly Scheduled. If the
147836 + * portal is watching congestion groups, the QMAN_ENQUEUE_FLAG_WATCH_CGR flag
147837 + * is requested, and the FQ is a member of a congestion group, then this
147838 + * function returns -EAGAIN if the congestion group is currently congested.
147839 + * Note, this does not eliminate ERNs, as the async interface means we can be
147840 + * sending enqueue commands to an un-congested FQ that becomes congested before
147841 + * the enqueue commands are processed, but it does minimise needless thrashing
147842 + * of an already busy hardware resource by throttling many of the to-be-dropped
147843 + * enqueues "at the source".
147844 + */
147845 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags);
147846 +
147847 +typedef int (*qman_cb_precommit) (void *arg);
147848 +/**
147849 + * qman_enqueue_precommit - Enqueue a frame to a frame queue and call cb
147850 + * @fq: the frame queue object to enqueue to
147851 + * @fd: a descriptor of the frame to be enqueued
147852 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147853 + * @cb: user supplied callback function to invoke before writing commit verb.
147854 + * @cb_arg: callback function argument
147855 + *
147856 + * This is similar to qman_enqueue except that it will invoke a user supplied
147857 + * callback function just before writng the commit verb. This is useful
147858 + * when the user want to do something *just before* enqueuing the request and
147859 + * the enqueue can't fail.
147860 + */
147861 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
147862 + u32 flags, qman_cb_precommit cb, void *cb_arg);
147863 +
147864 +/**
147865 + * qman_enqueue_orp - Enqueue a frame to a frame queue using an ORP
147866 + * @fq: the frame queue object to enqueue to
147867 + * @fd: a descriptor of the frame to be enqueued
147868 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147869 + * @orp: the frame queue object used as an order restoration point.
147870 + * @orp_seqnum: the sequence number of this frame in the order restoration path
147871 + *
147872 + * Similar to qman_enqueue(), but with the addition of an Order Restoration
147873 + * Point (@orp) and corresponding sequence number (@orp_seqnum) for this
147874 + * enqueue operation to employ order restoration. Each frame queue object acts
147875 + * as an Order Definition Point (ODP) by providing each frame dequeued from it
147876 + * with an incrementing sequence number, this value is generally ignored unless
147877 + * that sequence of dequeued frames will need order restoration later. Each
147878 + * frame queue object also encapsulates an Order Restoration Point (ORP), which
147879 + * is a re-assembly context for re-ordering frames relative to their sequence
147880 + * numbers as they are enqueued. The ORP does not have to be within the frame
147881 + * queue that receives the enqueued frame, in fact it is usually the frame
147882 + * queue from which the frames were originally dequeued. For the purposes of
147883 + * order restoration, multiple frames (or "fragments") can be enqueued for a
147884 + * single sequence number by setting the QMAN_ENQUEUE_FLAG_NLIS flag for all
147885 + * enqueues except the final fragment of a given sequence number. Ordering
147886 + * between sequence numbers is guaranteed, even if fragments of different
147887 + * sequence numbers are interlaced with one another. Fragments of the same
147888 + * sequence number will retain the order in which they are enqueued. If no
147889 + * enqueue is to performed, QMAN_ENQUEUE_FLAG_HOLE indicates that the given
147890 + * sequence number is to be "skipped" by the ORP logic (eg. if a frame has been
147891 + * dropped from a sequence), or QMAN_ENQUEUE_FLAG_NESN indicates that the given
147892 + * sequence number should become the ORP's "Next Expected Sequence Number".
147893 + *
147894 + * Side note: a frame queue object can be used purely as an ORP, without
147895 + * carrying any frames at all. Care should be taken not to deallocate a frame
147896 + * queue object that is being actively used as an ORP, as a future allocation
147897 + * of the frame queue object may start using the internal ORP before the
147898 + * previous use has finished.
147899 + */
147900 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
147901 + struct qman_fq *orp, u16 orp_seqnum);
147902 +
147903 +/**
147904 + * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs
147905 + * @result: is set by the API to the base FQID of the allocated range
147906 + * @count: the number of FQIDs required
147907 + * @align: required alignment of the allocated range
147908 + * @partial: non-zero if the API can return fewer than @count FQIDs
147909 + *
147910 + * Returns the number of frame queues allocated, or a negative error code. If
147911 + * @partial is non zero, the allocation request may return a smaller range of
147912 + * FQs than requested (though alignment will be as requested). If @partial is
147913 + * zero, the return value will either be 'count' or negative.
147914 + */
147915 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial);
147916 +static inline int qman_alloc_fqid(u32 *result)
147917 +{
147918 + int ret = qman_alloc_fqid_range(result, 1, 0, 0);
147919 + return (ret > 0) ? 0 : ret;
147920 +}
147921 +
147922 +/**
147923 + * qman_release_fqid_range - Release the specified range of frame queue IDs
147924 + * @fqid: the base FQID of the range to deallocate
147925 + * @count: the number of FQIDs in the range
147926 + *
147927 + * This function can also be used to seed the allocator with ranges of FQIDs
147928 + * that it can subsequently allocate from.
147929 + */
147930 +void qman_release_fqid_range(u32 fqid, unsigned int count);
147931 +static inline void qman_release_fqid(u32 fqid)
147932 +{
147933 + qman_release_fqid_range(fqid, 1);
147934 +}
147935 +
147936 +void qman_seed_fqid_range(u32 fqid, unsigned int count);
147937 +
147938 +
147939 +int qman_shutdown_fq(u32 fqid);
147940 +
147941 +/**
147942 + * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
147943 + * @fqid: the base FQID of the range to deallocate
147944 + * @count: the number of FQIDs in the range
147945 + */
147946 +int qman_reserve_fqid_range(u32 fqid, unsigned int count);
147947 +static inline int qman_reserve_fqid(u32 fqid)
147948 +{
147949 + return qman_reserve_fqid_range(fqid, 1);
147950 +}
147951 +
147952 + /* Pool-channel management */
147953 + /* ----------------------- */
147954 +/**
147955 + * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs
147956 + * @result: is set by the API to the base pool-channel ID of the allocated range
147957 + * @count: the number of pool-channel IDs required
147958 + * @align: required alignment of the allocated range
147959 + * @partial: non-zero if the API can return fewer than @count
147960 + *
147961 + * Returns the number of pool-channel IDs allocated, or a negative error code.
147962 + * If @partial is non zero, the allocation request may return a smaller range of
147963 + * than requested (though alignment will be as requested). If @partial is zero,
147964 + * the return value will either be 'count' or negative.
147965 + */
147966 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial);
147967 +static inline int qman_alloc_pool(u32 *result)
147968 +{
147969 + int ret = qman_alloc_pool_range(result, 1, 0, 0);
147970 + return (ret > 0) ? 0 : ret;
147971 +}
147972 +
147973 +/**
147974 + * qman_release_pool_range - Release the specified range of pool-channel IDs
147975 + * @id: the base pool-channel ID of the range to deallocate
147976 + * @count: the number of pool-channel IDs in the range
147977 + */
147978 +void qman_release_pool_range(u32 id, unsigned int count);
147979 +static inline void qman_release_pool(u32 id)
147980 +{
147981 + qman_release_pool_range(id, 1);
147982 +}
147983 +
147984 +/**
147985 + * qman_reserve_pool_range - Reserve the specified range of pool-channel IDs
147986 + * @id: the base pool-channel ID of the range to reserve
147987 + * @count: the number of pool-channel IDs in the range
147988 + */
147989 +int qman_reserve_pool_range(u32 id, unsigned int count);
147990 +static inline int qman_reserve_pool(u32 id)
147991 +{
147992 + return qman_reserve_pool_range(id, 1);
147993 +}
147994 +
147995 +void qman_seed_pool_range(u32 id, unsigned int count);
147996 +
147997 + /* CGR management */
147998 + /* -------------- */
147999 +/**
148000 + * qman_create_cgr - Register a congestion group object
148001 + * @cgr: the 'cgr' object, with fields filled in
148002 + * @flags: QMAN_CGR_FLAG_* values
148003 + * @opts: optional state of CGR settings
148004 + *
148005 + * Registers this object to receiving congestion entry/exit callbacks on the
148006 + * portal affine to the cpu portal on which this API is executed. If opts is
148007 + * NULL then only the callback (cgr->cb) function is registered. If @flags
148008 + * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset
148009 + * any unspecified parameters) will be used rather than a modify hw hardware
148010 + * (which only modifies the specified parameters).
148011 + */
148012 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
148013 + struct qm_mcc_initcgr *opts);
148014 +
148015 +/**
148016 + * qman_create_cgr_to_dcp - Register a congestion group object to DCP portal
148017 + * @cgr: the 'cgr' object, with fields filled in
148018 + * @flags: QMAN_CGR_FLAG_* values
148019 + * @dcp_portal: the DCP portal to which the cgr object is registered.
148020 + * @opts: optional state of CGR settings
148021 + *
148022 + */
148023 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
148024 + struct qm_mcc_initcgr *opts);
148025 +
148026 +/**
148027 + * qman_delete_cgr - Deregisters a congestion group object
148028 + * @cgr: the 'cgr' object to deregister
148029 + *
148030 + * "Unplugs" this CGR object from the portal affine to the cpu on which this API
148031 + * is executed. This must be excuted on the same affine portal on which it was
148032 + * created.
148033 + */
148034 +int qman_delete_cgr(struct qman_cgr *cgr);
148035 +
148036 +/**
148037 + * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU
148038 + * @cgr: the 'cgr' object to deregister
148039 + *
148040 + * This will select the proper CPU and run there qman_delete_cgr().
148041 + */
148042 +void qman_delete_cgr_safe(struct qman_cgr *cgr);
148043 +
148044 +/**
148045 + * qman_modify_cgr - Modify CGR fields
148046 + * @cgr: the 'cgr' object to modify
148047 + * @flags: QMAN_CGR_FLAG_* values
148048 + * @opts: the CGR-modification settings
148049 + *
148050 + * The @opts parameter comes from the low-level portal API, and can be NULL.
148051 + * Note that some fields and options within @opts may be ignored or overwritten
148052 + * by the driver, in particular the 'cgrid' field is ignored (this operation
148053 + * only affects the given CGR object). If @flags contains
148054 + * QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset any
148055 + * unspecified parameters) will be used rather than a modify hw hardware (which
148056 + * only modifies the specified parameters).
148057 + */
148058 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
148059 + struct qm_mcc_initcgr *opts);
148060 +
148061 +/**
148062 +* qman_query_cgr - Queries CGR fields
148063 +* @cgr: the 'cgr' object to query
148064 +* @result: storage for the queried congestion group record
148065 +*/
148066 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *result);
148067 +
148068 +/**
148069 + * qman_query_congestion - Queries the state of all congestion groups
148070 + * @congestion: storage for the queried state of all congestion groups
148071 + */
148072 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion);
148073 +
148074 +/**
148075 + * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs
148076 + * @result: is set by the API to the base CGR ID of the allocated range
148077 + * @count: the number of CGR IDs required
148078 + * @align: required alignment of the allocated range
148079 + * @partial: non-zero if the API can return fewer than @count
148080 + *
148081 + * Returns the number of CGR IDs allocated, or a negative error code.
148082 + * If @partial is non zero, the allocation request may return a smaller range of
148083 + * than requested (though alignment will be as requested). If @partial is zero,
148084 + * the return value will either be 'count' or negative.
148085 + */
148086 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial);
148087 +static inline int qman_alloc_cgrid(u32 *result)
148088 +{
148089 + int ret = qman_alloc_cgrid_range(result, 1, 0, 0);
148090 + return (ret > 0) ? 0 : ret;
148091 +}
148092 +
148093 +/**
148094 + * qman_release_cgrid_range - Release the specified range of CGR IDs
148095 + * @id: the base CGR ID of the range to deallocate
148096 + * @count: the number of CGR IDs in the range
148097 + */
148098 +void qman_release_cgrid_range(u32 id, unsigned int count);
148099 +static inline void qman_release_cgrid(u32 id)
148100 +{
148101 + qman_release_cgrid_range(id, 1);
148102 +}
148103 +
148104 +/**
148105 + * qman_reserve_cgrid_range - Reserve the specified range of CGR ID
148106 + * @id: the base CGR ID of the range to reserve
148107 + * @count: the number of CGR IDs in the range
148108 + */
148109 +int qman_reserve_cgrid_range(u32 id, unsigned int count);
148110 +static inline int qman_reserve_cgrid(u32 id)
148111 +{
148112 + return qman_reserve_cgrid_range(id, 1);
148113 +}
148114 +
148115 +void qman_seed_cgrid_range(u32 id, unsigned int count);
148116 +
148117 +
148118 + /* Helpers */
148119 + /* ------- */
148120 +/**
148121 + * qman_poll_fq_for_init - Check if an FQ has been initialised from OOS
148122 + * @fqid: the FQID that will be initialised by other s/w
148123 + *
148124 + * In many situations, a FQID is provided for communication between s/w
148125 + * entities, and whilst the consumer is responsible for initialising and
148126 + * scheduling the FQ, the producer(s) generally create a wrapper FQ object using
148127 + * and only call qman_enqueue() (no FQ initialisation, scheduling, etc). Ie;
148128 + * qman_create_fq(..., QMAN_FQ_FLAG_NO_MODIFY, ...);
148129 + * However, data can not be enqueued to the FQ until it is initialised out of
148130 + * the OOS state - this function polls for that condition. It is particularly
148131 + * useful for users of IPC functions - each endpoint's Rx FQ is the other
148132 + * endpoint's Tx FQ, so each side can initialise and schedule their Rx FQ object
148133 + * and then use this API on the (NO_MODIFY) Tx FQ object in order to
148134 + * synchronise. The function returns zero for success, +1 if the FQ is still in
148135 + * the OOS state, or negative if there was an error.
148136 + */
148137 +static inline int qman_poll_fq_for_init(struct qman_fq *fq)
148138 +{
148139 + struct qm_mcr_queryfq_np np;
148140 + int err;
148141 + err = qman_query_fq_np(fq, &np);
148142 + if (err)
148143 + return err;
148144 + if ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS)
148145 + return 1;
148146 + return 0;
148147 +}
148148 +
148149 + /* -------------- */
148150 + /* CEETM :: types */
148151 + /* -------------- */
148152 +/**
148153 + * Token Rate Structure
148154 + * Shaping rates are based on a "credit" system and a pre-configured h/w
148155 + * internal timer. The following type represents a shaper "rate" parameter as a
148156 + * fractional number of "tokens". Here's how it works. This (fractional) number
148157 + * of tokens is added to the shaper's "credit" every time the h/w timer elapses
148158 + * (up to a limit which is set by another shaper parameter). Every time a frame
148159 + * is enqueued through a shaper, the shaper deducts as many tokens as there are
148160 + * bytes of data in the enqueued frame. A shaper will not allow itself to
148161 + * enqueue any frames if its token count is negative. As such;
148162 + *
148163 + * The rate at which data is enqueued is limited by the
148164 + * rate at which tokens are added.
148165 + *
148166 + * Therefore if the user knows the period between these h/w timer updates in
148167 + * seconds, they can calculate the maximum traffic rate of the shaper (in
148168 + * bytes-per-second) from the token rate. And vice versa, they can calculate
148169 + * the token rate to use in order to achieve a given traffic rate.
148170 + */
148171 +struct qm_ceetm_rate {
148172 + /* The token rate is; whole + (fraction/8192) */
148173 + u32 whole:11; /* 0..2047 */
148174 + u32 fraction:13; /* 0..8191 */
148175 +};
148176 +
148177 +struct qm_ceetm_weight_code {
148178 + /* The weight code is; 5 msbits + 3 lsbits */
148179 + u8 y:5;
148180 + u8 x:3;
148181 +};
148182 +
148183 +struct qm_ceetm {
148184 + unsigned int idx;
148185 + struct list_head sub_portals;
148186 + struct list_head lnis;
148187 + unsigned int sp_range[2];
148188 + unsigned int lni_range[2];
148189 +};
148190 +
148191 +struct qm_ceetm_sp {
148192 + struct list_head node;
148193 + unsigned int idx;
148194 + unsigned int dcp_idx;
148195 + int is_claimed;
148196 + struct qm_ceetm_lni *lni;
148197 +};
148198 +
148199 +/* Logical Network Interface */
148200 +struct qm_ceetm_lni {
148201 + struct list_head node;
148202 + unsigned int idx;
148203 + unsigned int dcp_idx;
148204 + int is_claimed;
148205 + struct qm_ceetm_sp *sp;
148206 + struct list_head channels;
148207 + int shaper_enable;
148208 + int shaper_couple;
148209 + int oal;
148210 + struct qm_ceetm_rate cr_token_rate;
148211 + struct qm_ceetm_rate er_token_rate;
148212 + u16 cr_token_bucket_limit;
148213 + u16 er_token_bucket_limit;
148214 +};
148215 +
148216 +/* Class Queue Channel */
148217 +struct qm_ceetm_channel {
148218 + struct list_head node;
148219 + unsigned int idx;
148220 + unsigned int lni_idx;
148221 + unsigned int dcp_idx;
148222 + struct list_head class_queues;
148223 + struct list_head ccgs;
148224 + u8 shaper_enable;
148225 + u8 shaper_couple;
148226 + struct qm_ceetm_rate cr_token_rate;
148227 + struct qm_ceetm_rate er_token_rate;
148228 + u16 cr_token_bucket_limit;
148229 + u16 er_token_bucket_limit;
148230 +};
148231 +
148232 +struct qm_ceetm_ccg;
148233 +
148234 +/* This callback type is used when handling congestion entry/exit. The
148235 + * 'cb_ctx' value is the opaque value associated with ccg object.
148236 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit.
148237 + */
148238 +typedef void (*qman_cb_ccgr)(struct qm_ceetm_ccg *ccg, void *cb_ctx,
148239 + int congested);
148240 +
148241 +/* Class Congestion Group */
148242 +struct qm_ceetm_ccg {
148243 + struct qm_ceetm_channel *parent;
148244 + struct list_head node;
148245 + struct list_head cb_node;
148246 + qman_cb_ccgr cb;
148247 + void *cb_ctx;
148248 + unsigned int idx;
148249 +};
148250 +
148251 +/* Class Queue */
148252 +struct qm_ceetm_cq {
148253 + struct qm_ceetm_channel *parent;
148254 + struct qm_ceetm_ccg *ccg;
148255 + struct list_head node;
148256 + unsigned int idx;
148257 + int is_claimed;
148258 + struct list_head bound_lfqids;
148259 + struct list_head binding_node;
148260 +};
148261 +
148262 +/* Logical Frame Queue */
148263 +struct qm_ceetm_lfq {
148264 + struct qm_ceetm_channel *parent;
148265 + struct list_head node;
148266 + unsigned int idx;
148267 + unsigned int dctidx;
148268 + u64 context_a;
148269 + u32 context_b;
148270 + qman_cb_mr ern;
148271 +};
148272 +
148273 +/**
148274 + * qman_ceetm_bps2tokenrate - Given a desired rate 'bps' measured in bps
148275 + * (ie. bits-per-second), compute the 'token_rate' fraction that best
148276 + * approximates that rate.
148277 + * @bps: the desired shaper rate in bps.
148278 + * @token_rate: the output token rate computed with the given kbps.
148279 + * @rounding: dictates how to round if an exact conversion is not possible; if
148280 + * it is negative then 'token_rate' will round down to the highest value that
148281 + * does not exceed the desired rate, if it is positive then 'token_rate' will
148282 + * round up to the lowest value that is greater than or equal to the desired
148283 + * rate, and if it is zero then it will round to the nearest approximation,
148284 + * whether that be up or down.
148285 + *
148286 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
148287 + */
148288 +int qman_ceetm_bps2tokenrate(u64 bps,
148289 + struct qm_ceetm_rate *token_rate,
148290 + int rounding);
148291 +
148292 +/**
148293 + * qman_ceetm_tokenrate2bps - Given a 'token_rate', compute the
148294 + * corresponding number of 'bps'.
148295 + * @token_rate: the input desired token_rate fraction.
148296 + * @bps: the output shaper rate in bps computed with the give token rate.
148297 + * @rounding: has the same semantics as the previous function.
148298 + *
148299 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
148300 + */
148301 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate,
148302 + u64 *bps,
148303 + int rounding);
148304 +
148305 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
148306 + int partial);
148307 +static inline int qman_alloc_ceetm0_channel(u32 *result)
148308 +{
148309 + int ret = qman_alloc_ceetm0_channel_range(result, 1, 0, 0);
148310 + return (ret > 0) ? 0 : ret;
148311 +}
148312 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count);
148313 +static inline void qman_release_ceetm0_channelid(u32 channelid)
148314 +{
148315 + qman_release_ceetm0_channel_range(channelid, 1);
148316 +}
148317 +
148318 +int qman_reserve_ceetm0_channel_range(u32 channelid, u32 count);
148319 +static inline int qman_reserve_ceetm0_channelid(u32 channelid)
148320 +{
148321 + return qman_reserve_ceetm0_channel_range(channelid, 1);
148322 +}
148323 +
148324 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count);
148325 +
148326 +
148327 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
148328 + int partial);
148329 +static inline int qman_alloc_ceetm1_channel(u32 *result)
148330 +{
148331 + int ret = qman_alloc_ceetm1_channel_range(result, 1, 0, 0);
148332 + return (ret > 0) ? 0 : ret;
148333 +}
148334 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count);
148335 +static inline void qman_release_ceetm1_channelid(u32 channelid)
148336 +{
148337 + qman_release_ceetm1_channel_range(channelid, 1);
148338 +}
148339 +int qman_reserve_ceetm1_channel_range(u32 channelid, u32 count);
148340 +static inline int qman_reserve_ceetm1_channelid(u32 channelid)
148341 +{
148342 + return qman_reserve_ceetm1_channel_range(channelid, 1);
148343 +}
148344 +
148345 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count);
148346 +
148347 +
148348 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
148349 + int partial);
148350 +static inline int qman_alloc_ceetm0_lfqid(u32 *result)
148351 +{
148352 + int ret = qman_alloc_ceetm0_lfqid_range(result, 1, 0, 0);
148353 + return (ret > 0) ? 0 : ret;
148354 +}
148355 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count);
148356 +static inline void qman_release_ceetm0_lfqid(u32 lfqid)
148357 +{
148358 + qman_release_ceetm0_lfqid_range(lfqid, 1);
148359 +}
148360 +int qman_reserve_ceetm0_lfqid_range(u32 lfqid, u32 count);
148361 +static inline int qman_reserve_ceetm0_lfqid(u32 lfqid)
148362 +{
148363 + return qman_reserve_ceetm0_lfqid_range(lfqid, 1);
148364 +}
148365 +
148366 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count);
148367 +
148368 +
148369 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
148370 + int partial);
148371 +static inline int qman_alloc_ceetm1_lfqid(u32 *result)
148372 +{
148373 + int ret = qman_alloc_ceetm1_lfqid_range(result, 1, 0, 0);
148374 + return (ret > 0) ? 0 : ret;
148375 +}
148376 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count);
148377 +static inline void qman_release_ceetm1_lfqid(u32 lfqid)
148378 +{
148379 + qman_release_ceetm1_lfqid_range(lfqid, 1);
148380 +}
148381 +int qman_reserve_ceetm1_lfqid_range(u32 lfqid, u32 count);
148382 +static inline int qman_reserve_ceetm1_lfqid(u32 lfqid)
148383 +{
148384 + return qman_reserve_ceetm1_lfqid_range(lfqid, 1);
148385 +}
148386 +
148387 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count);
148388 +
148389 +
148390 + /* ----------------------------- */
148391 + /* CEETM :: sub-portals */
148392 + /* ----------------------------- */
148393 +
148394 +/**
148395 + * qman_ceetm_sp_claim - Claims the given sub-portal, provided it is available
148396 + * to us and configured for traffic-management.
148397 + * @sp: the returned sub-portal object, if successful.
148398 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
148399 + * instance),
148400 + * @sp_idx" is the desired sub-portal index from 0 to 15.
148401 + *
148402 + * Returns zero for success, or -ENODEV if the sub-portal is in use, or -EINVAL
148403 + * if the sp_idx is out of range.
148404 + *
148405 + * Note that if there are multiple driver domains (eg. a linux kernel versus
148406 + * user-space drivers in USDPAA, or multiple guests running under a hypervisor)
148407 + * then a sub-portal may be accessible by more than one instance of a qman
148408 + * driver and so it may be claimed multiple times. If this is the case, it is
148409 + * up to the system architect to prevent conflicting configuration actions
148410 + * coming from the different driver domains. The qman drivers do not have any
148411 + * behind-the-scenes coordination to prevent this from happening.
148412 + */
148413 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp,
148414 + enum qm_dc_portal dcp_idx,
148415 + unsigned int sp_idx);
148416 +
148417 +/**
148418 + * qman_ceetm_sp_release - Releases a previously claimed sub-portal.
148419 + * @sp: the sub-portal to be released.
148420 + *
148421 + * Returns 0 for success, or -EBUSY for failure if the dependencies are not
148422 + * released.
148423 + */
148424 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp);
148425 +
148426 + /* ----------------------------------- */
148427 + /* CEETM :: logical network interfaces */
148428 + /* ----------------------------------- */
148429 +
148430 +/**
148431 + * qman_ceetm_lni_claim - Claims an unclaimed LNI.
148432 + * @lni: the returned LNI object, if successful.
148433 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
148434 + * instance)
148435 + * @lni_idx: is the desired LNI index.
148436 + *
148437 + * Returns zero for success, or -EINVAL on failure, which will happen if the LNI
148438 + * is not available or has already been claimed (and not yet successfully
148439 + * released), or lni_dix is out of range.
148440 + *
148441 + * Note that there may be multiple driver domains (or instances) that need to
148442 + * transmit out the same LNI, so this claim is only guaranteeing exclusivity
148443 + * within the domain of the driver being called. See qman_ceetm_sp_claim() and
148444 + * qman_ceetm_sp_get_lni() for more information.
148445 + */
148446 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni,
148447 + enum qm_dc_portal dcp_id,
148448 + unsigned int lni_idx);
148449 +
148450 +/**
148451 + * qman_ceetm_lni_releaes - Releases a previously claimed LNI.
148452 + * @lni: the lni needs to be released.
148453 + *
148454 + * This will only succeed if all dependent objects have been released.
148455 + * Returns zero for success, or -EBUSY if the dependencies are not released.
148456 + */
148457 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni);
148458 +
148459 +/**
148460 + * qman_ceetm_sp_set_lni
148461 + * qman_ceetm_sp_get_lni - Set/get the LNI that the sub-portal is currently
148462 + * mapped to.
148463 + * @sp: the given sub-portal.
148464 + * @lni(in "set"function): the LNI object which the sp will be mappaed to.
148465 + * @lni_idx(in "get" function): the LNI index which the sp is mapped to.
148466 + *
148467 + * Returns zero for success, or -EINVAL for the "set" function when this sp-lni
148468 + * mapping has been set, or configure mapping command returns error, and
148469 + * -EINVAL for "get" function when this sp-lni mapping is not set or the query
148470 + * mapping command returns error.
148471 + *
148472 + * This may be useful in situations where multiple driver domains have access
148473 + * to the same sub-portals in order to all be able to transmit out the same
148474 + * physical interface (perhaps they're on different IP addresses or VPNs, so
148475 + * Fman is splitting Rx traffic and here we need to converge Tx traffic). In
148476 + * that case, a control-plane is likely to use qman_ceetm_lni_claim() followed
148477 + * by qman_ceetm_sp_set_lni() to configure the sub-portal, and other domains
148478 + * are likely to use qman_ceetm_sp_get_lni() followed by qman_ceetm_lni_claim()
148479 + * in order to determine the LNI that the control-plane had assigned. This is
148480 + * why the "get" returns an index, whereas the "set" takes an (already claimed)
148481 + * LNI object.
148482 + */
148483 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp,
148484 + struct qm_ceetm_lni *lni);
148485 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp,
148486 + unsigned int *lni_idx);
148487 +
148488 +/**
148489 + * qman_ceetm_lni_enable_shaper
148490 + * qman_ceetm_lni_disable_shaper - Enables/disables shaping on the LNI.
148491 + * @lni: the given LNI.
148492 + * @coupled: indicates whether CR and ER are coupled.
148493 + * @oal: the overhead accounting length which is added to the actual length of
148494 + * each frame when performing shaper calculations.
148495 + *
148496 + * When the number of (unused) committed-rate tokens reach the committed-rate
148497 + * token limit, 'coupled' indicates whether surplus tokens should be added to
148498 + * the excess-rate token count (up to the excess-rate token limit).
148499 + * When LNI is claimed, the shaper is disabled by default. The enable function
148500 + * will turn on this shaper for this lni.
148501 + * Whenever a claimed LNI is first enabled for shaping, its committed and
148502 + * excess token rates and limits are zero, so will need to be changed to do
148503 + * anything useful. The shaper can subsequently be enabled/disabled without
148504 + * resetting the shaping parameters, but the shaping parameters will be reset
148505 + * when the LNI is released.
148506 + *
148507 + * Returns zero for success, or errno for "enable" function in the cases as:
148508 + * a) -EINVAL if the shaper is already enabled,
148509 + * b) -EIO if the configure shaper command returns error.
148510 + * For "disable" function, returns:
148511 + * a) -EINVAL if the shaper is has already disabled.
148512 + * b) -EIO if calling configure shaper command returns error.
148513 + */
148514 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
148515 + int oal);
148516 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni);
148517 +
148518 +/**
148519 + * qman_ceetm_lni_is_shaper_enabled - Check LNI shaper status
148520 + * @lni: the give LNI
148521 + */
148522 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni);
148523 +
148524 +/**
148525 + * qman_ceetm_lni_set_commit_rate
148526 + * qman_ceetm_lni_get_commit_rate
148527 + * qman_ceetm_lni_set_excess_rate
148528 + * qman_ceetm_lni_get_excess_rate - Set/get the shaper CR/ER token rate and
148529 + * token limit for the given LNI.
148530 + * @lni: the given LNI.
148531 + * @token_rate: the desired token rate for "set" fuction, or the token rate of
148532 + * the LNI queried by "get" function.
148533 + * @token_limit: the desired token bucket limit for "set" function, or the token
148534 + * limit of the given LNI queried by "get" function.
148535 + *
148536 + * Returns zero for success. The "set" function returns -EINVAL if the given
148537 + * LNI is unshapped or -EIO if the configure shaper command returns error.
148538 + * The "get" function returns -EINVAL if the token rate or the token limit is
148539 + * not set or the query command returns error.
148540 + */
148541 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
148542 + const struct qm_ceetm_rate *token_rate,
148543 + u16 token_limit);
148544 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
148545 + struct qm_ceetm_rate *token_rate,
148546 + u16 *token_limit);
148547 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
148548 + const struct qm_ceetm_rate *token_rate,
148549 + u16 token_limit);
148550 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
148551 + struct qm_ceetm_rate *token_rate,
148552 + u16 *token_limit);
148553 +/**
148554 + * qman_ceetm_lni_set_commit_rate_bps
148555 + * qman_ceetm_lni_get_commit_rate_bps
148556 + * qman_ceetm_lni_set_excess_rate_bps
148557 + * qman_ceetm_lni_get_excess_rate_bps - Set/get the shaper CR/ER rate
148558 + * and token limit for the given LNI.
148559 + * @lni: the given LNI.
148560 + * @bps: the desired shaping rate in bps for "set" fuction, or the shaping rate
148561 + * of the LNI queried by "get" function.
148562 + * @token_limit: the desired token bucket limit for "set" function, or the token
148563 + * limit of the given LNI queried by "get" function.
148564 + *
148565 + * Returns zero for success. The "set" function returns -EINVAL if the given
148566 + * LNI is unshapped or -EIO if the configure shaper command returns error.
148567 + * The "get" function returns -EINVAL if the token rate or the token limit is
148568 + * not set or the query command returns error.
148569 + */
148570 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
148571 + u64 bps,
148572 + u16 token_limit);
148573 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
148574 + u64 *bps, u16 *token_limit);
148575 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
148576 + u64 bps,
148577 + u16 token_limit);
148578 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
148579 + u64 *bps, u16 *token_limit);
148580 +
148581 +/**
148582 + * qman_ceetm_lni_set_tcfcc
148583 + * qman_ceetm_lni_get_tcfcc - Configure/query "Traffic Class Flow Control".
148584 + * @lni: the given LNI.
148585 + * @cq_level: is between 0 and 15, representing individual class queue levels
148586 + * (CQ0 to CQ7 for every channel) and grouped class queue levels (CQ8 to CQ15
148587 + * for every channel).
148588 + * @traffic_class: is between 0 and 7 when associating a given class queue level
148589 + * to a traffic class, or -1 when disabling traffic class flow control for this
148590 + * class queue level.
148591 + *
148592 + * Return zero for success, or -EINVAL if the cq_level or traffic_class is out
148593 + * of range as indicated above, or -EIO if the configure/query tcfcc command
148594 + * returns error.
148595 + *
148596 + * Refer to the section of QMan CEETM traffic class flow control in the
148597 + * Reference Manual.
148598 + */
148599 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
148600 + unsigned int cq_level,
148601 + int traffic_class);
148602 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni,
148603 + unsigned int cq_level,
148604 + int *traffic_class);
148605 +
148606 + /* ----------------------------- */
148607 + /* CEETM :: class queue channels */
148608 + /* ----------------------------- */
148609 +
148610 +/**
148611 + * qman_ceetm_channel_claim - Claims an unclaimed CQ channel that is mapped to
148612 + * the given LNI.
148613 + * @channel: the returned class queue channel object, if successful.
148614 + * @lni: the LNI that the channel belongs to.
148615 + *
148616 + * Channels are always initially "unshaped".
148617 + *
148618 + * Return zero for success, or -ENODEV if there is no channel available(all 32
148619 + * channels are claimed) or -EINVAL if the channel mapping command returns
148620 + * error.
148621 + */
148622 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
148623 + struct qm_ceetm_lni *lni);
148624 +
148625 +/**
148626 + * qman_ceetm_channel_release - Releases a previously claimed CQ channel.
148627 + * @channel: the channel needs to be released.
148628 + *
148629 + * Returns zero for success, or -EBUSY if the dependencies are still in use.
148630 + *
148631 + * Note any shaping of the channel will be cleared to leave it in an unshaped
148632 + * state.
148633 + */
148634 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel);
148635 +
148636 +/**
148637 + * qman_ceetm_channel_enable_shaper
148638 + * qman_ceetm_channel_disable_shaper - Enables/disables shaping on the channel.
148639 + * @channel: the given channel.
148640 + * @coupled: indicates whether surplus CR tokens should be added to the
148641 + * excess-rate token count (up to the excess-rate token limit) when the number
148642 + * of (unused) committed-rate tokens reach the committed_rate token limit.
148643 + *
148644 + * Whenever a claimed channel is first enabled for shaping, its committed and
148645 + * excess token rates and limits are zero, so will need to be changed to do
148646 + * anything useful. The shaper can subsequently be enabled/disabled without
148647 + * resetting the shaping parameters, but the shaping parameters will be reset
148648 + * when the channel is released.
148649 + *
148650 + * Return 0 for success, or -EINVAL for failure, in the case that the channel
148651 + * shaper has been enabled/disabled or the management command returns error.
148652 + */
148653 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
148654 + int coupled);
148655 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel);
148656 +
148657 +/**
148658 + * qman_ceetm_channel_is_shaper_enabled - Check channel shaper status.
148659 + * @channel: the give channel.
148660 + */
148661 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel);
148662 +
148663 +/**
148664 + * qman_ceetm_channel_set_commit_rate
148665 + * qman_ceetm_channel_get_commit_rate
148666 + * qman_ceetm_channel_set_excess_rate
148667 + * qman_ceetm_channel_get_excess_rate - Set/get channel CR/ER shaper parameters.
148668 + * @channel: the given channel.
148669 + * @token_rate: the desired token rate for "set" function, or the queried token
148670 + * rate for "get" function.
148671 + * @token_limit: the desired token limit for "set" function, or the queried
148672 + * token limit for "get" function.
148673 + *
148674 + * Return zero for success. The "set" function returns -EINVAL if the channel
148675 + * is unshaped, or -EIO if the configure shapper command returns error. The
148676 + * "get" function returns -EINVAL if token rate of token limit is not set, or
148677 + * the query shaper command returns error.
148678 + */
148679 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
148680 + const struct qm_ceetm_rate *token_rate,
148681 + u16 token_limit);
148682 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
148683 + struct qm_ceetm_rate *token_rate,
148684 + u16 *token_limit);
148685 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
148686 + const struct qm_ceetm_rate *token_rate,
148687 + u16 token_limit);
148688 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
148689 + struct qm_ceetm_rate *token_rate,
148690 + u16 *token_limit);
148691 +/**
148692 + * qman_ceetm_channel_set_commit_rate_bps
148693 + * qman_ceetm_channel_get_commit_rate_bps
148694 + * qman_ceetm_channel_set_excess_rate_bps
148695 + * qman_ceetm_channel_get_excess_rate_bps - Set/get channel CR/ER shaper
148696 + * parameters.
148697 + * @channel: the given channel.
148698 + * @token_rate: the desired shaper rate in bps for "set" function, or the
148699 + * shaper rate in bps for "get" function.
148700 + * @token_limit: the desired token limit for "set" function, or the queried
148701 + * token limit for "get" function.
148702 + *
148703 + * Return zero for success. The "set" function returns -EINVAL if the channel
148704 + * is unshaped, or -EIO if the configure shapper command returns error. The
148705 + * "get" function returns -EINVAL if token rate of token limit is not set, or
148706 + * the query shaper command returns error.
148707 + */
148708 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
148709 + u64 bps, u16 token_limit);
148710 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
148711 + u64 *bps, u16 *token_limit);
148712 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
148713 + u64 bps, u16 token_limit);
148714 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
148715 + u64 *bps, u16 *token_limit);
148716 +
148717 +/**
148718 + * qman_ceetm_channel_set_weight
148719 + * qman_ceetm_channel_get_weight - Set/get the weight for unshaped channel
148720 + * @channel: the given channel.
148721 + * @token_limit: the desired token limit as the weight of the unshaped channel
148722 + * for "set" function, or the queried token limit for "get" function.
148723 + *
148724 + * The algorithm of unshaped fair queuing (uFQ) is used for unshaped channel.
148725 + * It allows the unshaped channels to be included in the CR time eligible list,
148726 + * and thus use the configured CR token limit value as their fair queuing
148727 + * weight.
148728 + *
148729 + * Return zero for success, or -EINVAL if the channel is a shaped channel or
148730 + * the management command returns error.
148731 + */
148732 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
148733 + u16 token_limit);
148734 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
148735 + u16 *token_limit);
148736 +
148737 +/**
148738 + * qman_ceetm_channel_set_group
148739 + * qman_ceetm_channel_get_group - Set/get the grouping of the class scheduler.
148740 + * @channel: the given channel.
148741 + * @group_b: indicates whether there is group B in this channel.
148742 + * @prio_a: the priority of group A.
148743 + * @prio_b: the priority of group B.
148744 + *
148745 + * There are 8 individual class queues (CQ0-CQ7), and 8 grouped class queues
148746 + * (CQ8-CQ15). If 'group_b' is zero, then all the grouped class queues are in
148747 + * group A, otherwise they are split into group A (CQ8-11) and group B
148748 + * (CQ12-C15). The individual class queues and the group(s) are in strict
148749 + * priority order relative to each other. Within the group(s), the scheduling
148750 + * is not strict priority order, but the result of scheduling within a group
148751 + * is in strict priority order relative to the other class queues in the
148752 + * channel. 'prio_a' and 'prio_b' control the priority order of the groups
148753 + * relative to the individual class queues, and take values from 0-7. Eg. if
148754 + * 'group_b' is non-zero, 'prio_a' is 2 and 'prio_b' is 6, then the strict
148755 + * priority order would be;
148756 + * CQ0, CQ1, CQ2, GROUPA, CQ3, CQ4, CQ5, CQ6, GROUPB, CQ7
148757 + *
148758 + * Return 0 for success. For "set" function, returns -EINVAL if prio_a or
148759 + * prio_b are out of the range 0 - 7 (priority of group A or group B can not
148760 + * be 0, CQ0 is always the highest class queue in this channel.), or -EIO if
148761 + * the configure scheduler command returns error. For "get" function, return
148762 + * -EINVAL if the query scheduler command returns error.
148763 + */
148764 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel,
148765 + int group_b,
148766 + unsigned int prio_a,
148767 + unsigned int prio_b);
148768 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel,
148769 + int *group_b,
148770 + unsigned int *prio_a,
148771 + unsigned int *prio_b);
148772 +
148773 +/**
148774 + * qman_ceetm_channel_set_group_cr_eligibility
148775 + * qman_ceetm_channel_set_group_er_eligibility - Set channel group eligibility
148776 + * @channel: the given channel object
148777 + * @group_b: indicates whether there is group B in this channel.
148778 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
148779 + *
148780 + * Return zero for success, or -EINVAL if eligibility setting fails.
148781 +*/
148782 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
148783 + *channel, int group_b, int cre);
148784 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
148785 + *channel, int group_b, int ere);
148786 +
148787 +/**
148788 + * qman_ceetm_channel_set_cq_cr_eligibility
148789 + * qman_ceetm_channel_set_cq_er_eligibility - Set channel cq eligibility
148790 + * @channel: the given channel object
148791 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
148792 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
148793 + *
148794 + * Return zero for success, or -EINVAL if eligibility setting fails.
148795 +*/
148796 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
148797 + unsigned int idx, int cre);
148798 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
148799 + unsigned int idx, int ere);
148800 +
148801 + /* --------------------- */
148802 + /* CEETM :: class queues */
148803 + /* --------------------- */
148804 +
148805 +/**
148806 + * qman_ceetm_cq_claim - Claims an individual class queue.
148807 + * @cq: the returned class queue object, if successful.
148808 + * @channel: the class queue channel.
148809 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
148810 + * @ccg: represents the class congestion group that this class queue should be
148811 + * subscribed to, or NULL if no congestion group membership is desired.
148812 + *
148813 + * Returns zero for success, or -EINVAL if @idx is out of range 0 - 7 or
148814 + * if this class queue has been claimed, or configure class queue command
148815 + * returns error, or returns -ENOMEM if allocating CQ memory fails.
148816 + */
148817 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
148818 + struct qm_ceetm_channel *channel,
148819 + unsigned int idx,
148820 + struct qm_ceetm_ccg *ccg);
148821 +
148822 +/**
148823 + * qman_ceetm_cq_claim_A - Claims a class queue group A.
148824 + * @cq: the returned class queue object, if successful.
148825 + * @channel: the class queue channel.
148826 + * @idx: is from 8 to 15 if only group A exits, otherwise, it is from 8 to 11.
148827 + * @ccg: represents the class congestion group that this class queue should be
148828 + * subscribed to, or NULL if no congestion group membership is desired.
148829 + *
148830 + * Return zero for success, or -EINVAL if @idx is out the range or if
148831 + * this class queue has been claimed or configure class queue command returns
148832 + * error, or returns -ENOMEM if allocating CQ memory fails.
148833 + */
148834 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
148835 + struct qm_ceetm_channel *channel,
148836 + unsigned int idx,
148837 + struct qm_ceetm_ccg *ccg);
148838 +
148839 +/**
148840 + * qman_ceetm_cq_claim_B - Claims a class queue group B.
148841 + * @cq: the returned class queue object, if successful.
148842 + * @channel: the class queue channel.
148843 + * @idx: is from 0 to 3 (CQ12 to CQ15).
148844 + * @ccg: represents the class congestion group that this class queue should be
148845 + * subscribed to, or NULL if no congestion group membership is desired.
148846 + *
148847 + * Return zero for success, or -EINVAL if @idx is out the range or if
148848 + * this class queue has been claimed or configure class queue command returns
148849 + * error, or returns -ENOMEM if allocating CQ memory fails.
148850 + */
148851 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
148852 + struct qm_ceetm_channel *channel,
148853 + unsigned int idx,
148854 + struct qm_ceetm_ccg *ccg);
148855 +
148856 +/**
148857 + * qman_ceetm_cq_release - Releases a previously claimed class queue.
148858 + * @cq: The class queue to be released.
148859 + *
148860 + * Return zero for success, or -EBUSY if the dependent objects (eg. logical
148861 + * FQIDs) have not been released.
148862 + */
148863 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq);
148864 +
148865 +/**
148866 + * qman_ceetm_set_queue_weight
148867 + * qman_ceetm_get_queue_weight - Configure/query the weight of a grouped class
148868 + * queue.
148869 + * @cq: the given class queue.
148870 + * @weight_code: the desired weight code to set for the given class queue for
148871 + * "set" function or the queired weight code for "get" function.
148872 + *
148873 + * Grouped class queues have a default weight code of zero, which corresponds to
148874 + * a scheduler weighting of 1. This function can be used to modify a grouped
148875 + * class queue to another weight, (Use the helpers qman_ceetm_wbfs2ratio()
148876 + * and qman_ceetm_ratio2wbfs() to convert between these 'weight_code' values
148877 + * and the corresponding sharing weight.)
148878 + *
148879 + * Returns zero for success, or -EIO if the configure weight command returns
148880 + * error for "set" function, or -EINVAL if the query command returns
148881 + * error for "get" function.
148882 + * See section "CEETM Weighted Scheduling among Grouped Classes" in Reference
148883 + * Manual for weight and weight code.
148884 + */
148885 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
148886 + struct qm_ceetm_weight_code *weight_code);
148887 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
148888 + struct qm_ceetm_weight_code *weight_code);
148889 +
148890 +/**
148891 + * qman_ceetm_set_queue_weight_in_ratio
148892 + * qman_ceetm_get_queue_weight_in_ratio - Configure/query the weight of a
148893 + * grouped class queue.
148894 + * @cq: the given class queue.
148895 + * @ratio: the weight in ratio. It should be the real ratio number multiplied
148896 + * by 100 to get rid of fraction.
148897 + *
148898 + * Returns zero for success, or -EIO if the configure weight command returns
148899 + * error for "set" function, or -EINVAL if the query command returns
148900 + * error for "get" function.
148901 + */
148902 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio);
148903 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio);
148904 +
148905 +/* Weights are encoded using a pseudo-exponential scheme. The weight codes 0,
148906 + * 32, 64, [...] correspond to weights of 1, 2, 4, [...]. The weights
148907 + * corresponding to intermediate weight codes are calculated using linear
148908 + * interpolation on the inverted values. Or put another way, the inverse weights
148909 + * for each 32nd weight code are 1, 1/2, 1/4, [...], and so the intervals
148910 + * between these are divided linearly into 32 intermediate values, the inverses
148911 + * of which form the remaining weight codes.
148912 + *
148913 + * The Weighted Bandwidth Fair Scheduling (WBFS) algorithm provides a form of
148914 + * scheduling within a group of class queues (group A or B). Weights are used to
148915 + * normalise the class queues to an underlying BFS algorithm where all class
148916 + * queues are assumed to require "equal bandwidth". So the weights referred to
148917 + * by the weight codes act as divisors on the size of frames being enqueued. Ie.
148918 + * one class queue in a group is assigned a weight of 2 whilst the other class
148919 + * queues in the group keep the default weight of 1, then the WBFS scheduler
148920 + * will effectively treat all frames enqueued on the weight-2 class queue as
148921 + * having half the number of bytes they really have. Ie. if all other things are
148922 + * equal, that class queue would get twice as much bytes-per-second bandwidth as
148923 + * the others. So weights should be chosen to provide bandwidth ratios between
148924 + * members of the same class queue group. These weights have no bearing on
148925 + * behaviour outside that group's WBFS mechanism though.
148926 + */
148927 +
148928 +/**
148929 + * qman_ceetm_wbfs2ratio - Given a weight code ('wbfs'), an accurate fractional
148930 + * representation of the corresponding weight is given (in order to not lose
148931 + * any precision).
148932 + * @weight_code: The given weight code in WBFS.
148933 + * @numerator: the numerator part of the weight computed by the weight code.
148934 + * @denominator: the denominator part of the weight computed by the weight code
148935 + *
148936 + * Returns zero for success or -EINVAL if the given weight code is illegal.
148937 + */
148938 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
148939 + u32 *numerator,
148940 + u32 *denominator);
148941 +/**
148942 + * qman_ceetm_ratio2wbfs - Given a weight, find the nearest possible weight code
148943 + * If the user needs to know how close this is, convert the resulting weight
148944 + * code back to a weight and compare.
148945 + * @numerator: numerator part of the given weight.
148946 + * @denominator: denominator part of the given weight.
148947 + * @weight_code: the weight code computed from the given weight.
148948 + *
148949 + * Returns zero for success, or -ERANGE if "numerator/denominator" is outside
148950 + * the range of weights.
148951 + */
148952 +int qman_ceetm_ratio2wbfs(u32 numerator,
148953 + u32 denominator,
148954 + struct qm_ceetm_weight_code *weight_code,
148955 + int rounding);
148956 +
148957 +#define QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER 0x1
148958 +/**
148959 + * qman_ceetm_cq_get_dequeue_statistics - Get the statistics provided by CEETM
148960 + * CQ counters.
148961 + * @cq: the given CQ object.
148962 + * @flags: indicates whether the statistics counter will be cleared after query.
148963 + * @frame_count: The number of the frames that have been counted since the
148964 + * counter was cleared last time.
148965 + * @byte_count: the number of bytes in all frames that have been counted.
148966 + *
148967 + * Return zero for success or -EINVAL if query statistics command returns error.
148968 + *
148969 + */
148970 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
148971 + u64 *frame_count, u64 *byte_count);
148972 +
148973 +/**
148974 + * qman_ceetm_drain_cq - drain the CQ till it is empty.
148975 + * @cq: the give CQ object.
148976 + * Return 0 for success or -EINVAL for unsuccessful command to empty CQ.
148977 + */
148978 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq);
148979 +
148980 + /* ---------------------- */
148981 + /* CEETM :: logical FQIDs */
148982 + /* ---------------------- */
148983 +/**
148984 + * qman_ceetm_lfq_claim - Claims an unused logical FQID, associates it with
148985 + * the given class queue.
148986 + * @lfq: the returned lfq object, if successful.
148987 + * @cq: the class queue which needs to claim a LFQID.
148988 + *
148989 + * Return zero for success, or -ENODEV if no LFQID is available or -ENOMEM if
148990 + * allocating memory for lfq fails, or -EINVAL if configuring LFQMT fails.
148991 + */
148992 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
148993 + struct qm_ceetm_cq *cq);
148994 +
148995 +/**
148996 + * qman_ceetm_lfq_release - Releases a previously claimed logical FQID.
148997 + * @lfq: the lfq to be released.
148998 + *
148999 + * Return zero for success.
149000 + */
149001 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq);
149002 +
149003 +/**
149004 + * qman_ceetm_lfq_set_context
149005 + * qman_ceetm_lfq_get_context - Set/get the context_a/context_b pair to the
149006 + * "dequeue context table" associated with the logical FQID.
149007 + * @lfq: the given logical FQ object.
149008 + * @context_a: contextA of the dequeue context.
149009 + * @context_b: contextB of the dequeue context.
149010 + *
149011 + * Returns zero for success, or -EINVAL if there is error to set/get the
149012 + * context pair.
149013 + */
149014 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq,
149015 + u64 context_a,
149016 + u32 context_b);
149017 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq,
149018 + u64 *context_a,
149019 + u32 *context_b);
149020 +
149021 +/**
149022 + * qman_ceetm_create_fq - Initialise a FQ object for the LFQ.
149023 + * @lfq: the given logic fq.
149024 + * @fq: the fq object created for the given logic fq.
149025 + *
149026 + * The FQ object can be used in qman_enqueue() and qman_enqueue_orp() APIs to
149027 + * target a logical FQID (and the class queue it is associated with).
149028 + * Note that this FQ object can only be used for enqueues, and
149029 + * in the case of qman_enqueue_orp() it can not be used as the 'orp' parameter,
149030 + * only as 'fq'. This FQ object can not (and shouldn't) be destroyed, it is only
149031 + * valid as long as the underlying 'lfq' remains claimed. It is the user's
149032 + * responsibility to ensure that the underlying 'lfq' is not released until any
149033 + * enqueues to this FQ object have completed. The only field the user needs to
149034 + * fill in is fq->cb.ern, as that enqueue rejection handler is the callback that
149035 + * could conceivably be called on this FQ object. This API can be called
149036 + * multiple times to create multiple FQ objects referring to the same logical
149037 + * FQID, and any enqueue rejections will respect the callback of the object that
149038 + * issued the enqueue (and will identify the object via the parameter passed to
149039 + * the callback too). There is no 'flags' parameter to this API as there is for
149040 + * qman_create_fq() - the created FQ object behaves as though qman_create_fq()
149041 + * had been called with the single flag QMAN_FQ_FLAG_NO_MODIFY.
149042 + *
149043 + * Returns 0 for success.
149044 + */
149045 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq);
149046 +
149047 + /* -------------------------------- */
149048 + /* CEETM :: class congestion groups */
149049 + /* -------------------------------- */
149050 +
149051 +/**
149052 + * qman_ceetm_ccg_claim - Claims an unused CCG.
149053 + * @ccg: the returned CCG object, if successful.
149054 + * @channel: the given class queue channel
149055 + * @cscn: the callback function of this CCG.
149056 + * @cb_ctx: the corresponding context to be used used if state change
149057 + * notifications are later enabled for this CCG.
149058 + *
149059 + * The congestion group is local to the given class queue channel, so only
149060 + * class queues within the channel can be associated with that congestion group.
149061 + * The association of class queues to congestion groups occurs when the class
149062 + * queues are claimed, see qman_ceetm_cq_claim() and related functions.
149063 + * Congestion groups are in a "zero" state when initially claimed, and they are
149064 + * returned to that state when released.
149065 + *
149066 + * Return zero for success, or -EINVAL if no CCG in the channel is available.
149067 + */
149068 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
149069 + struct qm_ceetm_channel *channel,
149070 + unsigned int idx,
149071 + void (*cscn)(struct qm_ceetm_ccg *,
149072 + void *cb_ctx,
149073 + int congested),
149074 + void *cb_ctx);
149075 +
149076 +/**
149077 + * qman_ceetm_ccg_release - Releases a previously claimed CCG.
149078 + * @ccg: the given ccg.
149079 + *
149080 + * Returns zero for success, or -EBUSY if the given ccg's dependent objects
149081 + * (class queues that are associated with the CCG) have not been released.
149082 + */
149083 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg);
149084 +
149085 +/* This struct is used to specify attributes for a CCG. The 'we_mask' field
149086 + * controls which CCG attributes are to be updated, and the remainder specify
149087 + * the values for those attributes. A CCG counts either frames or the bytes
149088 + * within those frames, but not both ('mode'). A CCG can optionally cause
149089 + * enqueues to be rejected, due to tail-drop or WRED, or both (they are
149090 + * independent options, 'td_en' and 'wr_en_g,wr_en_y,wr_en_r'). Tail-drop can be
149091 + * level-triggered due to a single threshold ('td_thres') or edge-triggered due
149092 + * to a "congestion state", but not both ('td_mode'). Congestion state has
149093 + * distinct entry and exit thresholds ('cs_thres_in' and 'cs_thres_out'), and
149094 + * notifications can be sent to software the CCG goes in to and out of this
149095 + * congested state ('cscn_en'). */
149096 +struct qm_ceetm_ccg_params {
149097 + /* Boolean fields together in a single bitfield struct */
149098 + struct {
149099 + /* Whether to count bytes or frames. 1==frames */
149100 + u8 mode:1;
149101 + /* En/disable tail-drop. 1==enable */
149102 + u8 td_en:1;
149103 + /* Tail-drop on congestion-state or threshold. 1=threshold */
149104 + u8 td_mode:1;
149105 + /* Generate congestion state change notifications. 1==enable */
149106 + u8 cscn_en:1;
149107 + /* Enable WRED rejections (per colour). 1==enable */
149108 + u8 wr_en_g:1;
149109 + u8 wr_en_y:1;
149110 + u8 wr_en_r:1;
149111 + } __packed;
149112 + /* Tail-drop threshold. See qm_cgr_thres_[gs]et64(). */
149113 + struct qm_cgr_cs_thres td_thres;
149114 + /* Congestion state thresholds, for entry and exit. */
149115 + struct qm_cgr_cs_thres cs_thres_in;
149116 + struct qm_cgr_cs_thres cs_thres_out;
149117 + /* Overhead accounting length. Per-packet "tax", from -128 to +127 */
149118 + signed char oal;
149119 + /* Congestion state change notification for DCP portal, virtual CCGID*/
149120 + /* WRED parameters. */
149121 + struct qm_cgr_wr_parm wr_parm_g;
149122 + struct qm_cgr_wr_parm wr_parm_y;
149123 + struct qm_cgr_wr_parm wr_parm_r;
149124 +};
149125 +/* Bits used in 'we_mask' to qman_ceetm_ccg_set(), controls which attributes of
149126 + * the CCGR are to be updated. */
149127 +#define QM_CCGR_WE_MODE 0x0001 /* mode (bytes/frames) */
149128 +#define QM_CCGR_WE_CS_THRES_IN 0x0002 /* congestion state entry threshold */
149129 +#define QM_CCGR_WE_TD_EN 0x0004 /* congestion state tail-drop enable */
149130 +#define QM_CCGR_WE_CSCN_TUPD 0x0008 /* CSCN target update */
149131 +#define QM_CCGR_WE_CSCN_EN 0x0010 /* congestion notification enable */
149132 +#define QM_CCGR_WE_WR_EN_R 0x0020 /* WRED enable - red */
149133 +#define QM_CCGR_WE_WR_EN_Y 0x0040 /* WRED enable - yellow */
149134 +#define QM_CCGR_WE_WR_EN_G 0x0080 /* WRED enable - green */
149135 +#define QM_CCGR_WE_WR_PARM_R 0x0100 /* WRED parameters - red */
149136 +#define QM_CCGR_WE_WR_PARM_Y 0x0200 /* WRED parameters - yellow */
149137 +#define QM_CCGR_WE_WR_PARM_G 0x0400 /* WRED parameters - green */
149138 +#define QM_CCGR_WE_OAL 0x0800 /* overhead accounting length */
149139 +#define QM_CCGR_WE_CS_THRES_OUT 0x1000 /* congestion state exit threshold */
149140 +#define QM_CCGR_WE_TD_THRES 0x2000 /* tail-drop threshold */
149141 +#define QM_CCGR_WE_TD_MODE 0x4000 /* tail-drop mode (state/threshold) */
149142 +#define QM_CCGR_WE_CDV 0x8000 /* cdv */
149143 +
149144 +/**
149145 + * qman_ceetm_ccg_set
149146 + * qman_ceetm_ccg_get - Configure/query a subset of CCG attributes.
149147 + * @ccg: the given CCG object.
149148 + * @we_mask: the write enable mask.
149149 + * @params: the parameters setting for this ccg
149150 + *
149151 + * Return 0 for success, or -EIO if configure ccg command returns error for
149152 + * "set" function, or -EINVAL if query ccg command returns error for "get"
149153 + * function.
149154 + */
149155 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg,
149156 + u16 we_mask,
149157 + const struct qm_ceetm_ccg_params *params);
149158 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
149159 + struct qm_ceetm_ccg_params *params);
149160 +
149161 +/** qman_ceetm_cscn_swp_set - Add or remove a software portal from the target
149162 + * mask.
149163 + * qman_ceetm_cscn_swp_get - Query whether a given software portal index is
149164 + * in the cscn target mask.
149165 + * @ccg: the give CCG object.
149166 + * @swp_idx: the index of the software portal.
149167 + * @cscn_enabled: 1: Set the swp to be cscn target. 0: remove the swp from
149168 + * the target mask.
149169 + * @we_mask: the write enable mask.
149170 + * @params: the parameters setting for this ccg
149171 + *
149172 + * Return 0 for success, or -EINVAL if command in set/get function fails.
149173 + */
149174 +int qman_ceetm_cscn_swp_set(struct qm_ceetm_ccg *ccg,
149175 + u16 swp_idx,
149176 + unsigned int cscn_enabled,
149177 + u16 we_mask,
149178 + const struct qm_ceetm_ccg_params *params);
149179 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
149180 + u16 swp_idx,
149181 + unsigned int *cscn_enabled);
149182 +
149183 +/** qman_ceetm_cscn_dcp_set - Add or remove a direct connect portal from the\
149184 + * target mask.
149185 + * qman_ceetm_cscn_dcp_get - Query whether a given direct connect portal index
149186 + * is in the cscn target mask.
149187 + * @ccg: the give CCG object.
149188 + * @dcp_idx: the index of the direct connect portal.
149189 + * @vcgid: congestion state change notification for dcp portal, virtual CGID.
149190 + * @cscn_enabled: 1: Set the dcp to be cscn target. 0: remove the dcp from
149191 + * the target mask.
149192 + * @we_mask: the write enable mask.
149193 + * @params: the parameters setting for this ccg
149194 + *
149195 + * Return 0 for success, or -EINVAL if command in set/get function fails.
149196 + */
149197 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
149198 + u16 dcp_idx,
149199 + u8 vcgid,
149200 + unsigned int cscn_enabled,
149201 + u16 we_mask,
149202 + const struct qm_ceetm_ccg_params *params);
149203 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
149204 + u16 dcp_idx,
149205 + u8 *vcgid,
149206 + unsigned int *cscn_enabled);
149207 +
149208 +/**
149209 + * qman_ceetm_ccg_get_reject_statistics - Get the statistics provided by
149210 + * CEETM CCG counters.
149211 + * @ccg: the given CCG object.
149212 + * @flags: indicates whether the statistics counter will be cleared after query.
149213 + * @frame_count: The number of the frames that have been counted since the
149214 + * counter was cleared last time.
149215 + * @byte_count: the number of bytes in all frames that have been counted.
149216 + *
149217 + * Return zero for success or -EINVAL if query statistics command returns error.
149218 + *
149219 + */
149220 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
149221 + u64 *frame_count, u64 *byte_count);
149222 +
149223 +/**
149224 + * qman_ceetm_query_lfqmt - Query the logical frame queue mapping table
149225 + * @lfqid: Logical Frame Queue ID
149226 + * @lfqmt_query: Results of the query command
149227 + *
149228 + * Returns zero for success or -EIO if the query command returns error.
149229 + *
149230 + */
149231 +int qman_ceetm_query_lfqmt(int lfqid,
149232 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query);
149233 +
149234 +/**
149235 + * qman_ceetm_query_write_statistics - Query (and optionally write) statistics
149236 + * @cid: Target ID (CQID or CCGRID)
149237 + * @dcp_idx: CEETM portal ID
149238 + * @command_type: One of the following:
149239 + * 0 = Query dequeue statistics. CID carries the CQID to be queried.
149240 + * 1 = Query and clear dequeue statistics. CID carries the CQID to be queried
149241 + * 2 = Write dequeue statistics. CID carries the CQID to be written.
149242 + * 3 = Query reject statistics. CID carries the CCGRID to be queried.
149243 + * 4 = Query and clear reject statistics. CID carries the CCGRID to be queried
149244 + * 5 = Write reject statistics. CID carries the CCGRID to be written
149245 + * @frame_count: Frame count value to be written if this is a write command
149246 + * @byte_count: Bytes count value to be written if this is a write command
149247 + *
149248 + * Returns zero for success or -EIO if the query command returns error.
149249 + */
149250 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
149251 + u16 command_type, u64 frame_count,
149252 + u64 byte_count);
149253 +
149254 +/**
149255 + * qman_set_wpm - Set waterfall power management
149256 + *
149257 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
149258 + *
149259 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
149260 + * accessible.
149261 + */
149262 +int qman_set_wpm(int wpm_enable);
149263 +
149264 +/**
149265 + * qman_get_wpm - Query the waterfall power management setting
149266 + *
149267 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
149268 + *
149269 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
149270 + * accessible.
149271 + */
149272 +int qman_get_wpm(int *wpm_enable);
149273 +
149274 +/* The below qman_p_***() variants might be called in a migration situation
149275 + * (e.g. cpu hotplug). They are used to continue accessing the portal that
149276 + * execution was affine to prior to migration.
149277 + * @qman_portal specifies which portal the APIs will use.
149278 +*/
149279 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal
149280 + *p);
149281 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits);
149282 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits);
149283 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit);
149284 +u32 qman_p_poll_slow(struct qman_portal *p);
149285 +void qman_p_poll(struct qman_portal *p);
149286 +void qman_p_stop_dequeues(struct qman_portal *p);
149287 +void qman_p_start_dequeues(struct qman_portal *p);
149288 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools);
149289 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools);
149290 +u32 qman_p_static_dequeue_get(struct qman_portal *p);
149291 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
149292 + int park_request);
149293 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
149294 + u32 flags __maybe_unused, u32 vdqcr);
149295 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
149296 + const struct qm_fd *fd, u32 flags);
149297 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
149298 + const struct qm_fd *fd, u32 flags,
149299 + struct qman_fq *orp, u16 orp_seqnum);
149300 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
149301 + const struct qm_fd *fd, u32 flags,
149302 + qman_cb_precommit cb, void *cb_arg);
149303 +#ifdef __cplusplus
149304 +}
149305 +#endif
149306 +
149307 +#endif /* FSL_QMAN_H */
149308 diff --git a/include/linux/fsl_usdpaa.h b/include/linux/fsl_usdpaa.h
149309 new file mode 100644
149310 index 00000000..381853de
149311 --- /dev/null
149312 +++ b/include/linux/fsl_usdpaa.h
149313 @@ -0,0 +1,372 @@
149314 +/* Copyright 2011-2012 Freescale Semiconductor, Inc.
149315 + *
149316 + * This file is licensed under the terms of the GNU General Public License
149317 + * version 2. This program is licensed "as is" without any warranty of any
149318 + * kind, whether express or implied.
149319 + */
149320 +
149321 +#ifndef FSL_USDPAA_H
149322 +#define FSL_USDPAA_H
149323 +
149324 +#ifdef __cplusplus
149325 +extern "C" {
149326 +#endif
149327 +
149328 +#include <linux/uaccess.h>
149329 +#include <linux/ioctl.h>
149330 +#include <linux/fsl_qman.h> /* For "enum qm_channel" */
149331 +#include <linux/compat.h>
149332 +
149333 +#ifdef CONFIG_FSL_USDPAA
149334 +
149335 +/******************************/
149336 +/* Allocation of resource IDs */
149337 +/******************************/
149338 +
149339 +/* This enum is used to distinguish between the type of underlying object being
149340 + * manipulated. */
149341 +enum usdpaa_id_type {
149342 + usdpaa_id_fqid,
149343 + usdpaa_id_bpid,
149344 + usdpaa_id_qpool,
149345 + usdpaa_id_cgrid,
149346 + usdpaa_id_ceetm0_lfqid,
149347 + usdpaa_id_ceetm0_channelid,
149348 + usdpaa_id_ceetm1_lfqid,
149349 + usdpaa_id_ceetm1_channelid,
149350 + usdpaa_id_max /* <-- not a valid type, represents the number of types */
149351 +};
149352 +#define USDPAA_IOCTL_MAGIC 'u'
149353 +struct usdpaa_ioctl_id_alloc {
149354 + uint32_t base; /* Return value, the start of the allocated range */
149355 + enum usdpaa_id_type id_type; /* what kind of resource(s) to allocate */
149356 + uint32_t num; /* how many IDs to allocate (and return value) */
149357 + uint32_t align; /* must be a power of 2, 0 is treated like 1 */
149358 + int partial; /* whether to allow less than 'num' */
149359 +};
149360 +struct usdpaa_ioctl_id_release {
149361 + /* Input; */
149362 + enum usdpaa_id_type id_type;
149363 + uint32_t base;
149364 + uint32_t num;
149365 +};
149366 +struct usdpaa_ioctl_id_reserve {
149367 + enum usdpaa_id_type id_type;
149368 + uint32_t base;
149369 + uint32_t num;
149370 +};
149371 +
149372 +
149373 +/* ioctl() commands */
149374 +#define USDPAA_IOCTL_ID_ALLOC \
149375 + _IOWR(USDPAA_IOCTL_MAGIC, 0x01, struct usdpaa_ioctl_id_alloc)
149376 +#define USDPAA_IOCTL_ID_RELEASE \
149377 + _IOW(USDPAA_IOCTL_MAGIC, 0x02, struct usdpaa_ioctl_id_release)
149378 +#define USDPAA_IOCTL_ID_RESERVE \
149379 + _IOW(USDPAA_IOCTL_MAGIC, 0x0A, struct usdpaa_ioctl_id_reserve)
149380 +
149381 +/**********************/
149382 +/* Mapping DMA memory */
149383 +/**********************/
149384 +
149385 +/* Maximum length for a map name, including NULL-terminator */
149386 +#define USDPAA_DMA_NAME_MAX 16
149387 +/* Flags for requesting DMA maps. Maps are private+unnamed or sharable+named.
149388 + * For a sharable and named map, specify _SHARED (whether creating one or
149389 + * binding to an existing one). If _SHARED is specified and _CREATE is not, then
149390 + * the mapping must already exist. If _SHARED and _CREATE are specified and the
149391 + * mapping doesn't already exist, it will be created. If _SHARED and _CREATE are
149392 + * specified and the mapping already exists, the mapping will fail unless _LAZY
149393 + * is specified. When mapping to a pre-existing sharable map, the length must be
149394 + * an exact match. Lengths must be a power-of-4 multiple of page size.
149395 + *
149396 + * Note that this does not actually map the memory to user-space, that is done
149397 + * by a subsequent mmap() using the page offset returned from this ioctl(). The
149398 + * ioctl() is what gives the process permission to do this, and a page-offset
149399 + * with which to do so.
149400 + */
149401 +#define USDPAA_DMA_FLAG_SHARE 0x01
149402 +#define USDPAA_DMA_FLAG_CREATE 0x02
149403 +#define USDPAA_DMA_FLAG_LAZY 0x04
149404 +#define USDPAA_DMA_FLAG_RDONLY 0x08
149405 +struct usdpaa_ioctl_dma_map {
149406 + /* Output parameters - virtual and physical addresses */
149407 + void *ptr;
149408 + uint64_t phys_addr;
149409 + /* Input parameter, the length of the region to be created (or if
149410 + * mapping an existing region, this must match it). Must be a power-of-4
149411 + * multiple of page size. */
149412 + uint64_t len;
149413 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
149414 + uint32_t flags;
149415 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
149416 + * of the existing mapping to use). */
149417 + char name[USDPAA_DMA_NAME_MAX];
149418 + /* If this ioctl() creates the mapping, this is an input parameter
149419 + * stating whether the region supports locking. If mapping an existing
149420 + * region, this is a return value indicating the same thing. */
149421 + int has_locking;
149422 + /* In the case of a successful map with _CREATE and _LAZY, this return
149423 + * value indicates whether we created the mapped region or whether it
149424 + * already existed. */
149425 + int did_create;
149426 +};
149427 +
149428 +#ifdef CONFIG_COMPAT
149429 +struct usdpaa_ioctl_dma_map_compat {
149430 + /* Output parameters - virtual and physical addresses */
149431 + compat_uptr_t ptr;
149432 + uint64_t phys_addr;
149433 + /* Input parameter, the length of the region to be created (or if
149434 + * mapping an existing region, this must match it). Must be a power-of-4
149435 + * multiple of page size. */
149436 + uint64_t len;
149437 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
149438 + uint32_t flags;
149439 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
149440 + * of the existing mapping to use). */
149441 + char name[USDPAA_DMA_NAME_MAX];
149442 + /* If this ioctl() creates the mapping, this is an input parameter
149443 + * stating whether the region supports locking. If mapping an existing
149444 + * region, this is a return value indicating the same thing. */
149445 + int has_locking;
149446 + /* In the case of a successful map with _CREATE and _LAZY, this return
149447 + * value indicates whether we created the mapped region or whether it
149448 + * already existed. */
149449 + int did_create;
149450 +};
149451 +
149452 +#define USDPAA_IOCTL_DMA_MAP_COMPAT \
149453 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map_compat)
149454 +#endif
149455 +
149456 +
149457 +#define USDPAA_IOCTL_DMA_MAP \
149458 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map)
149459 +/* munmap() does not remove the DMA map, just the user-space mapping to it.
149460 + * This ioctl will do both (though you can munmap() before calling the ioctl
149461 + * too). */
149462 +#define USDPAA_IOCTL_DMA_UNMAP \
149463 + _IOW(USDPAA_IOCTL_MAGIC, 0x04, unsigned char)
149464 +/* We implement a cross-process locking scheme per DMA map. Call this ioctl()
149465 + * with a mmap()'d address, and the process will (interruptible) sleep if the
149466 + * lock is already held by another process. Process destruction will
149467 + * automatically clean up any held locks. */
149468 +#define USDPAA_IOCTL_DMA_LOCK \
149469 + _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char)
149470 +#define USDPAA_IOCTL_DMA_UNLOCK \
149471 + _IOW(USDPAA_IOCTL_MAGIC, 0x06, unsigned char)
149472 +
149473 +/***************************************/
149474 +/* Mapping and using QMan/BMan portals */
149475 +/***************************************/
149476 +enum usdpaa_portal_type {
149477 + usdpaa_portal_qman,
149478 + usdpaa_portal_bman,
149479 +};
149480 +
149481 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
149482 +
149483 +struct usdpaa_ioctl_portal_map {
149484 + /* Input parameter, is a qman or bman portal required. */
149485 +
149486 + enum usdpaa_portal_type type;
149487 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149488 + for don't care. The portal index will be populated by the
149489 + driver when the ioctl() successfully completes */
149490 + uint32_t index;
149491 +
149492 + /* Return value if the map succeeds, this gives the mapped
149493 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
149494 + struct usdpaa_portal_map {
149495 + void *cinh;
149496 + void *cena;
149497 + } addr;
149498 + /* Qman-specific return values */
149499 + uint16_t channel;
149500 + uint32_t pools;
149501 +};
149502 +
149503 +#ifdef CONFIG_COMPAT
149504 +struct compat_usdpaa_ioctl_portal_map {
149505 + /* Input parameter, is a qman or bman portal required. */
149506 + enum usdpaa_portal_type type;
149507 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149508 + for don't care. The portal index will be populated by the
149509 + driver when the ioctl() successfully completes */
149510 + uint32_t index;
149511 + /* Return value if the map succeeds, this gives the mapped
149512 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
149513 + struct usdpaa_portal_map_compat {
149514 + compat_uptr_t cinh;
149515 + compat_uptr_t cena;
149516 + } addr;
149517 + /* Qman-specific return values */
149518 + uint16_t channel;
149519 + uint32_t pools;
149520 +};
149521 +#define USDPAA_IOCTL_PORTAL_MAP_COMPAT \
149522 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct compat_usdpaa_ioctl_portal_map)
149523 +#define USDPAA_IOCTL_PORTAL_UNMAP_COMPAT \
149524 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map_compat)
149525 +#endif
149526 +
149527 +#define USDPAA_IOCTL_PORTAL_MAP \
149528 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct usdpaa_ioctl_portal_map)
149529 +#define USDPAA_IOCTL_PORTAL_UNMAP \
149530 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map)
149531 +
149532 +struct usdpaa_ioctl_irq_map {
149533 + enum usdpaa_portal_type type; /* Type of portal to map */
149534 + int fd; /* File descriptor that contains the portal */
149535 + void *portal_cinh; /* Cache inhibited area to identify the portal */
149536 +};
149537 +
149538 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP \
149539 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct usdpaa_ioctl_irq_map)
149540 +
149541 +#ifdef CONFIG_COMPAT
149542 +
149543 +struct compat_ioctl_irq_map {
149544 + enum usdpaa_portal_type type; /* Type of portal to map */
149545 + compat_int_t fd; /* File descriptor that contains the portal */
149546 + compat_uptr_t portal_cinh; /* Used identify the portal */};
149547 +
149548 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT \
149549 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct compat_ioctl_irq_map)
149550 +#endif
149551 +
149552 +/* ioctl to query the amount of DMA memory used in the system */
149553 +struct usdpaa_ioctl_dma_used {
149554 + uint64_t free_bytes;
149555 + uint64_t total_bytes;
149556 +};
149557 +#define USDPAA_IOCTL_DMA_USED \
149558 + _IOR(USDPAA_IOCTL_MAGIC, 0x0B, struct usdpaa_ioctl_dma_used)
149559 +
149560 +/* ioctl to allocate a raw portal */
149561 +struct usdpaa_ioctl_raw_portal {
149562 + /* inputs */
149563 + enum usdpaa_portal_type type; /* Type of portal to allocate */
149564 +
149565 + /* set to non zero to turn on stashing */
149566 + uint8_t enable_stash;
149567 + /* Stashing attributes for the portal */
149568 + uint32_t cpu;
149569 + uint32_t cache;
149570 + uint32_t window;
149571 +
149572 + /* Specifies the stash request queue this portal should use */
149573 + uint8_t sdest;
149574 +
149575 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149576 + * for don't care. The portal index will be populated by the
149577 + * driver when the ioctl() successfully completes */
149578 + uint32_t index;
149579 +
149580 + /* outputs */
149581 + uint64_t cinh;
149582 + uint64_t cena;
149583 +};
149584 +
149585 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL \
149586 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct usdpaa_ioctl_raw_portal)
149587 +
149588 +#define USDPAA_IOCTL_FREE_RAW_PORTAL \
149589 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct usdpaa_ioctl_raw_portal)
149590 +
149591 +#ifdef CONFIG_COMPAT
149592 +
149593 +struct compat_ioctl_raw_portal {
149594 + /* inputs */
149595 + enum usdpaa_portal_type type; /* Type of portal to allocate */
149596 +
149597 + /* set to non zero to turn on stashing */
149598 + uint8_t enable_stash;
149599 + /* Stashing attributes for the portal */
149600 + uint32_t cpu;
149601 + uint32_t cache;
149602 + uint32_t window;
149603 + /* Specifies the stash request queue this portal should use */
149604 + uint8_t sdest;
149605 +
149606 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149607 + * for don't care. The portal index will be populated by the
149608 + * driver when the ioctl() successfully completes */
149609 + uint32_t index;
149610 +
149611 + /* outputs */
149612 + uint64_t cinh;
149613 + uint64_t cena;
149614 +};
149615 +
149616 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT \
149617 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct compat_ioctl_raw_portal)
149618 +
149619 +#define USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT \
149620 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct compat_ioctl_raw_portal)
149621 +
149622 +#endif
149623 +
149624 +#ifdef __KERNEL__
149625 +
149626 +/* Early-boot hook */
149627 +int __init fsl_usdpaa_init_early(void);
149628 +
149629 +/* Fault-handling in arch/powerpc/mm/mem.c gives USDPAA an opportunity to detect
149630 + * faults within its ranges via this hook. */
149631 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size);
149632 +
149633 +#endif /* __KERNEL__ */
149634 +
149635 +#endif /* CONFIG_FSL_USDPAA */
149636 +
149637 +#ifdef __KERNEL__
149638 +/* This interface is needed in a few places and though it's not specific to
149639 + * USDPAA as such, creating a new header for it doesn't make any sense. The
149640 + * qbman kernel driver implements this interface and uses it as the backend for
149641 + * both the FQID and BPID allocators. The fsl_usdpaa driver also uses this
149642 + * interface for tracking per-process allocations handed out to user-space. */
149643 +struct dpa_alloc {
149644 + struct list_head free;
149645 + spinlock_t lock;
149646 + struct list_head used;
149647 +};
149648 +#define DECLARE_DPA_ALLOC(name) \
149649 + struct dpa_alloc name = { \
149650 + .free = { \
149651 + .prev = &name.free, \
149652 + .next = &name.free \
149653 + }, \
149654 + .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
149655 + .used = { \
149656 + .prev = &name.used, \
149657 + .next = &name.used \
149658 + } \
149659 + }
149660 +static inline void dpa_alloc_init(struct dpa_alloc *alloc)
149661 +{
149662 + INIT_LIST_HEAD(&alloc->free);
149663 + INIT_LIST_HEAD(&alloc->used);
149664 + spin_lock_init(&alloc->lock);
149665 +}
149666 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
149667 + int partial);
149668 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count);
149669 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 fqid, u32 count);
149670 +
149671 +/* Like 'new' but specifies the desired range, returns -ENOMEM if the entire
149672 + * desired range is not available, or 0 for success. */
149673 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base_id, u32 count);
149674 +/* Pops and returns contiguous ranges from the allocator. Returns -ENOMEM when
149675 + * 'alloc' is empty. */
149676 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count);
149677 +/* Returns 1 if the specified id is alloced, 0 otherwise */
149678 +int dpa_alloc_check(struct dpa_alloc *list, u32 id);
149679 +#endif /* __KERNEL__ */
149680 +
149681 +#ifdef __cplusplus
149682 +}
149683 +#endif
149684 +
149685 +#endif /* FSL_USDPAA_H */
149686 diff --git a/include/uapi/linux/fmd/Kbuild b/include/uapi/linux/fmd/Kbuild
149687 new file mode 100644
149688 index 00000000..56a20401
149689 --- /dev/null
149690 +++ b/include/uapi/linux/fmd/Kbuild
149691 @@ -0,0 +1,5 @@
149692 +header-y += integrations/
149693 +header-y += Peripherals/
149694 +
149695 +header-y += ioctls.h
149696 +header-y += net_ioctls.h
149697 diff --git a/include/uapi/linux/fmd/Peripherals/Kbuild b/include/uapi/linux/fmd/Peripherals/Kbuild
149698 new file mode 100644
149699 index 00000000..43883efe
149700 --- /dev/null
149701 +++ b/include/uapi/linux/fmd/Peripherals/Kbuild
149702 @@ -0,0 +1,4 @@
149703 +header-y += fm_ioctls.h
149704 +header-y += fm_port_ioctls.h
149705 +header-y += fm_pcd_ioctls.h
149706 +header-y += fm_test_ioctls.h
149707 diff --git a/include/uapi/linux/fmd/Peripherals/fm_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h
149708 new file mode 100644
149709 index 00000000..e0c2dd31
149710 --- /dev/null
149711 +++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h
149712 @@ -0,0 +1,628 @@
149713 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
149714 + * All rights reserved.
149715 + *
149716 + * Redistribution and use in source and binary forms, with or without
149717 + * modification, are permitted provided that the following conditions are met:
149718 + * * Redistributions of source code must retain the above copyright
149719 + * notice, this list of conditions and the following disclaimer.
149720 + * * Redistributions in binary form must reproduce the above copyright
149721 + * notice, this list of conditions and the following disclaimer in the
149722 + * documentation and/or other materials provided with the distribution.
149723 + * * Neither the name of Freescale Semiconductor nor the
149724 + * names of its contributors may be used to endorse or promote products
149725 + * derived from this software without specific prior written permission.
149726 + *
149727 + *
149728 + * ALTERNATIVELY, this software may be distributed under the terms of the
149729 + * GNU General Public License ("GPL") as published by the Free Software
149730 + * Foundation, either version 2 of that License or (at your option) any
149731 + * later version.
149732 + *
149733 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
149734 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
149735 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
149736 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
149737 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
149738 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
149739 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
149740 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
149741 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
149742 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
149743 + */
149744 +
149745 +/**************************************************************************//**
149746 + @File fm_ioctls.h
149747 +
149748 + @Description FM Char device ioctls
149749 +*//***************************************************************************/
149750 +#ifndef __FM_IOCTLS_H
149751 +#define __FM_IOCTLS_H
149752 +
149753 +
149754 +/**************************************************************************//**
149755 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
149756 +
149757 + @Description FM Linux ioctls definitions and enums
149758 +
149759 + @{
149760 +*//***************************************************************************/
149761 +
149762 +/**************************************************************************//**
149763 + @Collection FM IOCTL device ('/dev') definitions
149764 +*//***************************************************************************/
149765 +#define DEV_FM_NAME "fm" /**< Name of the FM chardev */
149766 +
149767 +#define DEV_FM_MINOR_BASE 0
149768 +#define DEV_FM_PCD_MINOR_BASE (DEV_FM_MINOR_BASE + 1) /*/dev/fmx-pcd */
149769 +#define DEV_FM_OH_PORTS_MINOR_BASE (DEV_FM_PCD_MINOR_BASE + 1) /*/dev/fmx-port-ohy */
149770 +#define DEV_FM_RX_PORTS_MINOR_BASE (DEV_FM_OH_PORTS_MINOR_BASE + FM_MAX_NUM_OF_OH_PORTS) /*/dev/fmx-port-rxy */
149771 +#define DEV_FM_TX_PORTS_MINOR_BASE (DEV_FM_RX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_RX_PORTS) /*/dev/fmx-port-txy */
149772 +#define DEV_FM_MAX_MINORS (DEV_FM_TX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_TX_PORTS)
149773 +
149774 +#define FM_IOC_NUM(n) (n)
149775 +#define FM_PCD_IOC_NUM(n) (n+20)
149776 +#define FM_PORT_IOC_NUM(n) (n+70)
149777 +/* @} */
149778 +
149779 +#define IOC_FM_MAX_NUM_OF_PORTS 64
149780 +
149781 +
149782 +/**************************************************************************//**
149783 + @Description Enum for defining port types
149784 + (must match enum e_FmPortType defined in fm_ext.h)
149785 +*//***************************************************************************/
149786 +typedef enum ioc_fm_port_type {
149787 + e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
149788 + e_IOC_FM_PORT_TYPE_RX, /**< 1G Rx port */
149789 + e_IOC_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
149790 + e_IOC_FM_PORT_TYPE_TX, /**< 1G Tx port */
149791 + e_IOC_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
149792 + e_IOC_FM_PORT_TYPE_DUMMY
149793 +} ioc_fm_port_type;
149794 +
149795 +
149796 +/**************************************************************************//**
149797 + @Group lnx_ioctl_FM_lib_grp FM library
149798 +
149799 + @Description FM API functions, definitions and enums
149800 + The FM module is the main driver module and is a mandatory module
149801 + for FM driver users. Before any further module initialization,
149802 + this module must be initialized.
149803 + The FM is a "single-tone" module. It is responsible of the common
149804 + HW modules: FPM, DMA, common QMI, common BMI initializations and
149805 + run-time control routines. This module must be initialized always
149806 + when working with any of the FM modules.
149807 + NOTE - We assumes that the FML will be initialize only by core No. 0!
149808 +
149809 + @{
149810 +*//***************************************************************************/
149811 +
149812 +/**************************************************************************//**
149813 + @Description FM Exceptions
149814 +*//***************************************************************************/
149815 +typedef enum ioc_fm_exceptions {
149816 + e_IOC_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */
149817 + e_IOC_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
149818 + e_IOC_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
149819 + e_IOC_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
149820 + e_IOC_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
149821 + e_IOC_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
149822 + e_IOC_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
149823 + e_IOC_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
149824 + e_IOC_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
149825 + e_IOC_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
149826 + e_IOC_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
149827 + e_IOC_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
149828 + e_IOC_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
149829 + e_IOC_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
149830 + e_IOC_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
149831 + e_IOC_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
149832 + e_IOC_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
149833 +} ioc_fm_exceptions;
149834 +
149835 +/**************************************************************************//**
149836 + @Group lnx_ioctl_FM_runtime_control_grp FM Runtime Control Unit
149837 +
149838 + @Description FM Runtime control unit API functions, definitions and enums.
149839 + The FM driver provides a set of control routines for each module.
149840 + These routines may only be called after the module was fully
149841 + initialized (both configuration and initialization routines were
149842 + called). They are typically used to get information from hardware
149843 + (status, counters/statistics, revision etc.), to modify a current
149844 + state or to force/enable a required action. Run-time control may
149845 + be called whenever necessary and as many times as needed.
149846 + @{
149847 +*//***************************************************************************/
149848 +
149849 +/**************************************************************************//**
149850 + @Collection General FM defines.
149851 + *//***************************************************************************/
149852 +#define IOC_FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
149853 + FM_MAX_NUM_OF_1G_RX_PORTS + \
149854 + FM_MAX_NUM_OF_10G_RX_PORTS + \
149855 + FM_MAX_NUM_OF_1G_TX_PORTS + \
149856 + FM_MAX_NUM_OF_10G_TX_PORTS)
149857 +/* @} */
149858 +
149859 +/**************************************************************************//**
149860 + @Description Structure for Port bandwidth requirement. Port is identified
149861 + by type and relative id.
149862 + (must be identical to t_FmPortBandwidth defined in fm_ext.h)
149863 +*//***************************************************************************/
149864 +typedef struct ioc_fm_port_bandwidth_t {
149865 + ioc_fm_port_type type; /**< FM port type */
149866 + uint8_t relative_port_id; /**< Type relative port id */
149867 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
149868 +} ioc_fm_port_bandwidth_t;
149869 +
149870 +/**************************************************************************//**
149871 + @Description A Structure containing an array of Port bandwidth requirements.
149872 + The user should state the ports requiring bandwidth in terms of
149873 + percentage - i.e. all port's bandwidths in the array must add
149874 + up to 100.
149875 + (must be identical to t_FmPortsBandwidthParams defined in fm_ext.h)
149876 +*//***************************************************************************/
149877 +typedef struct ioc_fm_port_bandwidth_params {
149878 + uint8_t num_of_ports;
149879 + /**< num of ports listed in the array below */
149880 + ioc_fm_port_bandwidth_t ports_bandwidths[IOC_FM_MAX_NUM_OF_VALID_PORTS];
149881 + /**< for each port, it's bandwidth (all port's
149882 + bandwidths must add up to 100.*/
149883 +} ioc_fm_port_bandwidth_params;
149884 +
149885 +/**************************************************************************//**
149886 + @Description enum for defining FM counters
149887 +*//***************************************************************************/
149888 +typedef enum ioc_fm_counters {
149889 + e_IOC_FM_COUNTERS_ENQ_TOTAL_FRAME, /**< QMI total enqueued frames counter */
149890 + e_IOC_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
149891 + e_IOC_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
149892 + e_IOC_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
149893 + e_IOC_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
149894 + e_IOC_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
149895 + e_IOC_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
149896 + e_IOC_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
149897 + e_IOC_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
149898 + e_IOC_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
149899 +} ioc_fm_counters;
149900 +
149901 +typedef struct ioc_fm_obj_t {
149902 + void *obj;
149903 +} ioc_fm_obj_t;
149904 +
149905 +/**************************************************************************//**
149906 + @Description A structure for returning revision information
149907 + (must match struct t_FmRevisionInfo declared in fm_ext.h)
149908 +*//***************************************************************************/
149909 +typedef struct ioc_fm_revision_info_t {
149910 + uint8_t major; /**< Major revision */
149911 + uint8_t minor; /**< Minor revision */
149912 +} ioc_fm_revision_info_t;
149913 +
149914 +/**************************************************************************//**
149915 + @Description A structure for FM counters
149916 +*//***************************************************************************/
149917 +typedef struct ioc_fm_counters_params_t {
149918 + ioc_fm_counters cnt; /**< The requested counter */
149919 + uint32_t val; /**< The requested value to get/set from/into the counter */
149920 +} ioc_fm_counters_params_t;
149921 +
149922 +typedef union ioc_fm_api_version_t {
149923 + struct {
149924 + uint8_t major;
149925 + uint8_t minor;
149926 + uint8_t respin;
149927 + uint8_t reserved;
149928 + } version;
149929 + uint32_t ver;
149930 +} ioc_fm_api_version_t;
149931 +
149932 +#if (DPAA_VERSION >= 11)
149933 +/**************************************************************************//**
149934 + @Description A structure of information about each of the external
149935 + buffer pools used by a port or storage-profile.
149936 + (must be identical to t_FmExtPoolParams defined in fm_ext.h)
149937 +*//***************************************************************************/
149938 +typedef struct ioc_fm_ext_pool_params {
149939 + uint8_t id; /**< External buffer pool id */
149940 + uint16_t size; /**< External buffer pool buffer size */
149941 +} ioc_fm_ext_pool_params;
149942 +
149943 +/**************************************************************************//**
149944 + @Description A structure for informing the driver about the external
149945 + buffer pools allocated in the BM and used by a port or a
149946 + storage-profile.
149947 + (must be identical to t_FmExtPools defined in fm_ext.h)
149948 +*//***************************************************************************/
149949 +typedef struct ioc_fm_ext_pools {
149950 + uint8_t num_of_pools_used; /**< Number of pools use by this port */
149951 + ioc_fm_ext_pool_params ext_buf_pool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
149952 + /**< Parameters for each port */
149953 +} ioc_fm_ext_pools;
149954 +
149955 +typedef struct ioc_fm_vsp_params_t {
149956 + void *p_fm; /**< A handle to the FM object this VSP related to */
149957 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
149958 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
149959 + parameter associated with Rx / OP port */
149960 + uint16_t liodn_offset; /**< VSP's LIODN offset */
149961 + struct {
149962 + ioc_fm_port_type port_type; /**< Port type */
149963 + uint8_t port_id; /**< Port Id - relative to type */
149964 + } port_params;
149965 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
149966 + defined in relevant FM object */
149967 + void *id; /**< return value */
149968 +} ioc_fm_vsp_params_t;
149969 +#endif /* (DPAA_VERSION >= 11) */
149970 +
149971 +/**************************************************************************//**
149972 + @Description A structure for defining BM pool depletion criteria
149973 +*//***************************************************************************/
149974 +typedef struct ioc_fm_buf_pool_depletion_t {
149975 + bool pools_grp_mode_enable; /**< select mode in which pause frames will be sent after
149976 + a number of pools (all together!) are depleted */
149977 + uint8_t num_of_pools; /**< the number of depleted pools that will invoke
149978 + pause frames transmission. */
149979 + bool pools_to_consider[BM_MAX_NUM_OF_POOLS];
149980 + /**< For each pool, TRUE if it should be considered for
149981 + depletion (Note - this pool must be used by this port!). */
149982 + bool single_pool_mode_enable; /**< select mode in which pause frames will be sent after
149983 + a single-pool is depleted; */
149984 + bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS];
149985 + /**< For each pool, TRUE if it should be considered for
149986 + depletion (Note - this pool must be used by this port!) */
149987 +#if (DPAA_VERSION >= 11)
149988 + bool pfc_priorities_en[FM_MAX_NUM_OF_PFC_PRIORITIES];
149989 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame
149990 + which is transmitted */
149991 +#endif /* (DPAA_VERSION >= 11) */
149992 +} ioc_fm_buf_pool_depletion_t;
149993 +
149994 +#if (DPAA_VERSION >= 11)
149995 +typedef struct ioc_fm_buf_pool_depletion_params_t {
149996 + void *p_fm_vsp;
149997 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
149998 +} ioc_fm_buf_pool_depletion_params_t;
149999 +#endif /* (DPAA_VERSION >= 11) */
150000 +
150001 +typedef struct ioc_fm_buffer_prefix_content_t {
150002 + uint16_t priv_data_size; /**< Number of bytes to be left at the beginning
150003 + of the external buffer; Note that the private-area will
150004 + start from the base of the buffer address. */
150005 + bool pass_prs_result; /**< TRUE to pass the parse result to/from the FM;
150006 + User may use FM_PORT_GetBufferPrsResult() in order to
150007 + get the parser-result from a buffer. */
150008 + bool pass_time_stamp; /**< TRUE to pass the timeStamp to/from the FM
150009 + User may use FM_PORT_GetBufferTimeStamp() in order to
150010 + get the parser-result from a buffer. */
150011 + bool pass_hash_result; /**< TRUE to pass the KG hash result to/from the FM
150012 + User may use FM_PORT_GetBufferHashResult() in order to
150013 + get the parser-result from a buffer. */
150014 + bool pass_all_other_pcd_info; /**< Add all other Internal-Context information:
150015 + AD, hash-result, key, etc. */
150016 + uint16_t data_align; /**< 0 to use driver's default alignment [64],
150017 + other value for selecting a data alignment (must be a power of 2);
150018 + if write optimization is used, must be >= 16. */
150019 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
150020 + Note that this field impacts the size of the buffer-prefix
150021 + (i.e. it pushes the data offset);
150022 + This field is irrelevant if DPAA_VERSION==10 */
150023 +} ioc_fm_buffer_prefix_content_t;
150024 +
150025 +typedef struct ioc_fm_buffer_prefix_content_params_t {
150026 + void *p_fm_vsp;
150027 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
150028 +} ioc_fm_buffer_prefix_content_params_t;
150029 +
150030 +#if (DPAA_VERSION >= 11)
150031 +typedef struct ioc_fm_vsp_config_no_sg_params_t {
150032 + void *p_fm_vsp;
150033 + bool no_sg;
150034 +} ioc_fm_vsp_config_no_sg_params_t;
150035 +
150036 +typedef struct ioc_fm_vsp_prs_result_params_t {
150037 + void *p_fm_vsp;
150038 + void *p_data;
150039 +} ioc_fm_vsp_prs_result_params_t;
150040 +#endif
150041 +
150042 +typedef struct fm_ctrl_mon_t {
150043 + uint8_t percent_cnt[2];
150044 +} fm_ctrl_mon_t;
150045 +
150046 +typedef struct ioc_fm_ctrl_mon_counters_params_t {
150047 + uint8_t fm_ctrl_index;
150048 + fm_ctrl_mon_t *p_mon;
150049 +} ioc_fm_ctrl_mon_counters_params_t;
150050 +
150051 +/**************************************************************************//**
150052 + @Function FM_IOC_SET_PORTS_BANDWIDTH
150053 +
150054 + @Description Sets relative weights between ports when accessing common resources.
150055 +
150056 + @Param[in] ioc_fm_port_bandwidth_params Port bandwidth percentages,
150057 + their sum must equal 100.
150058 +
150059 + @Return E_OK on success; Error code otherwise.
150060 +
150061 + @Cautions Allowed only following FM_Init().
150062 +*//***************************************************************************/
150063 +#define FM_IOC_SET_PORTS_BANDWIDTH _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(2), ioc_fm_port_bandwidth_params)
150064 +
150065 +/**************************************************************************//**
150066 + @Function FM_IOC_GET_REVISION
150067 +
150068 + @Description Returns the FM revision
150069 +
150070 + @Param[out] ioc_fm_revision_info_t A structure of revision information parameters.
150071 +
150072 + @Return None.
150073 +
150074 + @Cautions Allowed only following FM_Init().
150075 +*//***************************************************************************/
150076 +#define FM_IOC_GET_REVISION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(3), ioc_fm_revision_info_t)
150077 +
150078 +/**************************************************************************//**
150079 + @Function FM_IOC_GET_COUNTER
150080 +
150081 + @Description Reads one of the FM counters.
150082 +
150083 + @Param[in,out] ioc_fm_counters_params_t The requested counter parameters.
150084 +
150085 + @Return Counter's current value.
150086 +
150087 + @Cautions Allowed only following FM_Init().
150088 + Note that it is user's responsibilty to call this routine only
150089 + for enabled counters, and there will be no indication if a
150090 + disabled counter is accessed.
150091 +*//***************************************************************************/
150092 +#define FM_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(4), ioc_fm_counters_params_t)
150093 +
150094 +/**************************************************************************//**
150095 + @Function FM_IOC_SET_COUNTER
150096 +
150097 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
150098 +
150099 + @Param[in] ioc_fm_counters_params_t The requested counter parameters.
150100 +
150101 + @Return E_OK on success; Error code otherwise.
150102 +
150103 + @Cautions Allowed only following FM_Init().
150104 +*//***************************************************************************/
150105 +#define FM_IOC_SET_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(5), ioc_fm_counters_params_t)
150106 +
150107 +/**************************************************************************//**
150108 + @Function FM_IOC_FORCE_INTR
150109 +
150110 + @Description Causes an interrupt event on the requested source.
150111 +
150112 + @Param[in] ioc_fm_exceptions An exception to be forced.
150113 +
150114 + @Return E_OK on success; Error code if the exception is not enabled,
150115 + or is not able to create interrupt.
150116 +
150117 + @Cautions Allowed only following FM_Init().
150118 +*//***************************************************************************/
150119 +#define FM_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(6), ioc_fm_exceptions)
150120 +
150121 +/**************************************************************************//**
150122 + @Function FM_IOC_GET_API_VERSION
150123 +
150124 + @Description Reads the FMD IOCTL API version.
150125 +
150126 + @Param[in,out] ioc_fm_api_version_t The requested counter parameters.
150127 +
150128 + @Return Version's value.
150129 +*//***************************************************************************/
150130 +#define FM_IOC_GET_API_VERSION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(7), ioc_fm_api_version_t)
150131 +
150132 +#if (DPAA_VERSION >= 11)
150133 +/**************************************************************************//**
150134 + @Function FM_VSP_Config
150135 +
150136 + @Description Creates descriptor for the FM VSP module.
150137 +
150138 + The routine returns a handle (descriptor) to the FM VSP object.
150139 + This descriptor must be passed as first parameter to all other
150140 + FM VSP function calls.
150141 +
150142 + No actual initialization or configuration of FM hardware is
150143 + done by this routine.
150144 +
150145 +@Param[in] p_FmVspParams Pointer to data structure of parameters
150146 +
150147 + @Retval Handle to FM VSP object, or NULL for Failure.
150148 +*//***************************************************************************/
150149 +#if defined(CONFIG_COMPAT)
150150 +#define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t)
150151 +#endif
150152 +#define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t)
150153 +
150154 +/**************************************************************************//**
150155 + @Function FM_VSP_Init
150156 +
150157 + @Description Initializes the FM VSP module
150158 +
150159 + @Param[in] h_FmVsp - FM VSP module descriptor
150160 +
150161 + @Return E_OK on success; Error code otherwise.
150162 +*//***************************************************************************/
150163 +#if defined(CONFIG_COMPAT)
150164 +#define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t)
150165 +#endif
150166 +#define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t)
150167 +
150168 +/**************************************************************************//**
150169 + @Function FM_VSP_Free
150170 +
150171 + @Description Frees all resources that were assigned to FM VSP module.
150172 +
150173 + Calling this routine invalidates the descriptor.
150174 +
150175 + @Param[in] h_FmVsp - FM VSP module descriptor
150176 +
150177 + @Return E_OK on success; Error code otherwise.
150178 +*//***************************************************************************/
150179 +#if defined(CONFIG_COMPAT)
150180 +#define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t)
150181 +#endif
150182 +#define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t)
150183 +
150184 +/**************************************************************************//**
150185 + @Function FM_VSP_ConfigPoolDepletion
150186 +
150187 + @Description Calling this routine enables pause frame generation depending on the
150188 + depletion status of BM pools. It also defines the conditions to activate
150189 + this functionality. By default, this functionality is disabled.
150190 +
150191 + @Param[in] ioc_fm_buf_pool_depletion_params_t A structure holding the required parameters.
150192 +
150193 + @Return E_OK on success; Error code otherwise.
150194 +
150195 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
150196 +*//***************************************************************************/
150197 +#if defined(CONFIG_COMPAT)
150198 +#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)
150199 +#endif
150200 +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t)
150201 +
150202 +/**************************************************************************//**
150203 + @Function FM_VSP_ConfigBufferPrefixContent
150204 +
150205 + @Description Defines the structure, size and content of the application buffer.
150206 +
150207 + The prefix will
150208 + In VSPs defined for Tx ports, if 'passPrsResult', the application
150209 + should set a value to their offsets in the prefix of
150210 + the FM will save the first 'privDataSize', than,
150211 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
150212 + and timeStamp, and the packet itself (in this order), to the
150213 + application buffer, and to offset.
150214 +
150215 + Calling this routine changes the buffer margins definitions
150216 + in the internal driver data base from its default
150217 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
150218 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
150219 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
150220 +
150221 + @Param[in] ioc_fm_buffer_prefix_content_params_t A structure holding the required parameters.
150222 +
150223 + @Return E_OK on success; Error code otherwise.
150224 +
150225 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
150226 +*//***************************************************************************/
150227 +#if defined(CONFIG_COMPAT)
150228 +#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)
150229 +#endif
150230 +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t)
150231 +
150232 +/**************************************************************************//**
150233 + @Function FM_VSP_ConfigNoScatherGather
150234 +
150235 + @Description Calling this routine changes the possibility to receive S/G frame
150236 + in the internal driver data base
150237 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
150238 +
150239 + @Param[in] ioc_fm_vsp_config_no_sg_params_t A structure holding the required parameters.
150240 +
150241 + @Return E_OK on success; Error code otherwise.
150242 +
150243 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
150244 +*//***************************************************************************/
150245 +#if defined(CONFIG_COMPAT)
150246 +#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)
150247 +#endif
150248 +#define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t)
150249 +
150250 +/**************************************************************************//**
150251 + @Function FM_VSP_GetBufferPrsResult
150252 +
150253 + @Description Returns the pointer to the parse result in the data buffer.
150254 + In Rx ports this is relevant after reception, if parse
150255 + result is configured to be part of the data passed to the
150256 + application. For non Rx ports it may be used to get the pointer
150257 + of the area in the buffer where parse result should be
150258 + initialized - if so configured.
150259 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
150260 + configuration.
150261 +
150262 + @Param[in] ioc_fm_vsp_prs_result_params_t A structure holding the required parameters.
150263 +
150264 + @Return Parse result pointer on success, NULL if parse result was not
150265 + configured for this port.
150266 +
150267 + @Cautions Allowed only following FM_VSP_Init().
150268 +*//***************************************************************************/
150269 +#if defined(CONFIG_COMPAT)
150270 +#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)
150271 +#endif
150272 +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t)
150273 +#endif /* (DPAA_VERSION >= 11) */
150274 +
150275 +/**************************************************************************//**
150276 + @Function FM_CtrlMonStart
150277 +
150278 + @Description Start monitoring utilization of all available FM controllers.
150279 +
150280 + In order to obtain FM controllers utilization the following sequence
150281 + should be used:
150282 + -# FM_CtrlMonStart()
150283 + -# FM_CtrlMonStop()
150284 + -# FM_CtrlMonGetCounters() - issued for each FM controller
150285 +
150286 + @Return E_OK on success; Error code otherwise.
150287 +
150288 + @Cautions Allowed only following FM_Init().
150289 +*//***************************************************************************/
150290 +#define FM_IOC_CTRL_MON_START _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(15))
150291 +
150292 +
150293 +/**************************************************************************//**
150294 + @Function FM_CtrlMonStop
150295 +
150296 + @Description Stop monitoring utilization of all available FM controllers.
150297 +
150298 + In order to obtain FM controllers utilization the following sequence
150299 + should be used:
150300 + -# FM_CtrlMonStart()
150301 + -# FM_CtrlMonStop()
150302 + -# FM_CtrlMonGetCounters() - issued for each FM controller
150303 +
150304 + @Return E_OK on success; Error code otherwise.
150305 +
150306 + @Cautions Allowed only following FM_Init().
150307 +*//***************************************************************************/
150308 +#define FM_IOC_CTRL_MON_STOP _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(16))
150309 +
150310 +/**************************************************************************//**
150311 + @Function FM_CtrlMonGetCounters
150312 +
150313 + @Description Obtain FM controller utilization parameters.
150314 +
150315 + In order to obtain FM controllers utilization the following sequence
150316 + should be used:
150317 + -# FM_CtrlMonStart()
150318 + -# FM_CtrlMonStop()
150319 + -# FM_CtrlMonGetCounters() - issued for each FM controller
150320 +
150321 + @Param[in] ioc_fm_ctrl_mon_counters_params_t A structure holding the required parameters.
150322 +
150323 + @Return E_OK on success; Error code otherwise.
150324 +
150325 + @Cautions Allowed only following FM_Init().
150326 +*//***************************************************************************/
150327 +#if defined(CONFIG_COMPAT)
150328 +#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)
150329 +#endif
150330 +#define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t)
150331 +
150332 +/** @} */ /* end of lnx_ioctl_FM_runtime_control_grp group */
150333 +/** @} */ /* end of lnx_ioctl_FM_lib_grp group */
150334 +/** @} */ /* end of lnx_ioctl_FM_grp */
150335 +
150336 +#define FMD_API_VERSION_MAJOR 21
150337 +#define FMD_API_VERSION_MINOR 1
150338 +#define FMD_API_VERSION_RESPIN 0
150339 +
150340 +#endif /* __FM_IOCTLS_H */
150341 diff --git a/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
150342 new file mode 100644
150343 index 00000000..d13e878d
150344 --- /dev/null
150345 +++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
150346 @@ -0,0 +1,3084 @@
150347 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
150348 + * All rights reserved.
150349 + *
150350 + * Redistribution and use in source and binary forms, with or without
150351 + * modification, are permitted provided that the following conditions are met:
150352 + * * Redistributions of source code must retain the above copyright
150353 + * notice, this list of conditions and the following disclaimer.
150354 + * * Redistributions in binary form must reproduce the above copyright
150355 + * notice, this list of conditions and the following disclaimer in the
150356 + * documentation and/or other materials provided with the distribution.
150357 + * * Neither the name of Freescale Semiconductor nor the
150358 + * names of its contributors may be used to endorse or promote products
150359 + * derived from this software without specific prior written permission.
150360 + *
150361 + *
150362 + * ALTERNATIVELY, this software may be distributed under the terms of the
150363 + * GNU General Public License ("GPL") as published by the Free Software
150364 + * Foundation, either version 2 of that License or (at your option) any
150365 + * later version.
150366 + *
150367 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
150368 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
150369 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
150370 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
150371 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
150372 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
150373 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
150374 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
150375 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
150376 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
150377 + */
150378 +
150379 +
150380 +/******************************************************************************
150381 + @File fm_pcd_ioctls.h
150382 +
150383 + @Description FM PCD ...
150384 +*//***************************************************************************/
150385 +#ifndef __FM_PCD_IOCTLS_H
150386 +#define __FM_PCD_IOCTLS_H
150387 +
150388 +#include "net_ioctls.h"
150389 +#include "fm_ioctls.h"
150390 +
150391 +
150392 +/**************************************************************************//**
150393 +
150394 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
150395 +
150396 + @Description Frame Manager Linux ioctls definitions and enums
150397 +
150398 + @{
150399 +*//***************************************************************************/
150400 +
150401 +/**************************************************************************//**
150402 + @Group lnx_ioctl_FM_PCD_grp FM PCD
150403 +
150404 + @Description Frame Manager PCD API functions, definitions and enums
150405 +
150406 + The FM PCD module is responsible for the initialization of all
150407 + global classifying FM modules. This includes the parser general and
150408 + common registers, the key generator global and common registers,
150409 + and the policer global and common registers.
150410 + In addition, the FM PCD SW module will initialize all required
150411 + key generator schemes, coarse classification flows, and policer
150412 + profiles. When an FM module is configured to work with one of these
150413 + entities, it will register to it using the FM PORT API. The PCD
150414 + module will manage the PCD resources - i.e. resource management of
150415 + KeyGen schemes, etc.
150416 +
150417 + @{
150418 +*//***************************************************************************/
150419 +
150420 +/**************************************************************************//**
150421 + @Collection General PCD defines
150422 +*//***************************************************************************/
150423 +#define IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
150424 +
150425 +#define IOC_FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
150426 +#define IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
150427 + /**< Number of distinction units is limited by
150428 + register size (32 bits) minus reserved bits
150429 + for private headers. */
150430 +#define IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
150431 + in a distinction unit */
150432 +#define IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KeyGen registers */
150433 +#define IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
150434 + For HW implementation reasons, in most
150435 + cases less than this will be allowed; The
150436 + driver will return an initialization error
150437 + if resource is unavailable. */
150438 +#define IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
150439 +#define IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
150440 +
150441 +#define IOC_FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
150442 +#define IOC_FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
150443 +
150444 +#define IOC_FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
150445 + insert manipulation */
150446 +
150447 +#if DPAA_VERSION >= 11
150448 +#define IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
150449 +#endif /* DPAA_VERSION >= 11 */
150450 +/* @} */
150451 +
150452 +#ifdef FM_CAPWAP_SUPPORT
150453 +#error "FM_CAPWAP_SUPPORT not implemented!"
150454 +#endif
150455 +
150456 +
150457 +/**************************************************************************//**
150458 + @Group lnx_ioctl_FM_PCD_init_grp FM PCD Initialization Unit
150459 +
150460 + @Description Frame Manager PCD Initialization Unit API
150461 +
150462 + @{
150463 +*//***************************************************************************/
150464 +
150465 +/**************************************************************************//**
150466 + @Description PCD counters
150467 + (must match enum e_FmPcdCounters defined in fm_pcd_ext.h)
150468 +*//***************************************************************************/
150469 +typedef enum ioc_fm_pcd_counters {
150470 + e_IOC_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
150471 + e_IOC_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
150472 + e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
150473 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
150474 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
150475 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
150476 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
150477 + e_IOC_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
150478 + e_IOC_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
150479 + e_IOC_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
150480 + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
150481 + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
150482 + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
150483 + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
150484 + 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. */
150485 + 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. */
150486 + 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. */
150487 + 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. */
150488 + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
150489 + 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. */
150490 + 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). */
150491 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
150492 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
150493 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
150494 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
150495 + e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
150496 +} ioc_fm_pcd_counters;
150497 +
150498 +/**************************************************************************//**
150499 + @Description PCD interrupts
150500 + (must match enum e_FmPcdExceptions defined in fm_pcd_ext.h)
150501 +*//***************************************************************************/
150502 +typedef enum ioc_fm_pcd_exceptions {
150503 + e_IOC_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
150504 + e_IOC_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
150505 + e_IOC_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
150506 + e_IOC_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
150507 + e_IOC_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
150508 + e_IOC_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
150509 + e_IOC_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
150510 + e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
150511 +} ioc_fm_pcd_exceptions;
150512 +
150513 +/** @} */ /* end of lnx_ioctl_FM_PCD_init_grp group */
150514 +
150515 +
150516 +/**************************************************************************//**
150517 + @Group lnx_ioctl_FM_PCD_Runtime_grp FM PCD Runtime Unit
150518 +
150519 + @Description Frame Manager PCD Runtime Unit
150520 +
150521 + The runtime control allows creation of PCD infrastructure modules
150522 + such as Network Environment Characteristics, Classification Plan
150523 + Groups and Coarse Classification Trees.
150524 + It also allows on-the-fly initialization, modification and removal
150525 + of PCD modules such as KeyGen schemes, coarse classification nodes
150526 + and Policer profiles.
150527 +
150528 + In order to explain the programming model of the PCD driver interface
150529 + a few terms should be explained, and will be used below.
150530 + - Distinction Header - One of the 16 protocols supported by the FM parser,
150531 + or one of the SHIM headers (1 or 2). May be a header with a special
150532 + option (see below).
150533 + - Interchangeable Headers Group - This is a group of Headers recognized
150534 + by either one of them. For example, if in a specific context the user
150535 + chooses to treat IPv4 and IPV6 in the same way, they may create an
150536 + interchangeable Headers Unit consisting of these 2 headers.
150537 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
150538 + Group.
150539 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
150540 + IPv6, includes multicast, broadcast and other protocol specific options.
150541 + In terms of hardware it relates to the options available in the classification
150542 + plan.
150543 + - Network Environment Characteristics - a set of Distinction Units that define
150544 + the total recognizable header selection for a certain environment. This is
150545 + NOT the list of all headers that will ever appear in a flow, but rather
150546 + everything that needs distinction in a flow, where distinction is made by KeyGen
150547 + schemes and coarse classification action descriptors.
150548 +
150549 + The PCD runtime modules initialization is done in stages. The first stage after
150550 + initializing the PCD module itself is to establish a Network Flows Environment
150551 + Definition. The application may choose to establish one or more such environments.
150552 + Later, when needed, the application will have to state, for some of its modules,
150553 + to which single environment it belongs.
150554 +
150555 + @{
150556 +*//***************************************************************************/
150557 +
150558 +
150559 +/**************************************************************************//**
150560 + @Description structure for FM counters
150561 +*//***************************************************************************/
150562 +typedef struct ioc_fm_pcd_counters_params_t {
150563 + ioc_fm_pcd_counters cnt; /**< The requested counter */
150564 + uint32_t val; /**< The requested value to get/set from/into the counter */
150565 +} ioc_fm_pcd_counters_params_t;
150566 +
150567 +/**************************************************************************//**
150568 + @Description structure for FM exception definitios
150569 +*//***************************************************************************/
150570 +typedef struct ioc_fm_pcd_exception_params_t {
150571 + ioc_fm_pcd_exceptions exception; /**< The requested exception */
150572 + bool enable; /**< TRUE to enable interrupt, FALSE to mask it. */
150573 +} ioc_fm_pcd_exception_params_t;
150574 +
150575 +/**************************************************************************//**
150576 + @Description A structure for SW parser labels
150577 + (must be identical to struct t_FmPcdPrsLabelParams defined in fm_pcd_ext.h)
150578 + *//***************************************************************************/
150579 +typedef struct ioc_fm_pcd_prs_label_params_t {
150580 + uint32_t instruction_offset; /**< SW parser label instruction offset (2 bytes
150581 + resolution), relative to Parser RAM. */
150582 + ioc_net_header_type hdr; /**< The existence of this header will invoke
150583 + the SW parser code. */
150584 + uint8_t index_per_hdr; /**< Normally 0, if more than one SW parser
150585 + attachments for the same header, use this
150586 + index to distinguish between them. */
150587 +} ioc_fm_pcd_prs_label_params_t;
150588 +
150589 +/**************************************************************************//**
150590 + @Description A structure for SW parser
150591 + (Must match struct t_FmPcdPrsSwParams defined in fm_pcd_ext.h)
150592 + *//***************************************************************************/
150593 +typedef struct ioc_fm_pcd_prs_sw_params_t {
150594 + bool override; /**< FALSE to invoke a check that nothing else
150595 + was loaded to this address, including
150596 + internal patches.
150597 + TRUE to override any existing code.*/
150598 + uint32_t size; /**< SW parser code size */
150599 + uint16_t base; /**< SW parser base (in instruction counts!
150600 + must be larger than 0x20)*/
150601 + uint8_t *p_code; /**< SW parser code */
150602 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
150603 + /**< SW parser data (parameters) */
150604 + uint8_t num_of_labels; /**< Number of labels for SW parser. */
150605 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
150606 + /**< SW parser labels table,
150607 + containing num_of_labels entries */
150608 +} ioc_fm_pcd_prs_sw_params_t;
150609 +
150610 +/**************************************************************************//**
150611 + @Description A structure to set the a KeyGen default value
150612 + *//***************************************************************************/
150613 +typedef struct ioc_fm_pcd_kg_dflt_value_params_t {
150614 + uint8_t valueId; /**< 0,1 - one of 2 global default values */
150615 + uint32_t value; /**< The requested default value */
150616 +} ioc_fm_pcd_kg_dflt_value_params_t;
150617 +
150618 +
150619 +/**************************************************************************//**
150620 + @Function FM_PCD_Enable
150621 +
150622 + @Description This routine should be called after PCD is initialized for enabling all
150623 + PCD engines according to their existing configuration.
150624 +
150625 + @Return 0 on success; Error code otherwise.
150626 +
150627 + @Cautions Allowed only when PCD is disabled.
150628 +*//***************************************************************************/
150629 +#define FM_PCD_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(1))
150630 +
150631 +/**************************************************************************//**
150632 + @Function FM_PCD_Disable
150633 +
150634 + @Description This routine may be called when PCD is enabled in order to
150635 + disable all PCD engines. It may be called
150636 + only when none of the ports in the system are using the PCD.
150637 +
150638 + @Return 0 on success; Error code otherwise.
150639 +
150640 + @Cautions Allowed only when PCD is enabled.
150641 +*//***************************************************************************/
150642 +#define FM_PCD_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(2))
150643 +
150644 + /**************************************************************************//**
150645 + @Function FM_PCD_PrsLoadSw
150646 +
150647 + @Description This routine may be called only when all ports in the
150648 + system are actively using the classification plan scheme.
150649 + In such cases it is recommended in order to save resources.
150650 + The driver automatically saves 8 classification plans for
150651 + ports that do NOT use the classification plan mechanism, to
150652 + avoid this (in order to save those entries) this routine may
150653 + be called.
150654 +
150655 + @Param[in] ioc_fm_pcd_prs_sw_params_t A pointer to the image of the software parser code.
150656 +
150657 + @Return 0 on success; Error code otherwise.
150658 +
150659 + @Cautions Allowed only when PCD is disabled.
150660 +*//***************************************************************************/
150661 +#if defined(CONFIG_COMPAT)
150662 +#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)
150663 +#endif
150664 +#define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t)
150665 +
150666 +/**************************************************************************//**
150667 + @Function FM_PCD_KgSetDfltValue
150668 +
150669 + @Description Calling this routine sets a global default value to be used
150670 + by the KeyGen when parser does not recognize a required
150671 + field/header.
150672 + By default default values are 0.
150673 +
150674 + @Param[in] ioc_fm_pcd_kg_dflt_value_params_t A pointer to a structure with the relevant parameters
150675 +
150676 + @Return 0 on success; Error code otherwise.
150677 +
150678 + @Cautions Allowed only when PCD is disabled.
150679 +*//***************************************************************************/
150680 +#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)
150681 +
150682 +/**************************************************************************//**
150683 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
150684 +
150685 + @Description Calling this routine allows the keygen to access data past
150686 + the parser finishing point.
150687 +
150688 + @Param[in] uint8_t payload-offset; the number of bytes beyond the parser location.
150689 +
150690 + @Return 0 on success; Error code otherwise.
150691 +
150692 + @Cautions Allowed only when PCD is disabled.
150693 +*//***************************************************************************/
150694 +#define FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(7), uint8_t)
150695 +
150696 +/**************************************************************************//**
150697 + @Function FM_PCD_SetException
150698 +
150699 + @Description Calling this routine enables/disables PCD interrupts.
150700 +
150701 + @Param[in] ioc_fm_pcd_exception_params_t Arguments struct with exception to be enabled/disabled.
150702 +
150703 + @Return 0 on success; Error code otherwise.
150704 +*//***************************************************************************/
150705 +#define FM_PCD_IOC_SET_EXCEPTION _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(8), ioc_fm_pcd_exception_params_t)
150706 +
150707 +/**************************************************************************//**
150708 + @Function FM_PCD_GetCounter
150709 +
150710 + @Description Reads one of the FM PCD counters.
150711 +
150712 + @Param[in,out] ioc_fm_pcd_counters_params_t The requested counter parameters.
150713 +
150714 + @Return 0 on success; Error code otherwise.
150715 +
150716 + @Cautions Note that it is user's responsibilty to call this routine only
150717 + for enabled counters, and there will be no indication if a
150718 + disabled counter is accessed.
150719 +*//***************************************************************************/
150720 +#define FM_PCD_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(9), ioc_fm_pcd_counters_params_t)
150721 +
150722 +/**************************************************************************//**
150723 +
150724 + @Function FM_PCD_KgSchemeGetCounter
150725 +
150726 + @Description Reads scheme packet counter.
150727 +
150728 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
150729 +
150730 + @Return Counter's current value.
150731 +
150732 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
150733 +*//***************************************************************************/
150734 +#if defined(CONFIG_COMPAT)
150735 +#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)
150736 +#endif
150737 +#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)
150738 +
150739 +#if 0
150740 +TODO: unused IOCTL
150741 +/**************************************************************************//**
150742 + @Function FM_PCD_ModifyCounter
150743 +
150744 + @Description Writes a value to an enabled counter. Use "0" to reset the counter.
150745 +
150746 + @Param[in] ioc_fm_pcd_counters_params_t - The requested counter parameters.
150747 +
150748 + @Return 0 on success; Error code otherwise.
150749 +*//***************************************************************************/
150750 +#define FM_PCD_IOC_MODIFY_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(10), ioc_fm_pcd_counters_params_t)
150751 +#define FM_PCD_IOC_SET_COUNTER FM_PCD_IOC_MODIFY_COUNTER
150752 +#endif
150753 +
150754 +/**************************************************************************//**
150755 + @Function FM_PCD_ForceIntr
150756 +
150757 + @Description Causes an interrupt event on the requested source.
150758 +
150759 + @Param[in] ioc_fm_pcd_exceptions - An exception to be forced.
150760 +
150761 + @Return 0 on success; error code if the exception is not enabled,
150762 + or is not able to create interrupt.
150763 +*//***************************************************************************/
150764 +#define FM_PCD_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(11), ioc_fm_pcd_exceptions)
150765 +
150766 +/**************************************************************************//**
150767 + @Collection Definitions of coarse classification parameters as required by KeyGen
150768 + (when coarse classification is the next engine after this scheme).
150769 +*//***************************************************************************/
150770 +#define IOC_FM_PCD_MAX_NUM_OF_CC_TREES 8
150771 +#define IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS 16
150772 +#define IOC_FM_PCD_MAX_NUM_OF_CC_UNITS 4
150773 +#define IOC_FM_PCD_MAX_NUM_OF_KEYS 256
150774 +#define IOC_FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
150775 +#define IOC_FM_PCD_MAX_SIZE_OF_KEY 56
150776 +#define IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
150777 +#define IOC_FM_PCD_LAST_KEY_INDEX 0xffff
150778 +#define IOC_FM_PCD_MANIP_DSCP_VALUES 64
150779 +/* @} */
150780 +
150781 +/**************************************************************************//**
150782 + @Collection A set of definitions to allow protocol
150783 + special option description.
150784 +*//***************************************************************************/
150785 +typedef uint32_t ioc_protocol_opt_t; /**< A general type to define a protocol option. */
150786 +
150787 +typedef ioc_protocol_opt_t ioc_eth_protocol_opt_t; /**< Ethernet protocol options. */
150788 +#define IOC_ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
150789 +#define IOC_ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
150790 +
150791 +typedef ioc_protocol_opt_t ioc_vlan_protocol_opt_t; /**< Vlan protocol options. */
150792 +#define IOC_VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
150793 +
150794 +typedef ioc_protocol_opt_t ioc_mpls_protocol_opt_t; /**< MPLS protocol options. */
150795 +#define IOC_MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
150796 +
150797 +typedef ioc_protocol_opt_t ioc_ipv4_protocol_opt_t; /**< IPv4 protocol options. */
150798 +#define IOC_IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
150799 +#define IOC_IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
150800 +#define IOC_IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
150801 +#define IOC_IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
150802 +
150803 +#define IOC_IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
150804 + IPV4 Reassembly manipulation requires network
150805 + environment with IPV4 header and IPV4_FRAG_1 option */
150806 +
150807 +typedef ioc_protocol_opt_t ioc_ipv6_protocol_opt_t; /**< IPv6 protocol options. */
150808 +#define IOC_IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
150809 +#define IOC_IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
150810 +#define IOC_IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
150811 +
150812 +#define IOC_IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
150813 + IPV6 Reassembly manipulation requires network
150814 + environment with IPV6 header and IPV6_FRAG_1 option */
150815 +#if (DPAA_VERSION >= 11)
150816 +typedef ioc_protocol_opt_t ioc_capwap_protocol_opt_t; /**< CAPWAP protocol options. */
150817 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
150818 + CAPWAP Reassembly manipulation requires network
150819 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
150820 + in case where fragment found, the fragment-extension offset
150821 + may be found at 'shim2' (in parser-result). */
150822 +#endif /* (DPAA_VERSION >= 11) */
150823 +
150824 +/* @} */
150825 +
150826 +#define IOC_FM_PCD_MANIP_MAX_HDR_SIZE 256
150827 +#define IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
150828 +/**************************************************************************//**
150829 + @Collection A set of definitions to support Header Manipulation selection.
150830 +*//***************************************************************************/
150831 +typedef uint32_t ioc_hdr_manip_flags_t; /**< A general type to define a HMan update command flags. */
150832 +
150833 +typedef ioc_hdr_manip_flags_t ioc_ipv4_hdr_manip_update_flags_t; /**< IPv4 protocol HMan update command flags. */
150834 +
150835 +#define IOC_HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
150836 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150837 +#define IOC_HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
150838 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150839 +#define IOC_HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
150840 +#define IOC_HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
150841 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150842 +#define IOC_HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
150843 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150844 +
150845 +typedef ioc_hdr_manip_flags_t ioc_ipv6_hdr_manip_update_flags_t; /**< IPv6 protocol HMan update command flags. */
150846 +
150847 +#define IOC_HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
150848 + ('traffic_class' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150849 +#define IOC_HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
150850 +#define IOC_HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
150851 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150852 +#define IOC_HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
150853 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150854 +
150855 +typedef ioc_hdr_manip_flags_t ioc_tcp_udp_hdr_manip_update_flags_t;/**< TCP/UDP protocol HMan update command flags. */
150856 +
150857 +#define IOC_HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
150858 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
150859 +#define IOC_HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
150860 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
150861 +#define IOC_HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
150862 +
150863 +/* @} */
150864 +
150865 +/**************************************************************************//**
150866 + @Description A type used for returning the order of the key extraction.
150867 + each value in this array represents the index of the extraction
150868 + command as defined by the user in the initialization extraction array.
150869 + The valid size of this array is the user define number of extractions
150870 + required (also marked by the second '0' in this array).
150871 +*//***************************************************************************/
150872 +typedef uint8_t ioc_fm_pcd_kg_key_order_t [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
150873 +
150874 +/**************************************************************************//**
150875 + @Description All PCD engines
150876 + (must match enum e_FmPcdEngine defined in fm_pcd_ext.h)
150877 +*//***************************************************************************/
150878 +typedef enum ioc_fm_pcd_engine {
150879 + e_IOC_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
150880 + e_IOC_FM_PCD_DONE, /**< No PCD Engine indicated */
150881 + e_IOC_FM_PCD_KG, /**< KeyGen */
150882 + e_IOC_FM_PCD_CC, /**< Coarse Classifier */
150883 + e_IOC_FM_PCD_PLCR, /**< Policer */
150884 + e_IOC_FM_PCD_PRS, /**< Parser */
150885 +#if DPAA_VERSION >= 11
150886 + e_IOC_FM_PCD_FR, /**< Frame Replicator */
150887 +#endif /* DPAA_VERSION >= 11 */
150888 + e_IOC_FM_PCD_HASH /**< Hash Table */
150889 +} ioc_fm_pcd_engine;
150890 +
150891 +/**************************************************************************//**
150892 + @Description An enum for selecting extraction by header types
150893 + (Must match enum e_FmPcdExtractByHdrType defined in fm_pcd_ext.h)
150894 +*//***************************************************************************/
150895 +typedef enum ioc_fm_pcd_extract_by_hdr_type {
150896 + e_IOC_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
150897 + e_IOC_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
150898 + e_IOC_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
150899 +} ioc_fm_pcd_extract_by_hdr_type;
150900 +
150901 +/**************************************************************************//**
150902 + @Description An enum for selecting extraction source (when it is not the header)
150903 + (Must match enum e_FmPcdExtractFrom defined in fm_pcd_ext.h)
150904 +*//***************************************************************************/
150905 +typedef enum ioc_fm_pcd_extract_from {
150906 + e_IOC_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
150907 + e_IOC_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
150908 + e_IOC_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */
150909 + e_IOC_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
150910 + e_IOC_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
150911 + e_IOC_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */
150912 + e_IOC_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
150913 + e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
150914 +} ioc_fm_pcd_extract_from;
150915 +
150916 +/**************************************************************************//**
150917 + @Description An enum for selecting extraction type
150918 +*//***************************************************************************/
150919 +typedef enum ioc_fm_pcd_extract_type {
150920 + e_IOC_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
150921 + e_IOC_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
150922 + e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
150923 +} ioc_fm_pcd_extract_type;
150924 +
150925 +/**************************************************************************//**
150926 + @Description An enum for selecting a default
150927 +*//***************************************************************************/
150928 +typedef enum ioc_fm_pcd_kg_extract_dflt_select {
150929 + e_IOC_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
150930 + e_IOC_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
150931 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
150932 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
150933 + e_IOC_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
150934 +} ioc_fm_pcd_kg_extract_dflt_select;
150935 +
150936 +/**************************************************************************//**
150937 + @Description Enumeration type defining all default groups - each group shares
150938 + a default value, one of four user-initialized values.
150939 +*//***************************************************************************/
150940 +typedef enum ioc_fm_pcd_kg_known_fields_dflt_types {
150941 + e_IOC_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
150942 + e_IOC_FM_PCD_KG_TCI, /**< TCI field */
150943 + e_IOC_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
150944 + e_IOC_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
150945 + e_IOC_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
150946 + e_IOC_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
150947 + e_IOC_FM_PCD_KG_IP_ADDR, /**< IP addr */
150948 + e_IOC_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
150949 + e_IOC_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
150950 + e_IOC_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
150951 + e_IOC_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
150952 + e_IOC_FM_PCD_KG_L4_PORT, /**< L4 Port */
150953 + e_IOC_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
150954 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
150955 + any data extraction that is not the full
150956 + field described above */
150957 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
150958 + any data extraction without validation */
150959 + e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
150960 + extraction from parser result or
150961 + direct use of default value */
150962 +} ioc_fm_pcd_kg_known_fields_dflt_types;
150963 +
150964 +/**************************************************************************//**
150965 + @Description Enumeration type for defining header index for scenarios with
150966 + multiple (tunneled) headers
150967 +*//***************************************************************************/
150968 +typedef enum ioc_fm_pcd_hdr_index {
150969 + e_IOC_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
150970 + to specify regular IP (not tunneled). */
150971 + e_IOC_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
150972 + e_IOC_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
150973 + e_IOC_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
150974 + e_IOC_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
150975 +} ioc_fm_pcd_hdr_index;
150976 +
150977 +/**************************************************************************//**
150978 + @Description Enumeration type for selecting the policer profile functional type
150979 +*//***************************************************************************/
150980 +typedef enum ioc_fm_pcd_profile_type_selection {
150981 + e_IOC_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
150982 + e_IOC_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
150983 +} ioc_fm_pcd_profile_type_selection;
150984 +
150985 +/**************************************************************************//**
150986 + @Description Enumeration type for selecting the policer profile algorithm
150987 +*//***************************************************************************/
150988 +typedef enum ioc_fm_pcd_plcr_algorithm_selection {
150989 + e_IOC_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
150990 + e_IOC_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
150991 + e_IOC_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
150992 +} ioc_fm_pcd_plcr_algorithm_selection;
150993 +
150994 +/**************************************************************************//**
150995 + @Description Enumeration type for selecting a policer profile color mode
150996 +*//***************************************************************************/
150997 +typedef enum ioc_fm_pcd_plcr_color_mode {
150998 + e_IOC_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
150999 + e_IOC_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
151000 +} ioc_fm_pcd_plcr_color_mode;
151001 +
151002 +/**************************************************************************//**
151003 + @Description Enumeration type for selecting a policer profile color
151004 +*//***************************************************************************/
151005 +typedef enum ioc_fm_pcd_plcr_color {
151006 + e_IOC_FM_PCD_PLCR_GREEN, /**< Green */
151007 + e_IOC_FM_PCD_PLCR_YELLOW, /**< Yellow */
151008 + e_IOC_FM_PCD_PLCR_RED, /**< Red */
151009 + e_IOC_FM_PCD_PLCR_OVERRIDE /**< Color override */
151010 +} ioc_fm_pcd_plcr_color;
151011 +
151012 +/**************************************************************************//**
151013 + @Description Enumeration type for selecting the policer profile packet frame length selector
151014 +*//***************************************************************************/
151015 +typedef enum ioc_fm_pcd_plcr_frame_length_select {
151016 + e_IOC_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
151017 + e_IOC_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
151018 + e_IOC_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
151019 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
151020 +} ioc_fm_pcd_plcr_frame_length_select;
151021 +
151022 +/**************************************************************************//**
151023 + @Description Enumeration type for selecting roll-back frame
151024 +*//***************************************************************************/
151025 +typedef enum ioc_fm_pcd_plcr_roll_back_frame_select {
151026 + e_IOC_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */
151027 + e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */
151028 +} ioc_fm_pcd_plcr_roll_back_frame_select;
151029 +
151030 +/**************************************************************************//**
151031 + @Description Enumeration type for selecting the policer profile packet or byte mode
151032 +*//***************************************************************************/
151033 +typedef enum ioc_fm_pcd_plcr_rate_mode {
151034 + e_IOC_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
151035 + e_IOC_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
151036 +} ioc_fm_pcd_plcr_rate_mode;
151037 +
151038 +/**************************************************************************//**
151039 + @Description Enumeration type for defining action of frame
151040 +*//***************************************************************************/
151041 +typedef enum ioc_fm_pcd_done_action {
151042 + e_IOC_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
151043 + e_IOC_FM_PCD_DROP_FRAME /**< Drop frame */
151044 +} ioc_fm_pcd_done_action;
151045 +
151046 +/**************************************************************************//**
151047 + @Description Enumeration type for selecting the policer counter
151048 +*//***************************************************************************/
151049 +typedef enum ioc_fm_pcd_plcr_profile_counters {
151050 + e_IOC_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
151051 + e_IOC_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
151052 + e_IOC_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
151053 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
151054 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
151055 +} ioc_fm_pcd_plcr_profile_counters;
151056 +
151057 +/**************************************************************************//**
151058 + @Description Enumeration type for selecting the PCD action after extraction
151059 +*//***************************************************************************/
151060 +typedef enum ioc_fm_pcd_action {
151061 + e_IOC_FM_PCD_ACTION_NONE, /**< NONE */
151062 + e_IOC_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/
151063 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/
151064 +} ioc_fm_pcd_action;
151065 +
151066 +/**************************************************************************//**
151067 + @Description Enumeration type for selecting type of insert manipulation
151068 +*//***************************************************************************/
151069 +typedef enum ioc_fm_pcd_manip_hdr_insrt_type {
151070 + e_IOC_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
151071 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
151072 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
151073 + e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
151074 +#endif /* FM_CAPWAP_SUPPORT */
151075 +} ioc_fm_pcd_manip_hdr_insrt_type;
151076 +
151077 +/**************************************************************************//**
151078 + @Description Enumeration type for selecting type of remove manipulation
151079 +*//***************************************************************************/
151080 +typedef enum ioc_fm_pcd_manip_hdr_rmv_type {
151081 + e_IOC_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
151082 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
151083 +} ioc_fm_pcd_manip_hdr_rmv_type;
151084 +
151085 +/**************************************************************************//**
151086 + @Description An enum for selecting specific L2 fields removal
151087 +*//***************************************************************************/
151088 +typedef enum ioc_fm_pcd_manip_hdr_rmv_specific_l2 {
151089 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
151090 + e_IOC_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
151091 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
151092 + the header which follows the MPLS header */
151093 + e_IOC_FM_PCD_MANIP_HDR_RMV_MPLS /**< Remove MPLS header (Unlimited MPLS labels) */
151094 +} ioc_fm_pcd_manip_hdr_rmv_specific_l2;
151095 +
151096 +/**************************************************************************//**
151097 + @Description Enumeration type for selecting specific fields updates
151098 +*//***************************************************************************/
151099 +typedef enum ioc_fm_pcd_manip_hdr_field_update_type {
151100 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
151101 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
151102 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
151103 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
151104 +} ioc_fm_pcd_manip_hdr_field_update_type;
151105 +
151106 +/**************************************************************************//**
151107 + @Description Enumeration type for selecting VLAN updates
151108 +*//***************************************************************************/
151109 +typedef enum ioc_fm_pcd_manip_hdr_field_update_vlan {
151110 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
151111 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
151112 +} ioc_fm_pcd_manip_hdr_field_update_vlan;
151113 +
151114 +/**************************************************************************//**
151115 + @Description Enumeration type for selecting specific L2 fields removal
151116 +*//***************************************************************************/
151117 +typedef enum ioc_fm_pcd_manip_hdr_insrt_specific_l2 {
151118 + e_IOC_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */
151119 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2;
151120 +
151121 +#if (DPAA_VERSION >= 11)
151122 +/**************************************************************************//**
151123 + @Description Enumeration type for selecting QoS mapping mode
151124 +
151125 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
151126 + User should instruct the port to read the parser-result
151127 +*//***************************************************************************/
151128 +typedef enum ioc_fm_pcd_manip_hdr_qos_mapping_mode {
151129 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
151130 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the parser-result. */
151131 +} ioc_fm_pcd_manip_hdr_qos_mapping_mode;
151132 +
151133 +/**************************************************************************//**
151134 + @Description Enumeration type for selecting QoS source
151135 +
151136 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
151137 + User should left room for the parser-result on input/output buffer
151138 + and instruct the port to read/write the parser-result to the buffer (RPD should be set)
151139 +*//***************************************************************************/
151140 +typedef enum ioc_fm_pcd_manip_hdr_qos_src {
151141 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
151142 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the parser-result. */
151143 +} ioc_fm_pcd_manip_hdr_qos_src;
151144 +#endif /* (DPAA_VERSION >= 11) */
151145 +
151146 +/**************************************************************************//**
151147 + @Description Enumeration type for selecting type of header insertion
151148 +*//***************************************************************************/
151149 +typedef enum ioc_fm_pcd_manip_hdr_insrt_by_hdr_type {
151150 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
151151 +#if (DPAA_VERSION >= 11)
151152 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
151153 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
151154 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
151155 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
151156 +#endif /* (DPAA_VERSION >= 11) */
151157 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_type;
151158 +
151159 +/**************************************************************************//**
151160 + @Description Enumeration type for selecting specific custom command
151161 +*//***************************************************************************/
151162 +typedef enum ioc_fm_pcd_manip_hdr_custom_type {
151163 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
151164 +} ioc_fm_pcd_manip_hdr_custom_type;
151165 +
151166 +/**************************************************************************//**
151167 + @Description Enumeration type for selecting specific custom command
151168 +*//***************************************************************************/
151169 +typedef enum ioc_fm_pcd_manip_hdr_custom_ip_replace {
151170 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
151171 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
151172 +} ioc_fm_pcd_manip_hdr_custom_ip_replace;
151173 +
151174 +/**************************************************************************//**
151175 + @Description Enumeration type for selecting type of header removal
151176 +*//***************************************************************************/
151177 +typedef enum ioc_fm_pcd_manip_hdr_rmv_by_hdr_type {
151178 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
151179 +#if (DPAA_VERSION >= 11)
151180 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
151181 +#endif /* (DPAA_VERSION >= 11) */
151182 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
151183 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
151184 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
151185 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_type;
151186 +
151187 +/**************************************************************************//**
151188 + @Description Enumeration type for selecting type of timeout mode
151189 +*//***************************************************************************/
151190 +typedef enum ioc_fm_pcd_manip_reassem_time_out_mode {
151191 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
151192 + from the first fragment to the last */
151193 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
151194 +} ioc_fm_pcd_manip_reassem_time_out_mode;
151195 +
151196 +/**************************************************************************//**
151197 + @Description Enumeration type for selecting type of WaysNumber mode
151198 +*//***************************************************************************/
151199 +typedef enum ioc_fm_pcd_manip_reassem_ways_number {
151200 + e_IOC_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
151201 + e_IOC_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
151202 + e_IOC_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
151203 + e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
151204 + e_IOC_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
151205 + e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
151206 + e_IOC_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
151207 + e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
151208 +} ioc_fm_pcd_manip_reassem_ways_number;
151209 +
151210 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
151211 +/**************************************************************************//**
151212 + @Description Enumeration type for selecting type of statistics mode
151213 +*//***************************************************************************/
151214 +typedef enum ioc_fm_pcd_stats {
151215 + e_IOC_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
151216 +} ioc_fm_pcd_stats;
151217 +#endif
151218 +
151219 +/**************************************************************************//**
151220 + @Description Enumeration type for selecting manipulation type
151221 +*//***************************************************************************/
151222 +typedef enum ioc_fm_pcd_manip_type {
151223 + e_IOC_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
151224 + e_IOC_FM_PCD_MANIP_REASSEM, /**< Reassembly */
151225 + e_IOC_FM_PCD_MANIP_FRAG, /**< Fragmentation */
151226 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
151227 +} ioc_fm_pcd_manip_type;
151228 +
151229 +/**************************************************************************//**
151230 + @Description Enumeration type for selecting type of statistics mode
151231 +*//***************************************************************************/
151232 +typedef enum ioc_fm_pcd_cc_stats_mode {
151233 + e_IOC_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
151234 + e_IOC_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
151235 + e_IOC_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
151236 +#if (DPAA_VERSION >= 11)
151237 + e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */
151238 +#endif /* (DPAA_VERSION >= 11) */
151239 +} ioc_fm_pcd_cc_stats_mode;
151240 +
151241 +/**************************************************************************//**
151242 + @Description Enumeration type for determining the action in case an IP packet
151243 + is larger than MTU but its DF (Don't Fragment) bit is set.
151244 +*//***************************************************************************/
151245 +typedef enum ioc_fm_pcd_manip_dont_frag_action {
151246 + e_IOC_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
151247 + e_IOC_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_IOC_FM_PCD_MANIP_DISCARD_PACKET,
151248 + /**< Obsolete, cannot enqueue to error queue;
151249 + In practice, selects to discard packets;
151250 + Will be removed in the future */
151251 + e_IOC_FM_PCD_MANIP_FRAGMENT_PACKECT, /**< Fragment packet and continue normal processing */
151252 + e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
151253 +} ioc_fm_pcd_manip_dont_frag_action;
151254 +
151255 +/**************************************************************************//**
151256 + @Description Enumeration type for selecting type of special offload manipulation
151257 +*//***************************************************************************/
151258 +typedef enum ioc_fm_pcd_manip_special_offload_type {
151259 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
151260 +#if (DPAA_VERSION >= 11)
151261 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
151262 +#endif /* (DPAA_VERSION >= 11) */
151263 +} ioc_fm_pcd_manip_special_offload_type;
151264 +
151265 +/**************************************************************************//**
151266 + @Description A union of protocol dependent special options
151267 + (Must match union u_FmPcdHdrProtocolOpt defined in fm_pcd_ext.h)
151268 +*//***************************************************************************/
151269 +typedef union ioc_fm_pcd_hdr_protocol_opt_u {
151270 + ioc_eth_protocol_opt_t eth_opt; /**< Ethernet options */
151271 + ioc_vlan_protocol_opt_t vlan_opt; /**< Vlan options */
151272 + ioc_mpls_protocol_opt_t mpls_opt; /**< MPLS options */
151273 + ioc_ipv4_protocol_opt_t ipv4_opt; /**< IPv4 options */
151274 + ioc_ipv6_protocol_opt_t ipv6_opt; /**< IPv6 options */
151275 +#if (DPAA_VERSION >= 11)
151276 + ioc_capwap_protocol_opt_t capwap_opt; /**< CAPWAP options */
151277 +#endif /* (DPAA_VERSION >= 11) */
151278 +} ioc_fm_pcd_hdr_protocol_opt_u;
151279 +
151280 +/**************************************************************************//**
151281 + @Description A union holding all known protocol fields
151282 +*//***************************************************************************/
151283 +typedef union ioc_fm_pcd_fields_u {
151284 + ioc_header_field_eth_t eth; /**< Ethernet */
151285 + ioc_header_field_vlan_t vlan; /**< VLAN */
151286 + ioc_header_field_llc_snap_t llc_snap; /**< LLC SNAP */
151287 + ioc_header_field_pppoe_t pppoe; /**< PPPoE */
151288 + ioc_header_field_mpls_t mpls; /**< MPLS */
151289 + ioc_header_field_ip_t ip; /**< IP */
151290 + ioc_header_field_ipv4_t ipv4; /**< IPv4 */
151291 + ioc_header_field_ipv6_t ipv6; /**< IPv6 */
151292 + ioc_header_field_udp_t udp; /**< UDP */
151293 + ioc_header_field_udp_lite_t udp_lite; /**< UDP_Lite */
151294 + ioc_header_field_tcp_t tcp; /**< TCP */
151295 + ioc_header_field_sctp_t sctp; /**< SCTP */
151296 + ioc_header_field_dccp_t dccp; /**< DCCP */
151297 + ioc_header_field_gre_t gre; /**< GRE */
151298 + ioc_header_field_minencap_t minencap; /**< Minimal Encapsulation */
151299 + ioc_header_field_ipsec_ah_t ipsec_ah; /**< IPSec AH */
151300 + ioc_header_field_ipsec_esp_t ipsec_esp; /**< IPSec ESP */
151301 + ioc_header_field_udp_encap_esp_t udp_encap_esp; /**< UDP Encapsulation ESP */
151302 +} ioc_fm_pcd_fields_u;
151303 +
151304 +/**************************************************************************//**
151305 + @Description Parameters for defining header extraction for key generation
151306 +*//***************************************************************************/
151307 +typedef struct ioc_fm_pcd_from_hdr_t {
151308 + uint8_t size; /**< Size in byte */
151309 + uint8_t offset; /**< Byte offset */
151310 +} ioc_fm_pcd_from_hdr_t;
151311 +
151312 +/**************************************************************************//**
151313 + @Description Parameters for defining field extraction for key generation
151314 +*//***************************************************************************/
151315 +typedef struct ioc_fm_pcd_from_field_t {
151316 + ioc_fm_pcd_fields_u field; /**< Field selection */
151317 + uint8_t size; /**< Size in byte */
151318 + uint8_t offset; /**< Byte offset */
151319 +} ioc_fm_pcd_from_field_t;
151320 +
151321 +/**************************************************************************//**
151322 + @Description Parameters for defining a single network environment unit
151323 + A distinction unit should be defined if it will later be used
151324 + by one or more PCD engines to distinguish between flows.
151325 + (Must match struct t_FmPcdDistinctionUnit defined in fm_pcd_ext.h)
151326 +*//***************************************************************************/
151327 +typedef struct ioc_fm_pcd_distinction_unit_t {
151328 + struct {
151329 + ioc_net_header_type hdr; /**< One of the headers supported by the FM */
151330 + ioc_fm_pcd_hdr_protocol_opt_u opt; /**< Select only one option! */
151331 + } hdrs[IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
151332 +} ioc_fm_pcd_distinction_unit_t;
151333 +
151334 +/**************************************************************************//**
151335 + @Description Parameters for defining all different distinction units supported
151336 + by a specific PCD Network Environment Characteristics module.
151337 +
151338 + Each unit represent a protocol or a group of protocols that may
151339 + be used later by the different PCD engines to distinguish between flows.
151340 + (Must match struct t_FmPcdNetEnvParams defined in fm_pcd_ext.h)
151341 +*//***************************************************************************/
151342 +typedef struct ioc_fm_pcd_net_env_params_t {
151343 + uint8_t num_of_distinction_units;/**< Number of different units to be identified */
151344 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
151345 + /**< An array of num_of_distinction_units of the
151346 + different units to be identified */
151347 + void *id; /**< Output parameter; Returns the net-env Id to be used */
151348 +} ioc_fm_pcd_net_env_params_t;
151349 +
151350 +/**************************************************************************//**
151351 + @Description Parameters for defining a single extraction action when
151352 + creating a key
151353 +*//***************************************************************************/
151354 +typedef struct ioc_fm_pcd_extract_entry_t {
151355 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
151356 + union {
151357 + struct {
151358 + ioc_net_header_type hdr; /**< Header selection */
151359 + bool ignore_protocol_validation;
151360 + /**< Ignore protocol validation */
151361 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
151362 + IP. Otherwise should be cleared.*/
151363 + ioc_fm_pcd_extract_by_hdr_type type; /**< Header extraction type select */
151364 + union {
151365 + ioc_fm_pcd_from_hdr_t from_hdr; /**< Extract bytes from header parameters */
151366 + ioc_fm_pcd_from_field_t from_field; /**< Extract bytes from field parameters */
151367 + ioc_fm_pcd_fields_u full_field; /**< Extract full field parameters */
151368 + } extract_by_hdr_type;
151369 + } extract_by_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
151370 + struct {
151371 + ioc_fm_pcd_extract_from src; /**< Non-header extraction source */
151372 + ioc_fm_pcd_action action; /**< Relevant for CC Only */
151373 + uint16_t ic_indx_mask; /**< Relevant only for CC when
151374 + action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP;
151375 + Note that the number of bits that are set within
151376 + this mask must be log2 of the CC-node 'num_of_keys'.
151377 + Note that the mask cannot be set on the lower bits. */
151378 + uint8_t offset; /**< Byte offset */
151379 + uint8_t size; /**< Size in bytes */
151380 + } extract_non_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
151381 + } extract_params;
151382 +} ioc_fm_pcd_extract_entry_t;
151383 +
151384 +/**************************************************************************//**
151385 + @Description A structure for defining masks for each extracted
151386 + field in the key.
151387 +*//***************************************************************************/
151388 +typedef struct ioc_fm_pcd_kg_extract_mask_t {
151389 + uint8_t extract_array_index; /**< Index in the extraction array, as initialized by user */
151390 + uint8_t offset; /**< Byte offset */
151391 + uint8_t mask; /**< A byte mask (selected bits will be ignored) */
151392 +} ioc_fm_pcd_kg_extract_mask_t;
151393 +
151394 +/**************************************************************************//**
151395 + @Description A structure for defining default selection per groups
151396 + of fields
151397 +*//***************************************************************************/
151398 +typedef struct ioc_fm_pcd_kg_extract_dflt_t {
151399 + ioc_fm_pcd_kg_known_fields_dflt_types type; /**< Default type select*/
151400 + ioc_fm_pcd_kg_extract_dflt_select dflt_select; /**< Default register select */
151401 +} ioc_fm_pcd_kg_extract_dflt_t;
151402 +
151403 +
151404 +/**************************************************************************//**
151405 + @Description A structure for defining all parameters needed for
151406 + generation a key and using a hash function
151407 +*//***************************************************************************/
151408 +typedef struct ioc_fm_pcd_kg_key_extract_and_hash_params_t {
151409 + uint32_t private_dflt0; /**< Scheme default register 0 */
151410 + uint32_t private_dflt1; /**< Scheme default register 1 */
151411 + uint8_t num_of_used_extracts; /**< defines the valid size of the following array */
151412 + ioc_fm_pcd_extract_entry_t extract_array [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
151413 + /**< An array of extraction definitions. */
151414 + uint8_t num_of_used_dflts; /**< defines the valid size of the following array */
151415 + ioc_fm_pcd_kg_extract_dflt_t dflts[IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
151416 + /**< For each extraction used in this scheme, specify the required
151417 + default register to be used when header is not found.
151418 + types not specified in this array will get undefined value. */
151419 + uint8_t num_of_used_masks; /**< Defines the valid size of the following array */
151420 + ioc_fm_pcd_kg_extract_mask_t masks[IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
151421 + uint8_t hash_shift; /**< Hash result right shift.
151422 + Selects the 24 bits out of the 64 hash result.
151423 + 0 means using the 24 LSB's, otherwise use the
151424 + 24 LSB's after shifting right.*/
151425 + uint32_t hash_distribution_num_of_fqids; /**< must be > 1 and a power of 2. Represents the range
151426 + of queues for the key and hash functionality */
151427 + uint8_t hash_distribution_fqids_shift; /**< selects the FQID bits that will be effected by the hash */
151428 + bool symmetric_hash; /**< TRUE to generate the same hash for frames with swapped source and
151429 + destination fields on all layers; If TRUE, driver will check that for
151430 + all layers, if SRC extraction is selected, DST extraction must also be
151431 + selected, and vice versa. */
151432 +} ioc_fm_pcd_kg_key_extract_and_hash_params_t;
151433 +
151434 +/**************************************************************************//**
151435 + @Description A structure of parameters for defining a single
151436 + Qid mask (extracted OR).
151437 +*//***************************************************************************/
151438 +typedef struct ioc_fm_pcd_kg_extracted_or_params_t {
151439 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
151440 + union {
151441 + struct { /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
151442 + ioc_net_header_type hdr;
151443 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
151444 + IP. Otherwise should be cleared.*/
151445 + bool ignore_protocol_validation;
151446 +
151447 + } extract_by_hdr;
151448 + ioc_fm_pcd_extract_from src; /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
151449 + } extract_params;
151450 + uint8_t extraction_offset; /**< Offset for extraction */
151451 + ioc_fm_pcd_kg_extract_dflt_select dflt_value; /**< Select register from which extraction is taken if
151452 + field not found */
151453 + uint8_t mask; /**< Mask LSB byte of extraction (specified bits are ignored) */
151454 + uint8_t bit_offset_in_fqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
151455 + the extracted byte; Assume byte is placed as the 8 MSB's in
151456 + a 32 bit word where the lower bits
151457 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
151458 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
151459 + extracted byte will effect the 8 LSB's of the FQID,
151460 + if bitOffsetInFqid=31 than the byte's MSB will effect
151461 + the FQID's LSB; 0 means - no effect on FQID;
151462 + Note that one, and only one of
151463 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
151464 + extracted byte must effect either FQID or Policer profile).*/
151465 + uint8_t bit_offset_in_plcr_profile;
151466 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
151467 + effect using the extracted byte; Assume byte is placed
151468 + as the 8 MSB's in a 16 bit word where the lower bits
151469 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
151470 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
151471 + than the extracted byte will effect the whole policer profile id,
151472 + if bitOffsetInFqid=15 than the byte's MSB will effect
151473 + the Policer Profile id's LSB;
151474 + 0 means - no effect on policer profile; Note that one, and only one of
151475 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
151476 + extracted byte must effect either FQID or Policer profile).*/
151477 +} ioc_fm_pcd_kg_extracted_or_params_t;
151478 +
151479 +/**************************************************************************//**
151480 + @Description A structure for configuring scheme counter
151481 +*//***************************************************************************/
151482 +typedef struct ioc_fm_pcd_kg_scheme_counter_t {
151483 + bool update; /**< FALSE to keep the current counter state
151484 + and continue from that point, TRUE to update/reset
151485 + the counter when the scheme is written. */
151486 + uint32_t value; /**< If update=TRUE, this value will be written into the
151487 + counter; clear this field to reset the counter. */
151488 +} ioc_fm_pcd_kg_scheme_counter_t;
151489 +
151490 +
151491 +/**************************************************************************//**
151492 + @Description A structure for retrieving FMKG_SE_SPC
151493 +*//***************************************************************************/
151494 +typedef struct ioc_fm_pcd_kg_scheme_spc_t {
151495 + uint32_t val; /**< return value */
151496 + void *id; /**< scheme handle */
151497 +} ioc_fm_pcd_kg_scheme_spc_t;
151498 +
151499 +/**************************************************************************//**
151500 + @Description A structure for defining policer profile parameters as required by keygen
151501 + (when policer is the next engine after this scheme).
151502 + (Must match struct t_FmPcdKgPlcrProfile defined in fm_pcd_ext.h)
151503 +*//***************************************************************************/
151504 +typedef struct ioc_fm_pcd_kg_plcr_profile_t {
151505 + bool shared_profile; /**< TRUE if this profile is shared between ports
151506 + (i.e. managed by master partition) May not be TRUE
151507 + if profile is after Coarse Classification*/
151508 + bool direct; /**< If TRUE, direct_relative_profile_id only selects the profile
151509 + id, if FALSE fqid_offset_relative_profile_id_base is used
151510 + together with fqid_offset_shift and num_of_profiles
151511 + parameters, to define a range of profiles from
151512 + which the KeyGen result will determine the
151513 + destination policer profile. */
151514 + union {
151515 + uint16_t direct_relative_profile_id; /**< Used if 'direct' is TRUE, to select policer profile.
151516 + This parameter should indicate the policer profile offset within the port's
151517 + policer profiles or SHARED window. */
151518 + struct {
151519 + uint8_t fqid_offset_shift; /**< Shift of KG results without the qid base */
151520 + uint8_t fqid_offset_relative_profile_id_base;
151521 + /**< OR of KG results without the qid base
151522 + This parameter should indicate the policer profile
151523 + offset within the port's policer profiles window
151524 + or SHARED window depends on shared_profile */
151525 + uint8_t num_of_profiles; /**< Range of profiles starting at base */
151526 + } indirect_profile; /**< Indirect profile parameters */
151527 + } profile_select; /**< Direct/indirect profile selection and parameters */
151528 +} ioc_fm_pcd_kg_plcr_profile_t;
151529 +
151530 +#if DPAA_VERSION >= 11
151531 +/**************************************************************************//**
151532 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
151533 +*//***************************************************************************/
151534 +typedef struct ioc_fm_pcd_kg_storage_profile_t {
151535 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
151536 + profile id;
151537 + If FALSE, fqidOffsetRelativeProfileIdBase is used
151538 + together with fqidOffsetShift and numOfProfiles
151539 + parameters to define a range of profiles from which
151540 + the KeyGen result will determine the destination
151541 + storage profile. */
151542 + union {
151543 + uint16_t direct_relative_profileId; /**< Used when 'direct' is TRUE, to select a storage profile;
151544 + should indicate the storage profile offset within the
151545 + port's storage profiles window. */
151546 + struct {
151547 + uint8_t fqid_offset_shift; /**< Shift of KeyGen results without the FQID base */
151548 + uint8_t fqid_offset_relative_profile_id_base;
151549 + /**< OR of KeyGen results without the FQID base;
151550 + should indicate the policer profile offset within the
151551 + port's storage profiles window. */
151552 + uint8_t num_of_profiles; /**< Range of profiles starting at base. */
151553 + } indirect_profile; /**< Indirect profile parameters. */
151554 + } profile_select; /**< Direct/indirect profile selection and parameters. */
151555 +} ioc_fm_pcd_kg_storage_profile_t;
151556 +#endif /* DPAA_VERSION >= 11 */
151557 +
151558 +/**************************************************************************//**
151559 + @Description Parameters for defining CC as the next engine after KeyGen
151560 + (Must match struct t_FmPcdKgCc defined in fm_pcd_ext.h)
151561 +*//***************************************************************************/
151562 +typedef struct ioc_fm_pcd_kg_cc_t {
151563 + void *tree_id; /**< CC Tree id */
151564 + uint8_t grp_id; /**< CC group id within the CC tree */
151565 + bool plcr_next; /**< TRUE if after CC, in case of data frame,
151566 + policing is required. */
151567 + bool bypass_plcr_profile_generation;
151568 + /**< TRUE to bypass KeyGen policer profile generation;
151569 + selected profile is the one set at port initialization. */
151570 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Valid only if plcr_next = TRUE and
151571 + bypass_plcr_profile_generation = FALSE */
151572 +} ioc_fm_pcd_kg_cc_t;
151573 +
151574 +/**************************************************************************//**
151575 + @Description Parameters for defining initializing a KeyGen scheme
151576 + (Must match struct t_FmPcdKgSchemeParams defined in fm_pcd_ext.h)
151577 +*//***************************************************************************/
151578 +typedef struct ioc_fm_pcd_kg_scheme_params_t {
151579 + bool modify; /**< TRUE to change an existing scheme */
151580 + union {
151581 + uint8_t relative_scheme_id;
151582 + /**< if modify=FALSE: partition-relative scheme id */
151583 + void *scheme_id; /**< if modify=TRUE: the id of an existing scheme */
151584 + } scm_id;
151585 + bool always_direct; /**< This scheme is reached only directly, i.e. no need
151586 + for match vector; KeyGen will ignore it when matching */
151587 + struct { /**< HL relevant only if always_direct=FALSE */
151588 + void *net_env_id; /**< The id of the Network Environment as returned
151589 + by FM_PCD_NetEnvCharacteristicsSet() */
151590 + uint8_t num_of_distinction_units;
151591 + /**< Number of NetEnv units listed in unit_ids array */
151592 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
151593 + /**< Indexes as passed to SetNetEnvCharacteristics (?) array */
151594 + } net_env_params;
151595 + bool use_hash; /**< use the KG Hash functionality */
151596 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
151597 + /**< used only if useHash = TRUE */
151598 + bool bypass_fqid_generation;
151599 + /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
151600 + In such a case FQID after KG will be the default FQID
151601 + defined for the relevant port, or the FQID defined by CC
151602 + in cases where CC was the previous engine. */
151603 + uint32_t base_fqid; /**< Base FQID; Relevant only if bypass_fqid_generation = FALSE;
151604 + If hash is used and an even distribution is expected
151605 + according to hash_distribution_num_of_fqids, base_fqid must be aligned to
151606 + hash_distribution_num_of_fqids. */
151607 + uint8_t num_of_used_extracted_ors;
151608 + /**< Number of FQID masks listed in extracted_ors array*/
151609 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
151610 + /**< IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS
151611 + registers are shared between qid_masks
151612 + functionality and some of the extraction
151613 + actions; Normally only some will be used
151614 + for qid_mask. Driver will return error if
151615 + resource is full at initialization time. */
151616 +#if DPAA_VERSION >= 11
151617 + bool override_storage_profile;
151618 + /**< TRUE if KeyGen override previously decided storage profile */
151619 + ioc_fm_pcd_kg_storage_profile_t storage_profile;/**< Used when override_storage_profile=TRUE */
151620 +#endif /* DPAA_VERSION >= 11 */
151621 + ioc_fm_pcd_engine next_engine; /**< may be BMI, PLCR or CC */
151622 + union { /**< depends on nextEngine */
151623 + ioc_fm_pcd_done_action done_action; /**< Used when next engine is BMI (done) */
151624 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Used when next engine is PLCR */
151625 + ioc_fm_pcd_kg_cc_t cc; /**< Used when next engine is CC */
151626 + } kg_next_engine_params;
151627 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter; /**< A structure of parameters for updating
151628 + the scheme counter */
151629 + void *id; /**< Returns the scheme Id to be used */
151630 +} ioc_fm_pcd_kg_scheme_params_t;
151631 +
151632 +/**************************************************************************//**
151633 + @Collection
151634 +*//***************************************************************************/
151635 +#if DPAA_VERSION >= 11
151636 +#define IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
151637 +#define IOC_FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
151638 +#endif /* DPAA_VERSION >= 11 */
151639 +#define IOC_FM_PCD_CC_STATS_FLR_COUNT_SIZE 4 /* Size in bytes of a frame length range counter */
151640 +/* @} */
151641 +
151642 +/**************************************************************************//**
151643 + @Description Parameters for defining CC as the next engine after a CC node.
151644 + (Must match struct t_FmPcdCcNextCcParams defined in fm_pcd_ext.h)
151645 +*//***************************************************************************/
151646 +typedef struct ioc_fm_pcd_cc_next_cc_params_t {
151647 + void *cc_node_id; /**< Id of the next CC node */
151648 +} ioc_fm_pcd_cc_next_cc_params_t;
151649 +
151650 +#if DPAA_VERSION >= 11
151651 +/**************************************************************************//**
151652 + @Description A structure for defining Frame Replicator as the next engine after a CC node.
151653 + (Must match struct t_FmPcdCcNextFrParams defined in fm_pcd_ext.h)
151654 +*//***************************************************************************/
151655 +typedef struct ioc_fm_pcd_cc_next_fr_params_t {
151656 + void* frm_replic_id; /**< The id of the next frame replicator group */
151657 +} ioc_fm_pcd_cc_next_fr_params_t;
151658 +#endif /* DPAA_VERSION >= 11 */
151659 +
151660 +/**************************************************************************//**
151661 + @Description A structure for defining PLCR params when PLCR is the
151662 + next engine after a CC node
151663 + (Must match struct t_FmPcdCcNextPlcrParams defined in fm_pcd_ext.h)
151664 +*//***************************************************************************/
151665 +typedef struct ioc_fm_pcd_cc_next_plcr_params_t {
151666 + bool override_params; /**< TRUE if CC override previously decided parameters*/
151667 + bool shared_profile; /**< Relevant only if overrideParams=TRUE:
151668 + TRUE if this profile is shared between ports */
151669 + uint16_t new_relative_profile_id; /**< Relevant only if overrideParams=TRUE:
151670 + (otherwise profile id is taken from keygen);
151671 + This parameter should indicate the policer
151672 + profile offset within the port's
151673 + policer profiles or from SHARED window.*/
151674 + uint32_t new_fqid; /**< Relevant only if overrideParams=TRUE:
151675 + FQID for enquing the frame;
151676 + In earlier chips if policer next engine is KEYGEN,
151677 + this parameter can be 0, because the KEYGEN always decides
151678 + the enqueue FQID.*/
151679 +#if DPAA_VERSION >= 11
151680 + uint8_t new_relative_storage_profile_id;
151681 + /**< Indicates the relative storage profile offset within
151682 + the port's storage profiles window;
151683 + Relevant only if the port was configured with VSP. */
151684 +#endif /* DPAA_VERSION >= 11 */
151685 +} ioc_fm_pcd_cc_next_plcr_params_t;
151686 +
151687 +/**************************************************************************//**
151688 + @Description A structure for defining enqueue params when BMI is the
151689 + next engine after a CC node
151690 + (Must match struct t_FmPcdCcNextEnqueueParams defined in fm_pcd_ext.h)
151691 +*//***************************************************************************/
151692 +typedef struct ioc_fm_pcd_cc_next_enqueue_params_t {
151693 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
151694 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
151695 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME */
151696 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
151697 + (otherwise FQID is taken from KeyGen),
151698 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME*/
151699 +#if DPAA_VERSION >= 11
151700 + uint8_t new_relative_storage_profile_id;
151701 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
151702 + storage profile offset within the port's storage profiles
151703 + window; Relevant only if the port was configured with VSP. */
151704 +#endif /* DPAA_VERSION >= 11 */
151705 +
151706 +} ioc_fm_pcd_cc_next_enqueue_params_t;
151707 +
151708 +/**************************************************************************//**
151709 + @Description A structure for defining KG params when KG is the next engine after a CC node
151710 + (Must match struct t_FmPcdCcNextKgParams defined in fm_pcd_ext.h)
151711 +*//***************************************************************************/
151712 +typedef struct ioc_fm_pcd_cc_next_kg_params_t {
151713 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
151714 + Note - this parameters are irrelevant for earlier chips */
151715 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
151716 + (otherwise FQID is taken from KeyGen),
151717 + Note - this parameters are irrelevant for earlier chips */
151718 +#if DPAA_VERSION >= 11
151719 + uint8_t new_relative_storage_profile_id;
151720 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
151721 + storage profile offset within the port's storage profiles
151722 + window; Relevant only if the port was configured with VSP. */
151723 +#endif /* DPAA_VERSION >= 11 */
151724 + void *p_direct_scheme; /**< Direct scheme id to go to. */
151725 +} ioc_fm_pcd_cc_next_kg_params_t;
151726 +
151727 +/**************************************************************************//**
151728 + @Description Parameters for defining the next engine after a CC node.
151729 + (Must match struct t_FmPcdCcNextEngineParams defined in fm_pcd_ext.h)
151730 +*//***************************************************************************/
151731 +typedef struct ioc_fm_pcd_cc_next_engine_params_t {
151732 + ioc_fm_pcd_engine next_engine; /**< User has to initialize parameters
151733 + according to nextEngine definition */
151734 + union {
151735 + ioc_fm_pcd_cc_next_cc_params_t cc_params; /**< Parameters in case next engine is CC */
151736 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< Parameters in case next engine is PLCR */
151737 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< Parameters in case next engine is BMI */
151738 + ioc_fm_pcd_cc_next_kg_params_t kg_params; /**< Parameters in case next engine is KG */
151739 +#if DPAA_VERSION >= 11
151740 + ioc_fm_pcd_cc_next_fr_params_t fr_params; /**< Parameters in case next engine is FR */
151741 +#endif /* DPAA_VERSION >= 11 */
151742 + } params; /**< Union used for all the next-engine parameters options */
151743 + void *manip_id; /**< Handle to Manipulation object.
151744 + Relevant if next engine is of type result
151745 + (e_IOC_FM_PCD_PLCR, e_IOC_FM_PCD_KG, e_IOC_FM_PCD_DONE) */
151746 + bool statistics_en; /**< If TRUE, statistics counters are incremented
151747 + for each frame passing through this
151748 + Coarse Classification entry. */
151749 +} ioc_fm_pcd_cc_next_engine_params_t;
151750 +
151751 +/**************************************************************************//**
151752 + @Description Parameters for defining a single CC key
151753 +*//***************************************************************************/
151754 +typedef struct ioc_fm_pcd_cc_key_params_t {
151755 + uint8_t *p_key; /**< pointer to the key of the size defined in key_size */
151756 + uint8_t *p_mask; /**< pointer to the Mask per key of the size defined
151757 + in keySize. p_key and p_mask (if defined) has to be
151758 + of the same size defined in the key_size */
151759 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151760 + /**< parameters for the next for the defined Key in p_key */
151761 +
151762 +} ioc_fm_pcd_cc_key_params_t;
151763 +
151764 +/**************************************************************************//**
151765 + @Description Parameters for defining CC keys parameters
151766 + The driver supports two methods for CC node allocation: dynamic and static.
151767 + Static mode was created in order to prevent runtime alloc/free
151768 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
151769 + the driver automatically allocates the memory according to
151770 + 'max_num_of_keys' parameter. The driver calculates the maximal memory
151771 + size that may be used for this CC-Node taking into consideration
151772 + 'mask_support' and 'statistics_mode' parameters.
151773 + When 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
151774 + parameters of this node, 'max_num_of_keys' must be equal to 'num_of_keys'.
151775 + In dynamic mode, 'max_num_of_keys' must be zero. At initialization,
151776 + all required structures are allocated according to 'num_of_keys'
151777 + parameter. During runtime modification, these structures are
151778 + re-allocated according to the updated number of keys.
151779 +
151780 + Please note that 'action' and 'ic_indx_mask' mentioned in the
151781 + specific parameter explanations are passed in the extraction
151782 + parameters of the node (fields of extractccparams.extractnonhdr).
151783 +*//***************************************************************************/
151784 +typedef struct ioc_keys_params_t {
151785 + uint16_t max_num_of_keys;/**< Maximum number of keys that will (ever) be used in this CC-Node;
151786 + A value of zero may be used for dynamic memory allocation. */
151787 + bool mask_support; /**< This parameter is relevant only if a node is initialized with
151788 + action = e_IOC_FM_PCD_ACTION_EXACT_MATCH and max_num_of_keys > 0;
151789 + Should be TRUE to reserve table memory for key masks, even if
151790 + initial keys do not contain masks, or if the node was initialized
151791 + as 'empty' (without keys); this will allow user to add keys with
151792 + masks at runtime. */
151793 + ioc_fm_pcd_cc_stats_mode statistics_mode;/**< Determines the supported statistics mode for all node's keys.
151794 + To enable statistics gathering, statistics should be enabled per
151795 + every key, using 'statistics_en' in next engine parameters structure
151796 + of that key;
151797 + If 'max_num_of_keys' is set, all required structures will be
151798 + preallocated for all keys. */
151799 +#if (DPAA_VERSION >= 11)
151800 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
151801 + /**< Relevant only for 'RMON' statistics mode
151802 + (this feature is supported only on B4860 device);
151803 + Holds a list of programmable thresholds. For each received frame,
151804 + its length in bytes is examined against these range thresholds and
151805 + the appropriate counter is incremented by 1. For example, to belong
151806 + to range i, the following should hold:
151807 + range i-1 threshold < frame length <= range i threshold
151808 + Each range threshold must be larger then its preceding range
151809 + threshold. Last range threshold must be 0xFFFF. */
151810 +#endif /* (DPAA_VERSION >= 11) */
151811 + uint16_t num_of_keys; /**< Number of initial keys;
151812 + Note that in case of 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP,
151813 + this field should be power-of-2 of the number of bits that are
151814 + set in 'ic_indx_mask'. */
151815 + uint8_t key_size; /**< Size of key - for extraction of type FULL_FIELD, 'key_size' has
151816 + to be the standard size of the selected key; For other extraction
151817 + types, 'key_size' has to be as size of extraction; When 'action' =
151818 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
151819 + ioc_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS];
151820 + /**< An array with 'num_of_keys' entries, each entry specifies the
151821 + corresponding key parameters;
151822 + When 'action' = e_IOC_FM_PCD_ACTION_EXACT_MATCH, this value must not
151823 + exceed 255 (IOC_FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
151824 + for the 'miss' entry. */
151825 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
151826 + /**< Parameters for defining the next engine when a key is not matched;
151827 + Not relevant if action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP. */
151828 +} ioc_keys_params_t;
151829 +
151830 +/**************************************************************************//**
151831 + @Description Parameters for defining a CC node
151832 +*//***************************************************************************/
151833 +typedef struct ioc_fm_pcd_cc_node_params_t {
151834 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< Extraction parameters */
151835 + ioc_keys_params_t keys_params; /**< Keys definition matching the selected extraction */
151836 + void *id; /**< Output parameter; returns the CC node Id to be used */
151837 +} ioc_fm_pcd_cc_node_params_t;
151838 +
151839 +/**************************************************************************//**
151840 + @Description Parameters for defining a hash table
151841 + (Must match struct t_FmPcdHashTableParams defined in fm_pcd_ext.h)
151842 +*//***************************************************************************/
151843 +typedef struct ioc_fm_pcd_hash_table_params_t {
151844 + uint16_t max_num_of_keys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
151845 + ioc_fm_pcd_cc_stats_mode statistics_mode; /**< If not e_IOC_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
151846 + requested statistics mode will be allocated according to max_num_of_keys. */
151847 + uint8_t kg_hash_shift; /**< KG-Hash-shift as it was configured in the KG-scheme
151848 + that leads to this hash-table. */
151849 + uint16_t hash_res_mask; /**< Mask that will be used on the hash-result;
151850 + The number-of-sets for this hash will be calculated
151851 + as (2^(number of bits set in 'hash_res_mask'));
151852 + The 4 lower bits must be cleared. */
151853 + uint8_t hash_shift; /**< Byte offset from the beginning of the KeyGen hash result to the
151854 + 2-bytes to be used as hash index. */
151855 + uint8_t match_key_size; /**< Size of the exact match keys held by the hash buckets */
151856 +
151857 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
151858 + /**< Parameters for defining the next engine when a key is not matched */
151859 + void *id;
151860 +} ioc_fm_pcd_hash_table_params_t;
151861 +
151862 +/**************************************************************************//**
151863 + @Description A structure with the arguments for the FM_PCD_HashTableAddKey ioctl() call
151864 +*//***************************************************************************/
151865 +typedef struct ioc_fm_pcd_hash_table_add_key_params_t {
151866 + void *p_hash_tbl;
151867 + uint8_t key_size;
151868 + ioc_fm_pcd_cc_key_params_t key_params;
151869 +} ioc_fm_pcd_hash_table_add_key_params_t;
151870 +
151871 +/**************************************************************************//**
151872 + @Description Parameters for defining a CC tree group.
151873 +
151874 + This structure defines a CC group in terms of NetEnv units
151875 + and the action to be taken in each case. The unit_ids list must
151876 + be given in order from low to high indices.
151877 +
151878 + ioc_fm_pcd_cc_next_engine_params_t is a list of 2^num_of_distinction_units
151879 + structures where each defines the next action to be taken for
151880 + each units combination. for example:
151881 + num_of_distinction_units = 2
151882 + unit_ids = {1,3}
151883 + next_engine_per_entries_in_grp[0] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151884 + unit 1 - not found; unit 3 - not found;
151885 + next_engine_per_entries_in_grp[1] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151886 + unit 1 - not found; unit 3 - found;
151887 + next_engine_per_entries_in_grp[2] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151888 + unit 1 - found; unit 3 - not found;
151889 + next_engine_per_entries_in_grp[3] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151890 + unit 1 - found; unit 3 - found;
151891 +*//***************************************************************************/
151892 +typedef struct ioc_fm_pcd_cc_grp_params_t {
151893 + uint8_t num_of_distinction_units; /**< Up to 4 */
151894 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
151895 + /**< Indexes of the units as defined in
151896 + FM_PCD_NetEnvCharacteristicsSet() */
151897 + ioc_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
151898 + /**< Maximum entries per group is 16 */
151899 +} ioc_fm_pcd_cc_grp_params_t;
151900 +
151901 +/**************************************************************************//**
151902 + @Description Parameters for defining the CC tree groups
151903 + (Must match struct t_FmPcdCcTreeParams defined in fm_pcd_ext.h)
151904 +*//***************************************************************************/
151905 +typedef struct ioc_fm_pcd_cc_tree_params_t {
151906 + void *net_env_id; /**< Id of the Network Environment as returned
151907 + by FM_PCD_NetEnvCharacteristicsSet() */
151908 + uint8_t num_of_groups; /**< Number of CC groups within the CC tree */
151909 + ioc_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
151910 + /**< Parameters for each group. */
151911 + void *id; /**< Output parameter; Returns the tree Id to be used */
151912 +} ioc_fm_pcd_cc_tree_params_t;
151913 +
151914 +/**************************************************************************//**
151915 + @Description Parameters for defining policer byte rate
151916 +*//***************************************************************************/
151917 +typedef struct ioc_fm_pcd_plcr_byte_rate_mode_param_t {
151918 + ioc_fm_pcd_plcr_frame_length_select frame_length_selection; /**< Frame length selection */
151919 + ioc_fm_pcd_plcr_roll_back_frame_select roll_back_frame_selection; /**< relevant option only e_IOC_FM_PCD_PLCR_L2_FRM_LEN,
151920 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN */
151921 +} ioc_fm_pcd_plcr_byte_rate_mode_param_t;
151922 +
151923 +/**************************************************************************//**
151924 + @Description Parameters for defining the policer profile (based on
151925 + RFC-2698 or RFC-4115 attributes).
151926 +*//***************************************************************************/
151927 +typedef struct ioc_fm_pcd_plcr_non_passthrough_alg_param_t {
151928 + ioc_fm_pcd_plcr_rate_mode rate_mode; /**< Byte / Packet */
151929 + ioc_fm_pcd_plcr_byte_rate_mode_param_t byte_mode_param; /**< Valid for Byte NULL for Packet */
151930 + uint32_t committed_info_rate; /**< KBits/Sec or Packets/Sec */
151931 + uint32_t committed_burst_size; /**< KBits or Packets */
151932 + uint32_t peak_or_excess_info_rate; /**< KBits/Sec or Packets/Sec */
151933 + uint32_t peak_or_excess_burst_size; /**< KBits or Packets */
151934 +} ioc_fm_pcd_plcr_non_passthrough_alg_param_t;
151935 +
151936 +/**************************************************************************//**
151937 + @Description Parameters for defining the next engine after policer
151938 +*//***************************************************************************/
151939 +typedef union ioc_fm_pcd_plcr_next_engine_params_u {
151940 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
151941 + void *p_profile; /**< Policer profile handle - used when next engine
151942 + is PLCR, must be a SHARED profile */
151943 + void *p_direct_scheme; /**< Direct scheme select - when next engine is Keygen */
151944 +} ioc_fm_pcd_plcr_next_engine_params_u;
151945 +
151946 +typedef struct ioc_fm_pcd_port_params_t {
151947 + ioc_fm_port_type port_type; /**< Type of port for this profile */
151948 + uint8_t port_id; /**< FM-Port id of port for this profile */
151949 +} ioc_fm_pcd_port_params_t;
151950 +
151951 +/**************************************************************************//**
151952 + @Description Parameters for defining the policer profile entry
151953 + (Must match struct t_FmPcdPlcrProfileParams defined in fm_pcd_ext.h)
151954 +*//***************************************************************************/
151955 +typedef struct ioc_fm_pcd_plcr_profile_params_t {
151956 + bool modify; /**< TRUE to change an existing profile */
151957 + union {
151958 + struct {
151959 + ioc_fm_pcd_profile_type_selection profile_type; /**< Type of policer profile */
151960 + ioc_fm_pcd_port_params_t *p_fm_port; /**< Relevant for per-port profiles only */
151961 + uint16_t relative_profile_id; /**< Profile id - relative to shared group or to port */
151962 + } new_params; /**< Use it when modify = FALSE */
151963 + void *p_profile; /**< A handle to a profile - use it when modify=TRUE */
151964 + } profile_select;
151965 + ioc_fm_pcd_plcr_algorithm_selection alg_selection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
151966 + ioc_fm_pcd_plcr_color_mode color_mode; /**< COLOR_BLIND, COLOR_AWARE */
151967 +
151968 + union {
151969 + ioc_fm_pcd_plcr_color dflt_color; /**< For Color-Blind Pass-Through mode; the policer will re-color
151970 + any incoming packet with the default value. */
151971 + ioc_fm_pcd_plcr_color override; /**< For Color-Aware modes; the profile response to a
151972 + pre-color value of 2'b11. */
151973 + } color;
151974 +
151975 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; /**< RFC2698 or RFC4115 parameters */
151976 +
151977 + ioc_fm_pcd_engine next_engine_on_green; /**< Next engine for green-colored frames */
151978 + ioc_fm_pcd_plcr_next_engine_params_u params_on_green; /**< Next engine parameters for green-colored frames */
151979 +
151980 + ioc_fm_pcd_engine next_engine_on_yellow; /**< Next engine for yellow-colored frames */
151981 + ioc_fm_pcd_plcr_next_engine_params_u params_on_yellow; /**< Next engine parameters for yellow-colored frames */
151982 +
151983 + ioc_fm_pcd_engine next_engine_on_red; /**< Next engine for red-colored frames */
151984 + ioc_fm_pcd_plcr_next_engine_params_u params_on_red; /**< Next engine parameters for red-colored frames */
151985 +
151986 + bool trap_profile_on_flow_A; /**< Obsolete - do not use */
151987 + bool trap_profile_on_flow_B; /**< Obsolete - do not use */
151988 + bool trap_profile_on_flow_C; /**< Obsolete - do not use */
151989 +
151990 + void *id; /**< output parameter; Returns the profile Id to be used */
151991 +} ioc_fm_pcd_plcr_profile_params_t;
151992 +
151993 +/**************************************************************************//**
151994 + @Description A structure for modifying CC tree next engine
151995 +*//***************************************************************************/
151996 +typedef struct ioc_fm_pcd_cc_tree_modify_next_engine_params_t {
151997 + void *id; /**< CC tree Id to be used */
151998 + uint8_t grp_indx; /**< A Group index in the tree */
151999 + uint8_t indx; /**< Entry index in the group defined by grp_index */
152000 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
152001 + /**< Parameters for the next for the defined Key in the p_Key */
152002 +} ioc_fm_pcd_cc_tree_modify_next_engine_params_t;
152003 +
152004 +/**************************************************************************//**
152005 + @Description A structure for modifying CC node next engine
152006 +*//***************************************************************************/
152007 +typedef struct ioc_fm_pcd_cc_node_modify_next_engine_params_t {
152008 + void *id; /**< CC node Id to be used */
152009 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
152010 + NOTE: This parameter is IGNORED for miss-key! */
152011 + uint8_t key_size; /**< Key size of added key */
152012 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
152013 + /**< parameters for the next for the defined Key in the p_Key */
152014 +} ioc_fm_pcd_cc_node_modify_next_engine_params_t;
152015 +
152016 +/**************************************************************************//**
152017 + @Description A structure for remove CC node key
152018 +*//***************************************************************************/
152019 +typedef struct ioc_fm_pcd_cc_node_remove_key_params_t {
152020 + void *id; /**< CC node Id to be used */
152021 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
152022 + NOTE: This parameter is IGNORED for miss-key! */
152023 +} ioc_fm_pcd_cc_node_remove_key_params_t;
152024 +
152025 +/**************************************************************************//**
152026 + @Description A structure for modifying CC node key and next engine
152027 +*//***************************************************************************/
152028 +typedef struct ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
152029 + void *id; /**< CC node Id to be used */
152030 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
152031 + NOTE: This parameter is IGNORED for miss-key! */
152032 + uint8_t key_size; /**< Key size of added key */
152033 + ioc_fm_pcd_cc_key_params_t key_params; /**< it's array with numOfKeys entries each entry in
152034 + the array of the type ioc_fm_pcd_cc_key_params_t */
152035 +} ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
152036 +
152037 +/**************************************************************************//**
152038 + @Description A structure for modifying CC node key
152039 +*//***************************************************************************/
152040 +typedef struct ioc_fm_pcd_cc_node_modify_key_params_t {
152041 + void *id; /**< CC node Id to be used */
152042 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
152043 + NOTE: This parameter is IGNORED for miss-key! */
152044 + uint8_t key_size; /**< Key size of added key */
152045 + uint8_t *p_key; /**< Pointer to the key of the size defined in key_size */
152046 + uint8_t *p_mask; /**< Pointer to the Mask per key of the size defined
152047 + in keySize. p_Key and p_Mask (if defined) have to be
152048 + of the same size as defined in the key_size */
152049 +} ioc_fm_pcd_cc_node_modify_key_params_t;
152050 +
152051 +/**************************************************************************//**
152052 + @Description A structure with the arguments for the FM_PCD_HashTableRemoveKey ioctl() call
152053 +*//***************************************************************************/
152054 +typedef struct ioc_fm_pcd_hash_table_remove_key_params_t {
152055 + void *p_hash_tbl; /**< The id of the hash table */
152056 + uint8_t key_size; /**< The size of the key to remove */
152057 + uint8_t *p_key; /**< Pointer to the key to remove */
152058 +} ioc_fm_pcd_hash_table_remove_key_params_t;
152059 +
152060 +/**************************************************************************//**
152061 + @Description Parameters for selecting a location for requested manipulation
152062 +*//***************************************************************************/
152063 +typedef struct ioc_fm_manip_hdr_info_t {
152064 + ioc_net_header_type hdr; /**< Header selection */
152065 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
152066 + bool by_field; /**< TRUE if the location of manipulation is according to some field in the specific header*/
152067 + ioc_fm_pcd_fields_u full_field; /**< Relevant only when by_field = TRUE: Extract field */
152068 +} ioc_fm_manip_hdr_info_t;
152069 +
152070 +/**************************************************************************//**
152071 + @Description Parameters for defining header removal by header type
152072 +*//***************************************************************************/
152073 +typedef struct ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t {
152074 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_type type; /**< Selection of header removal location */
152075 + union {
152076 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
152077 + struct {
152078 + bool include;/**< If FALSE, remove until the specified header (not including the header);
152079 + If TRUE, remove also the specified header. */
152080 + ioc_fm_manip_hdr_info_t hdr_info;
152081 + } from_start_by_hdr; /**< Relevant when type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
152082 +#endif /* FM_CAPWAP_SUPPORT */
152083 +#if (DPAA_VERSION >= 11)
152084 + ioc_fm_manip_hdr_info_t hdr_info; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
152085 +#endif /* (DPAA_VERSION >= 11) */
152086 + ioc_fm_pcd_manip_hdr_rmv_specific_l2 specific_l2;/**< Relevant when type = e_IOC_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
152087 + Defines which L2 headers to remove. */
152088 + } u;
152089 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t;
152090 +
152091 +/**************************************************************************//**
152092 + @Description Parameters for configuring IP fragmentation manipulation
152093 +*//***************************************************************************/
152094 +typedef struct ioc_fm_pcd_manip_frag_ip_params_t {
152095 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
152096 + IP fragmentation will be executed.*/
152097 +#if DPAA_VERSION == 10
152098 + uint8_t scratch_bpid; /**< Absolute buffer pool id according to BM configuration.*/
152099 +#endif /* DPAA_VERSION == 10 */
152100 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
152101 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
152102 + received frame's buffer. */
152103 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
152104 + This parameter is relevant when 'sg_bpid_en=TRUE';
152105 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
152106 + of this pool need to be allocated in the same memory area as the received buffers.
152107 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
152108 + mutual to all these sources. */
152109 + ioc_fm_pcd_manip_dont_frag_action dont_frag_action; /**< Dont Fragment Action - If an IP packet is larger
152110 + than MTU and its DF bit is set, then this field will
152111 + determine the action to be taken.*/
152112 +} ioc_fm_pcd_manip_frag_ip_params_t;
152113 +
152114 +/**************************************************************************//**
152115 + @Description Parameters for configuring IP reassembly manipulation.
152116 +
152117 + This is a common structure for both IPv4 and IPv6 reassembly
152118 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
152119 + set the 'hdr' field in ioc_fm_pcd_manip_reassem_params_t to IOC_HEADER_TYPE_IPv6.
152120 +*//***************************************************************************/
152121 +typedef struct ioc_fm_pcd_manip_reassem_ip_params_t {
152122 + uint8_t relative_scheme_id[2]; /**< Partition relative scheme id:
152123 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
152124 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
152125 + NOTE: The following comment is relevant only for FMAN v2 devices:
152126 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
152127 + the user schemes id to ensure that the reassembly's schemes will be first match.
152128 + The remaining schemes, if defined, should have higher relative scheme ID. */
152129 +#if DPAA_VERSION >= 11
152130 + uint32_t non_consistent_sp_fqid; /**< In case that other fragments of the frame corresponds to different storage
152131 + profile than the opening fragment (Non-Consistent-SP state)
152132 + then one of two possible scenarios occurs:
152133 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
152134 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
152135 +#else
152136 + uint8_t sg_bpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
152137 +#endif /* DPAA_VERSION >= 11 */
152138 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
152139 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
152140 + uint16_t min_frag_size[2]; /**< Minimum fragment size:
152141 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
152142 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry[2];
152143 + /**< Number of frames per hash entry needed for reassembly process:
152144 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH);
152145 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH). */
152146 + uint16_t max_num_frames_in_process;/**< Number of frames which can be processed by Reassembly in the same time;
152147 + Must be power of 2;
152148 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH,
152149 + maxNumFramesInProcess has to be in the range of 4 - 512;
152150 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH,
152151 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
152152 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
152153 + uint32_t fqid_for_time_out_frames;/**< FQID in which time out frames will enqueue during Time Out Process */
152154 + uint32_t timeout_threshold_for_reassm_process;
152155 + /**< Represents the time interval in microseconds which defines
152156 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
152157 +} ioc_fm_pcd_manip_reassem_ip_params_t;
152158 +
152159 +/**************************************************************************//**
152160 + @Description Parameters for defining IPSEC manipulation
152161 +*//***************************************************************************/
152162 +typedef struct ioc_fm_pcd_manip_special_offload_ipsec_params_t {
152163 + bool decryption; /**< TRUE if being used in decryption direction;
152164 + FALSE if being used in encryption direction. */
152165 + bool ecn_copy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
152166 + (direction depends on the 'decryption' field). */
152167 + bool dscp_copy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
152168 + (direction depends on the 'decryption' field). */
152169 + bool variable_ip_hdr_len; /**< TRUE for supporting variable IP header length in decryption. */
152170 + bool variable_ip_version; /**< TRUE for supporting both IP version on the same SA in encryption */
152171 + uint8_t outer_ip_hdr_len; /**< If 'variable_ip_version == TRUE' than this field must be set to non-zero value;
152172 + It is specifies the length of the outer IP header that was configured in the
152173 + corresponding SA. */
152174 + uint16_t arw_size; /**< if <> '0' then will perform ARW check for this SA;
152175 + The value must be a multiplication of 16 */
152176 + void *arw_addr; /**< if arwSize <> '0' then this field must be set to non-zero value;
152177 + MUST be allocated from FMAN's MURAM that the post-sec op-port belong
152178 + Must be 4B aligned. Required MURAM size is '(NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
152179 +} ioc_fm_pcd_manip_special_offload_ipsec_params_t;
152180 +
152181 +#if (DPAA_VERSION >= 11)
152182 +/**************************************************************************//**
152183 + @Description Parameters for configuring CAPWAP fragmentation manipulation
152184 +
152185 + Restrictions:
152186 + - Maximum number of fragments per frame is 16.
152187 + - Transmit confirmation is not supported.
152188 + - Fragmentation nodes must be set as the last PCD action (i.e. the
152189 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
152190 + - Only BMan buffers shall be used for frames to be fragmented.
152191 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
152192 + does not support VSP. Therefore, on the same port where we have IPF we
152193 + cannot support VSP.
152194 +*//***************************************************************************/
152195 +typedef struct ioc_fm_pcd_manip_frag_capwap_params_t {
152196 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
152197 + CAPWAP fragmentation will be executed.*/
152198 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
152199 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
152200 + received frame's buffer. */
152201 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
152202 + This parameters is relevant when 'sgBpidEn=TRUE';
152203 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
152204 + of this pool need to be allocated in the same memory area as the received buffers.
152205 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
152206 + mutual to all these sources. */
152207 + bool compress_mode_en; /**< CAPWAP Header Options Compress Enable mode;
152208 + When this mode is enabled then only the first fragment include the CAPWAP header options
152209 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
152210 + options field (CAPWAP header is updated accordingly).*/
152211 +} ioc_fm_pcd_manip_frag_capwap_params_t;
152212 +
152213 +/**************************************************************************//**
152214 + @Description Parameters for configuring CAPWAP reassembly manipulation.
152215 +
152216 + Restrictions:
152217 + - Application must define one scheme to catch the reassembled frames.
152218 + - Maximum number of fragments per frame is 16.
152219 +
152220 +*//***************************************************************************/
152221 +typedef struct ioc_fm_pcd_manip_reassem_capwap_params_t {
152222 + uint8_t relative_scheme_id; /**< Partition relative scheme id;
152223 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
152224 + Rest schemes, if defined, should have higher relative scheme ID. */
152225 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
152226 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
152227 + uint16_t max_reassembled_frame_length;/**< The maximum CAPWAP reassembled frame length in bytes;
152228 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
152229 + considered as a valid length;
152230 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
152231 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
152232 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry;
152233 + /**< Number of frames per hash entry needed for reassembly process */
152234 + uint16_t max_num_frames_in_process; /**< Number of frames which can be processed by reassembly in the same time;
152235 + Must be power of 2;
152236 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
152237 + maxNumFramesInProcess has to be in the range of 4 - 512;
152238 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
152239 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
152240 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
152241 + uint32_t fqid_for_time_out_frames; /**< FQID in which time out frames will enqueue during Time Out Process;
152242 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
152243 + uint32_t timeout_threshold_for_reassm_process;
152244 + /**< Represents the time interval in microseconds which defines
152245 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
152246 +} ioc_fm_pcd_manip_reassem_capwap_params_t;
152247 +
152248 +/**************************************************************************//**
152249 + @Description structure for defining CAPWAP manipulation
152250 +*//***************************************************************************/
152251 +typedef struct ioc_fm_pcd_manip_special_offload_capwap_params_t {
152252 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
152253 + ioc_fm_pcd_manip_hdr_qos_src qos_src; /**< TODO */
152254 +} ioc_fm_pcd_manip_special_offload_capwap_params_t;
152255 +
152256 +#endif /* (DPAA_VERSION >= 11) */
152257 +
152258 +/**************************************************************************//**
152259 + @Description Parameters for defining special offload manipulation
152260 +*//***************************************************************************/
152261 +typedef struct ioc_fm_pcd_manip_special_offload_params_t {
152262 + ioc_fm_pcd_manip_special_offload_type type; /**< Type of special offload manipulation */
152263 + union
152264 + {
152265 + ioc_fm_pcd_manip_special_offload_ipsec_params_t ipsec; /**< Parameters for IPSec; Relevant when
152266 + type = e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
152267 +
152268 +#if (DPAA_VERSION >= 11)
152269 + ioc_fm_pcd_manip_special_offload_capwap_params_t capwap; /**< Parameters for CAPWAP; Relevant when
152270 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
152271 +#endif /* (DPAA_VERSION >= 11) */
152272 + } u;
152273 +} ioc_fm_pcd_manip_special_offload_params_t;
152274 +
152275 +/**************************************************************************//**
152276 + @Description Parameters for defining generic removal manipulation
152277 +*//***************************************************************************/
152278 +typedef struct ioc_fm_pcd_manip_hdr_rmv_generic_params_t {
152279 + uint8_t offset; /**< Offset from beginning of header to the start
152280 + location of the removal */
152281 + uint8_t size; /**< Size of removed section */
152282 +} ioc_fm_pcd_manip_hdr_rmv_generic_params_t;
152283 +
152284 +/**************************************************************************//**
152285 + @Description Parameters for defining insertion manipulation
152286 +*//***************************************************************************/
152287 +typedef struct ioc_fm_pcd_manip_hdr_insrt_t {
152288 + uint8_t size; /**< size of inserted section */
152289 + uint8_t *p_data; /**< data to be inserted */
152290 +} ioc_fm_pcd_manip_hdr_insrt_t;
152291 +
152292 +/**************************************************************************//**
152293 + @Description Parameters for defining generic insertion manipulation
152294 +*//***************************************************************************/
152295 +typedef struct ioc_fm_pcd_manip_hdr_insrt_generic_params_t {
152296 + uint8_t offset; /**< Offset from beginning of header to the start
152297 + location of the insertion */
152298 + uint8_t size; /**< Size of inserted section */
152299 + bool replace; /**< TRUE to override (replace) existing data at
152300 + 'offset', FALSE to insert */
152301 + uint8_t *p_data; /**< Pointer to data to be inserted */
152302 +} ioc_fm_pcd_manip_hdr_insrt_generic_params_t;
152303 +
152304 +/**************************************************************************//**
152305 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
152306 +*//***************************************************************************/
152307 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t {
152308 + uint8_t dscp_to_vpri_table[IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
152309 + /**< A table of VPri values for each DSCP value;
152310 + The index is the D_SCP value (0-0x3F) and the
152311 + value is the corresponding VPRI (0-15). */
152312 + uint8_t vpri_def_val; /**< 0-7, Relevant only if if update_type =
152313 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
152314 + this field is the Q Tag default value if the
152315 + IP header is not found. */
152316 +} ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t;
152317 +
152318 +/**************************************************************************//**
152319 + @Description Parameters for defining header manipulation VLAN fields updates
152320 +*//***************************************************************************/
152321 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_t {
152322 + ioc_fm_pcd_manip_hdr_field_update_vlan update_type; /**< Selects VLAN update type */
152323 + union {
152324 + uint8_t vpri; /**< 0-7, Relevant only if If update_type =
152325 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
152326 + is the new VLAN pri. */
152327 + ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t dscp_to_vpri;
152328 + /**< Parameters structure, Relevant only if update_type =
152329 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
152330 + } u;
152331 +} ioc_fm_pcd_manip_hdr_field_update_vlan_t;
152332 +
152333 +/**************************************************************************//**
152334 + @Description Parameters for defining header manipulation IPV4 fields updates
152335 +*//***************************************************************************/
152336 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv4_t {
152337 + ioc_ipv4_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
152338 + uint8_t tos; /**< 8 bit New TOS; Relevant if valid_updates contains
152339 + IOC_HDR_MANIP_IPV4_TOS */
152340 + uint16_t id; /**< 16 bit New IP ID; Relevant only if valid_updates
152341 + contains IOC_HDR_MANIP_IPV4_ID */
152342 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if valid_updates
152343 + contains IOC_HDR_MANIP_IPV4_SRC */
152344 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if valid_updates
152345 + contains IOC_HDR_MANIP_IPV4_DST */
152346 +} ioc_fm_pcd_manip_hdr_field_update_ipv4_t;
152347 +
152348 +/**************************************************************************//**
152349 + @Description Parameters for defining header manipulation IPV6 fields updates
152350 +*//***************************************************************************/
152351 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv6_t {
152352 + ioc_ipv6_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
152353 + uint8_t traffic_class; /**< 8 bit New Traffic Class; Relevant if valid_updates contains
152354 + IOC_HDR_MANIP_IPV6_TC */
152355 + uint8_t src[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
152356 + /**< 16 byte new IP SRC; Relevant only if valid_updates
152357 + contains IOC_HDR_MANIP_IPV6_SRC */
152358 + uint8_t dst[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
152359 + /**< 16 byte new IP DST; Relevant only if valid_updates
152360 + contains IOC_HDR_MANIP_IPV6_DST */
152361 +} ioc_fm_pcd_manip_hdr_field_update_ipv6_t;
152362 +
152363 +/**************************************************************************//**
152364 + @Description Parameters for defining header manipulation TCP/UDP fields updates
152365 +*//***************************************************************************/
152366 +typedef struct ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t {
152367 + ioc_tcp_udp_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
152368 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if valid_updates
152369 + contains IOC_HDR_MANIP_TCP_UDP_SRC */
152370 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if valid_updates
152371 + contains IOC_HDR_MANIP_TCP_UDP_DST */
152372 +} ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t;
152373 +
152374 +/**************************************************************************//**
152375 + @Description Parameters for defining header manipulation fields updates
152376 +*//***************************************************************************/
152377 +typedef struct ioc_fm_pcd_manip_hdr_field_update_params_t {
152378 + ioc_fm_pcd_manip_hdr_field_update_type type; /**< Type of header field update manipulation */
152379 + union {
152380 + ioc_fm_pcd_manip_hdr_field_update_vlan_t vlan; /**< Parameters for VLAN update. Relevant when
152381 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
152382 + ioc_fm_pcd_manip_hdr_field_update_ipv4_t ipv4; /**< Parameters for IPv4 update. Relevant when
152383 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
152384 + ioc_fm_pcd_manip_hdr_field_update_ipv6_t ipv6; /**< Parameters for IPv6 update. Relevant when
152385 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
152386 + ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t tcp_udp;/**< Parameters for TCP/UDP update. Relevant when
152387 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
152388 + } u;
152389 +} ioc_fm_pcd_manip_hdr_field_update_params_t;
152390 +
152391 +/**************************************************************************//**
152392 + @Description Parameters for defining custom header manipulation for IP replacement
152393 +*//***************************************************************************/
152394 +typedef struct ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t {
152395 + ioc_fm_pcd_manip_hdr_custom_ip_replace replace_type; /**< Selects replace update type */
152396 + bool dec_ttl_hl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
152397 + bool update_ipv4_id; /**< Relevant when replace_type =
152398 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
152399 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
152400 + update_ipv4_id = TRUE */
152401 + uint8_t hdr_size; /**< The size of the new IP header */
152402 + uint8_t hdr[IOC_FM_PCD_MANIP_MAX_HDR_SIZE];
152403 + /**< The new IP header */
152404 +} ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t;
152405 +
152406 +/**************************************************************************//**
152407 + @Description Parameters for defining custom header manipulation
152408 +*//***************************************************************************/
152409 +typedef struct ioc_fm_pcd_manip_hdr_custom_params_t {
152410 + ioc_fm_pcd_manip_hdr_custom_type type; /**< Type of header field update manipulation */
152411 + union {
152412 + ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t ip_hdr_replace;
152413 + /**< Parameters IP header replacement */
152414 + } u;
152415 +} ioc_fm_pcd_manip_hdr_custom_params_t;
152416 +
152417 +/**************************************************************************//**
152418 + @Description Parameters for defining specific L2 insertion manipulation
152419 +*//***************************************************************************/
152420 +typedef struct ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
152421 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; /**< Selects which L2 headers to insert */
152422 + bool update; /**< TRUE to update MPLS header */
152423 + uint8_t size; /**< size of inserted section */
152424 + uint8_t *p_data; /**< data to be inserted */
152425 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
152426 +
152427 +#if (DPAA_VERSION >= 11)
152428 +/**************************************************************************//**
152429 + @Description Parameters for defining IP insertion manipulation
152430 +*//***************************************************************************/
152431 +typedef struct ioc_fm_pcd_manip_hdr_insrt_ip_params_t {
152432 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
152433 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
152434 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
152435 + the inserted header */
152436 + uint16_t id; /**< 16 bit New IP ID */
152437 + bool dont_frag_overwrite;
152438 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
152439 + * This byte is configured to be overwritten when RPD is set. */
152440 + uint8_t last_dst_offset;
152441 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
152442 + * in order to calculate UDP checksum pseudo header;
152443 + * Otherwise set it to '0'. */
152444 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
152445 +} ioc_fm_pcd_manip_hdr_insrt_ip_params_t;
152446 +#endif /* (DPAA_VERSION >= 11) */
152447 +
152448 +/**************************************************************************//**
152449 + @Description Parameters for defining header insertion manipulation by header type
152450 +*//***************************************************************************/
152451 +typedef struct ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
152452 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; /**< Selects manipulation type */
152453 + union {
152454 + ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
152455 + /**< Used when type = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
152456 + Selects which L2 headers to remove */
152457 +#if (DPAA_VERSION >= 11)
152458 + ioc_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
152459 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
152460 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
152461 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
152462 +#endif /* (DPAA_VERSION >= 11) */
152463 + } u;
152464 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
152465 +
152466 +/**************************************************************************//**
152467 + @Description Parameters for defining header insertion manipulation
152468 +*//***************************************************************************/
152469 +typedef struct ioc_fm_pcd_manip_hdr_insrt_params_t {
152470 + ioc_fm_pcd_manip_hdr_insrt_type type; /**< Type of insertion manipulation */
152471 + union {
152472 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; /**< Parameters for defining header insertion manipulation by header type,
152473 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR */
152474 + ioc_fm_pcd_manip_hdr_insrt_generic_params_t generic;/**< Parameters for defining generic header insertion manipulation,
152475 + relevant if type = e_IOC_FM_PCD_MANIP_INSRT_GENERIC */
152476 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152477 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
152478 + /**< Parameters for defining header insertion manipulation by template,
152479 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
152480 +#endif /* FM_CAPWAP_SUPPORT */
152481 + } u;
152482 +} ioc_fm_pcd_manip_hdr_insrt_params_t;
152483 +
152484 +/**************************************************************************//**
152485 + @Description Parameters for defining header removal manipulation
152486 +*//***************************************************************************/
152487 +typedef struct ioc_fm_pcd_manip_hdr_rmv_params_t {
152488 + ioc_fm_pcd_manip_hdr_rmv_type type; /**< Type of header removal manipulation */
152489 + union {
152490 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t by_hdr; /**< Parameters for defining header removal manipulation by header type,
152491 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR */
152492 + ioc_fm_pcd_manip_hdr_rmv_generic_params_t generic; /**< Parameters for defining generic header removal manipulation,
152493 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_GENERIC */
152494 + } u;
152495 +} ioc_fm_pcd_manip_hdr_rmv_params_t;
152496 +
152497 +/**************************************************************************//**
152498 + @Description Parameters for defining header manipulation node
152499 +*//***************************************************************************/
152500 +typedef struct ioc_fm_pcd_manip_hdr_params_t {
152501 + bool rmv; /**< TRUE, to define removal manipulation */
152502 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
152503 +
152504 + bool insrt; /**< TRUE, to define insertion manipulation */
152505 + ioc_fm_pcd_manip_hdr_insrt_params_t insrt_params; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
152506 +
152507 + bool field_update; /**< TRUE, to define field update manipulation */
152508 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
152509 +
152510 + bool custom; /**< TRUE, to define custom manipulation */
152511 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
152512 +
152513 + bool dont_parse_after_manip;/**< FALSE to activate the parser a second time after
152514 + completing the manipulation on the frame */
152515 +} ioc_fm_pcd_manip_hdr_params_t;
152516 +
152517 +
152518 +/**************************************************************************//**
152519 + @Description structure for defining fragmentation manipulation
152520 +*//***************************************************************************/
152521 +typedef struct ioc_fm_pcd_manip_frag_params_t {
152522 + ioc_net_header_type hdr; /**< Header selection */
152523 + union {
152524 +#if (DPAA_VERSION >= 11)
152525 + ioc_fm_pcd_manip_frag_capwap_params_t capwap_frag; /**< Parameters for defining CAPWAP fragmentation,
152526 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
152527 +#endif /* (DPAA_VERSION >= 11) */
152528 + ioc_fm_pcd_manip_frag_ip_params_t ip_frag; /**< Parameters for defining IP fragmentation,
152529 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
152530 + } u;
152531 +} ioc_fm_pcd_manip_frag_params_t;
152532 +
152533 +/**************************************************************************//**
152534 + @Description structure for defining reassemble manipulation
152535 +*//***************************************************************************/
152536 +typedef struct ioc_fm_pcd_manip_reassem_params_t {
152537 + ioc_net_header_type hdr; /**< Header selection */
152538 + union {
152539 +#if (DPAA_VERSION >= 11)
152540 + ioc_fm_pcd_manip_reassem_capwap_params_t capwap_reassem; /**< Parameters for defining CAPWAP reassembly,
152541 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
152542 +#endif /* (DPAA_VERSION >= 11) */
152543 + ioc_fm_pcd_manip_reassem_ip_params_t ip_reassem; /**< Parameters for defining IP reassembly,
152544 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
152545 + } u;
152546 +} ioc_fm_pcd_manip_reassem_params_t;
152547 +
152548 +/**************************************************************************//**
152549 + @Description Parameters for defining a manipulation node
152550 +*//***************************************************************************/
152551 +typedef struct ioc_fm_pcd_manip_params_t {
152552 + ioc_fm_pcd_manip_type type; /**< Selects type of manipulation node */
152553 + union {
152554 + ioc_fm_pcd_manip_hdr_params_t hdr; /**< Parameters for defining header manipulation node */
152555 + ioc_fm_pcd_manip_reassem_params_t reassem;/**< Parameters for defining reassembly manipulation node */
152556 + ioc_fm_pcd_manip_frag_params_t frag; /**< Parameters for defining fragmentation manipulation node */
152557 + ioc_fm_pcd_manip_special_offload_params_t special_offload;/**< Parameters for defining special offload manipulation node */
152558 + } u;
152559 + void *p_next_manip;/**< Handle to another (previously defined) manipulation node;
152560 + Allows concatenation of manipulation actions
152561 + This parameter is optional and may be NULL. */
152562 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152563 + bool frag_or_reasm;/**< TRUE, if defined fragmentation/reassembly manipulation */
152564 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;/**< Parameters for fragmentation/reassembly manipulation,
152565 + relevant if frag_or_reasm = TRUE */
152566 +#endif /* FM_CAPWAP_SUPPORT */
152567 + void *id;
152568 +} ioc_fm_pcd_manip_params_t;
152569 +
152570 +/**************************************************************************//**
152571 + @Description Structure for retrieving IP reassembly statistics
152572 +*//***************************************************************************/
152573 +typedef struct ioc_fm_pcd_manip_reassem_ip_stats_t {
152574 + /* common counters for both IPv4 and IPv6 */
152575 + uint32_t timeout; /**< Counts the number of TimeOut occurrences */
152576 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
152577 + a Reassembly Frame Descriptor */
152578 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
152579 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
152580 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
152581 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
152582 +#if (DPAA_VERSION >= 11)
152583 + uint32_t non_consistent_sp; /**< Counts the number of Non Consistent Storage Profile events for
152584 + successfully reassembled frames */
152585 +#endif /* (DPAA_VERSION >= 11) */
152586 +struct {
152587 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
152588 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
152589 + have been processed for all frames */
152590 + uint32_t processed_fragments; /**< Counts the number of processed fragments
152591 + (valid and error fragments) for all frames */
152592 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
152593 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
152594 + uint32_t auto_learn_busy; /**< Counts the number of times a busy condition occurs when attempting
152595 + to access an IP-Reassembly Automatic Learning Hash set */
152596 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
152597 + exceeds 16 */
152598 + } specific_hdr_statistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
152599 +} ioc_fm_pcd_manip_reassem_ip_stats_t;
152600 +
152601 +/**************************************************************************//**
152602 + @Description Structure for retrieving IP fragmentation statistics
152603 +*//***************************************************************************/
152604 +typedef struct ioc_fm_pcd_manip_frag_ip_stats_t {
152605 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
152606 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
152607 + uint32_t generated_fragments; /**< Number of fragments that were generated */
152608 +} ioc_fm_pcd_manip_frag_ip_stats_t;
152609 +
152610 +#if (DPAA_VERSION >= 11)
152611 +/**************************************************************************//**
152612 + @Description Structure for retrieving CAPWAP reassembly statistics
152613 +*//***************************************************************************/
152614 +typedef struct ioc_fm_pcd_manip_reassem_capwap_stats_t {
152615 + uint32_t timeout; /**< Counts the number of timeout occurrences */
152616 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
152617 + a Reassembly Frame Descriptor */
152618 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
152619 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
152620 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
152621 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
152622 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
152623 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
152624 + have been processed for all frames */
152625 + uint32_t processed_fragments; /**< Counts the number of processed fragments
152626 + (valid and error fragments) for all frames */
152627 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
152628 + uint32_t autoLearn_busy; /**< Counts the number of times a busy condition occurs when attempting
152629 + to access an Reassembly Automatic Learning Hash set */
152630 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
152631 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
152632 + exceeds 16 */
152633 + uint32_t exceed_max_reassembly_frame_len;/**< ounts the number of times that a successful reassembled frame
152634 + length exceeds MaxReassembledFrameLength value */
152635 +} ioc_fm_pcd_manip_reassem_capwap_stats_t;
152636 +
152637 +/**************************************************************************//**
152638 + @Description Structure for retrieving CAPWAP fragmentation statistics
152639 +*//***************************************************************************/
152640 +typedef struct ioc_fm_pcd_manip_frag_capwap_stats_t {
152641 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
152642 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
152643 + uint32_t generated_fragments; /**< Number of fragments that were generated */
152644 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
152645 + uint8_t sg_allocation_failure; /**< Number of allocation failure of s/g buffers */
152646 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
152647 +} ioc_fm_pcd_manip_frag_capwap_stats_t;
152648 +#endif /* (DPAA_VERSION >= 11) */
152649 +
152650 +/**************************************************************************//**
152651 + @Description Structure for retrieving reassembly statistics
152652 +*//***************************************************************************/
152653 +typedef struct ioc_fm_pcd_manip_reassem_stats_t {
152654 + union {
152655 + ioc_fm_pcd_manip_reassem_ip_stats_t ip_reassem; /**< Structure for IP reassembly statistics */
152656 +#if (DPAA_VERSION >= 11)
152657 + ioc_fm_pcd_manip_reassem_capwap_stats_t capwap_reassem; /**< Structure for CAPWAP reassembly statistics */
152658 +#endif /* (DPAA_VERSION >= 11) */
152659 + } u;
152660 +} ioc_fm_pcd_manip_reassem_stats_t;
152661 +
152662 +/**************************************************************************//**
152663 + @Description structure for retrieving fragmentation statistics
152664 +*//***************************************************************************/
152665 +typedef struct ioc_fm_pcd_manip_frag_stats_t {
152666 + union {
152667 + ioc_fm_pcd_manip_frag_ip_stats_t ip_frag; /**< Structure for IP fragmentation statistics */
152668 +#if (DPAA_VERSION >= 11)
152669 + ioc_fm_pcd_manip_frag_capwap_stats_t capwap_frag; /**< Structure for CAPWAP fragmentation statistics */
152670 +#endif /* (DPAA_VERSION >= 11) */
152671 + } u;
152672 +} ioc_fm_pcd_manip_frag_stats_t;
152673 +
152674 +/**************************************************************************//**
152675 + @Description structure for defining manipulation statistics
152676 +*//***************************************************************************/
152677 +typedef struct ioc_fm_pcd_manip_stats_t {
152678 + union {
152679 + ioc_fm_pcd_manip_reassem_stats_t reassem; /**< Structure for reassembly statistics */
152680 + ioc_fm_pcd_manip_frag_stats_t frag; /**< Structure for fragmentation statistics */
152681 + } u;
152682 +} ioc_fm_pcd_manip_stats_t;
152683 +
152684 +/**************************************************************************//**
152685 + @Description Parameters for acquiring manipulation statistics
152686 +*//***************************************************************************/
152687 +typedef struct ioc_fm_pcd_manip_get_stats_t {
152688 + void *id;
152689 + ioc_fm_pcd_manip_stats_t stats;
152690 +} ioc_fm_pcd_manip_get_stats_t;
152691 +
152692 +#if DPAA_VERSION >= 11
152693 +/**************************************************************************//**
152694 + @Description Parameters for defining frame replicator group and its members
152695 +*//***************************************************************************/
152696 +typedef struct ioc_fm_pcd_frm_replic_group_params_t {
152697 + uint8_t max_num_of_entries; /**< Maximal number of members in the group - must be at least two */
152698 + uint8_t num_of_entries; /**< Number of members in the group - must be at least 1 */
152699 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
152700 + /**< Array of members' parameters */
152701 + void *id;
152702 +} ioc_fm_pcd_frm_replic_group_params_t;
152703 +
152704 +typedef struct ioc_fm_pcd_frm_replic_member_t {
152705 + void *h_replic_group;
152706 + uint16_t member_index;
152707 +} ioc_fm_pcd_frm_replic_member_t;
152708 +
152709 +typedef struct ioc_fm_pcd_frm_replic_member_params_t {
152710 + ioc_fm_pcd_frm_replic_member_t member;
152711 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params;
152712 +} ioc_fm_pcd_frm_replic_member_params_t;
152713 +#endif /* DPAA_VERSION >= 11 */
152714 +
152715 +
152716 +typedef struct ioc_fm_pcd_cc_key_statistics_t {
152717 + uint32_t byte_count; /**< This counter reflects byte count of frames that
152718 + were matched by this key. */
152719 + uint32_t frame_count; /**< This counter reflects count of frames that
152720 + were matched by this key. */
152721 +#if (DPAA_VERSION >= 11)
152722 + uint32_t frame_length_range_count[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
152723 + /**< These counters reflect how many frames matched
152724 + this key in 'RMON' statistics mode:
152725 + Each counter holds the number of frames of a
152726 + specific frames length range, according to the
152727 + ranges provided at initialization. */
152728 +#endif /* (DPAA_VERSION >= 11) */
152729 +} ioc_fm_pcd_cc_key_statistics_t;
152730 +
152731 +
152732 +typedef struct ioc_fm_pcd_cc_tbl_get_stats_t {
152733 + void *id;
152734 + uint16_t key_index;
152735 + ioc_fm_pcd_cc_key_statistics_t statistics;
152736 +} ioc_fm_pcd_cc_tbl_get_stats_t;
152737 +
152738 +/**************************************************************************//**
152739 + @Function FM_PCD_MatchTableGetKeyStatistics
152740 +
152741 + @Description This routine may be used to get statistics counters of specific key
152742 + in a CC Node.
152743 +
152744 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152745 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152746 + these counters reflect how many frames passed that were matched
152747 + this key; The total frames count will be returned in the counter
152748 + of the first range (as only one frame length range was defined).
152749 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
152750 + frame count will be separated to frame length counters, based on
152751 + provided frame length ranges.
152752 +
152753 + @Param[in] h_CcNode A handle to the node
152754 + @Param[in] keyIndex Key index for adding
152755 + @Param[out] p_KeyStatistics Key statistics counters
152756 +
152757 + @Return The specific key statistics.
152758 +
152759 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152760 +*//***************************************************************************/
152761 +
152762 +#if defined(CONFIG_COMPAT)
152763 +#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)
152764 +#endif
152765 +#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)
152766 +
152767 +/**************************************************************************//**
152768 + @Function FM_PCD_MatchTableGetMissStatistics
152769 +
152770 + @Description This routine may be used to get statistics counters of miss entry
152771 + in a CC Node.
152772 +
152773 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152774 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152775 + these counters reflect how many frames were not matched to any
152776 + existing key and therefore passed through the miss entry; The
152777 + total frames count will be returned in the counter of the
152778 + first range (as only one frame length range was defined).
152779 +
152780 + @Param[in] h_CcNode A handle to the node
152781 + @Param[out] p_MissStatistics Statistics counters for 'miss'
152782 +
152783 + @Return E_OK on success; Error code otherwise.
152784 +
152785 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152786 +*//***************************************************************************/
152787 +
152788 +#if defined(CONFIG_COMPAT)
152789 +#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)
152790 +#endif
152791 +#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)
152792 +
152793 +/**************************************************************************//**
152794 + @Function FM_PCD_HashTableGetMissStatistics
152795 +
152796 + @Description This routine may be used to get statistics counters of 'miss'
152797 + entry of the a hash table.
152798 +
152799 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152800 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152801 + these counters reflect how many frames were not matched to any
152802 + existing key and therefore passed through the miss entry;
152803 +
152804 + @Param[in] h_HashTbl A handle to a hash table
152805 + @Param[out] p_MissStatistics Statistics counters for 'miss'
152806 +
152807 + @Return E_OK on success; Error code otherwise.
152808 +
152809 + @Cautions Allowed only following FM_PCD_HashTableSet().
152810 +*//***************************************************************************/
152811 +
152812 +#if defined(CONFIG_COMPAT)
152813 +#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)
152814 +#endif
152815 +#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)
152816 +
152817 +
152818 +/**************************************************************************//**
152819 + @Function FM_PCD_NetEnvCharacteristicsSet
152820 +
152821 + @Description Define a set of Network Environment Characteristics.
152822 +
152823 + When setting an environment it is important to understand its
152824 + application. It is not meant to describe the flows that will run
152825 + on the ports using this environment, but what the user means TO DO
152826 + with the PCD mechanisms in order to parse-classify-distribute those
152827 + frames.
152828 + By specifying a distinction unit, the user means it would use that option
152829 + for distinction between frames at either a KeyGen scheme or a coarse
152830 + classification action descriptor. Using interchangeable headers to define a
152831 + unit means that the user is indifferent to which of the interchangeable
152832 + headers is present in the frame, and wants the distinction to be based
152833 + on the presence of either one of them.
152834 +
152835 + Depending on context, there are limitations to the use of environments. A
152836 + port using the PCD functionality is bound to an environment. Some or even
152837 + all ports may share an environment but also an environment per port is
152838 + possible. When initializing a scheme, a classification plan group (see below),
152839 + or a coarse classification tree, one of the initialized environments must be
152840 + stated and related to. When a port is bound to a scheme, a classification
152841 + plan group, or a coarse classification tree, it MUST be bound to the same
152842 + environment.
152843 +
152844 + The different PCD modules, may relate (for flows definition) ONLY on
152845 + distinction units as defined by their environment. When initializing a
152846 + scheme for example, it may not choose to select IPV4 as a match for
152847 + recognizing flows unless it was defined in the relating environment. In
152848 + fact, to guide the user through the configuration of the PCD, each module's
152849 + characterization in terms of flows is not done using protocol names, but using
152850 + environment indexes.
152851 +
152852 + In terms of HW implementation, the list of distinction units sets the LCV vectors
152853 + and later used for match vector, classification plan vectors and coarse classification
152854 + indexing.
152855 +
152856 + @Param[in,out] ioc_fm_pcd_net_env_params_t A structure defining the distiction units for this configuration.
152857 +
152858 + @Return 0 on success; Error code otherwise.
152859 +*//***************************************************************************/
152860 +#if defined(CONFIG_COMPAT)
152861 +#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)
152862 +#endif
152863 +#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)
152864 +
152865 +/**************************************************************************//**
152866 + @Function FM_PCD_NetEnvCharacteristicsDelete
152867 +
152868 + @Description Deletes a set of Network Environment Charecteristics.
152869 +
152870 + @Param[in] ioc_fm_obj_t - The id of a Network Environment object.
152871 +
152872 + @Return 0 on success; Error code otherwise.
152873 +*//***************************************************************************/
152874 +#if defined(CONFIG_COMPAT)
152875 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t)
152876 +#endif
152877 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t)
152878 +
152879 +/**************************************************************************//**
152880 + @Function FM_PCD_KgSchemeSet
152881 +
152882 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
152883 + This routine should be called for adding or modifying a scheme.
152884 + When a scheme needs modifying, the API requires that it will be
152885 + rewritten. In such a case 'modify' should be TRUE. If the
152886 + routine is called for a valid scheme and 'modify' is FALSE,
152887 + it will return error.
152888 +
152889 + @Param[in,out] ioc_fm_pcd_kg_scheme_params_t A structure of parameters for defining the scheme
152890 +
152891 + @Return 0 on success; Error code otherwise.
152892 +*//***************************************************************************/
152893 +#if defined(CONFIG_COMPAT)
152894 +#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)
152895 +#endif
152896 +#define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t)
152897 +
152898 +/**************************************************************************//**
152899 + @Function FM_PCD_KgSchemeDelete
152900 +
152901 + @Description Deleting an initialized scheme.
152902 +
152903 + @Param[in] ioc_fm_obj_t scheme id as initalized by application at FM_PCD_IOC_KG_SET_SCHEME
152904 +
152905 + @Return 0 on success; Error code otherwise.
152906 +*//***************************************************************************/
152907 +#if defined(CONFIG_COMPAT)
152908 +#define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t)
152909 +#endif
152910 +#define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t)
152911 +
152912 +/**************************************************************************//**
152913 + @Function FM_PCD_CcRootBuild
152914 +
152915 + @Description This routine must be called to define a complete coarse
152916 + classification tree. This is the way to define coarse
152917 + classification to a certain flow - the KeyGen schemes
152918 + may point only to trees defined in this way.
152919 +
152920 + @Param[in,out] ioc_fm_pcd_cc_tree_params_t A structure of parameters to define the tree.
152921 +
152922 + @Return 0 on success; Error code otherwise.
152923 +*//***************************************************************************/
152924 +#if defined(CONFIG_COMPAT)
152925 +#define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t)
152926 +#endif
152927 +#define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/
152928 +
152929 +/**************************************************************************//**
152930 + @Function FM_PCD_CcRootDelete
152931 +
152932 + @Description Deleting a built tree.
152933 +
152934 + @Param[in] ioc_fm_obj_t - The id of a CC tree.
152935 +*//***************************************************************************/
152936 +#if defined(CONFIG_COMPAT)
152937 +#define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t)
152938 +#endif
152939 +#define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t)
152940 +
152941 +/**************************************************************************//**
152942 + @Function FM_PCD_MatchTableSet
152943 +
152944 + @Description This routine should be called for each CC (coarse classification)
152945 + node. The whole CC tree should be built bottom up so that each
152946 + node points to already defined nodes. p_NodeId returns the node
152947 + Id to be used by other nodes.
152948 +
152949 + @Param[in,out] ioc_fm_pcd_cc_node_params_t A structure for defining the CC node params
152950 +
152951 + @Return 0 on success; Error code otherwise.
152952 +*//***************************************************************************/
152953 +#if defined(CONFIG_COMPAT)
152954 +#define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t)
152955 +#endif
152956 +#define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/
152957 +
152958 +/**************************************************************************//**
152959 + @Function FM_PCD_MatchTableDelete
152960 +
152961 + @Description Deleting a built node.
152962 +
152963 + @Param[in] ioc_fm_obj_t - The id of a CC node.
152964 +
152965 + @Return 0 on success; Error code otherwise.
152966 +*//***************************************************************************/
152967 +#if defined(CONFIG_COMPAT)
152968 +#define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t)
152969 +#endif
152970 +#define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t)
152971 +
152972 +/**************************************************************************//**
152973 + @Function FM_PCD_CcRootModifyNextEngine
152974 +
152975 + @Description Modify the Next Engine Parameters in the entry of the tree.
152976 +
152977 + @Param[in] ioc_fm_pcd_cc_tree_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152978 +
152979 + @Return 0 on success; Error code otherwise.
152980 +
152981 + @Cautions Allowed only following FM_PCD_CcRootBuild().
152982 +*//***************************************************************************/
152983 +#if defined(CONFIG_COMPAT)
152984 +#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)
152985 +#endif
152986 +#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)
152987 +
152988 +/**************************************************************************//**
152989 + @Function FM_PCD_MatchTableModifyNextEngine
152990 +
152991 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
152992 +
152993 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t A pointer to a structure with the relevant parameters
152994 +
152995 + @Return 0 on success; Error code otherwise.
152996 +
152997 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152998 +*//***************************************************************************/
152999 +#if defined(CONFIG_COMPAT)
153000 +#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)
153001 +#endif
153002 +#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)
153003 +
153004 +/**************************************************************************//**
153005 + @Function FM_PCD_MatchTableModifyMissNextEngine
153006 +
153007 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
153008 +
153009 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
153010 +
153011 + @Return 0 on success; Error code otherwise.
153012 +
153013 + @Cautions Allowed only following FM_PCD_MatchTableSet().
153014 +*//***************************************************************************/
153015 +#if defined(CONFIG_COMPAT)
153016 +#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)
153017 +#endif
153018 +#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)
153019 +
153020 +/**************************************************************************//**
153021 + @Function FM_PCD_MatchTableRemoveKey
153022 +
153023 + @Description Remove the key (including next engine parameters of this key)
153024 + defined by the index of the relevant node.
153025 +
153026 + @Param[in] ioc_fm_pcd_cc_node_remove_key_params_t A pointer to a structure with the relevant parameters
153027 +
153028 + @Return 0 on success; Error code otherwise.
153029 +
153030 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
153031 + node and for all of the nodes that lead to it.
153032 +*//***************************************************************************/
153033 +#if defined(CONFIG_COMPAT)
153034 +#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)
153035 +#endif
153036 +#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)
153037 +
153038 +/**************************************************************************//**
153039 + @Function FM_PCD_MatchTableAddKey
153040 +
153041 + @Description Add the key (including next engine parameters of this key in the
153042 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
153043 + may be used when the user doesn't care about the position of the
153044 + key in the table - in that case, the key will be automatically
153045 + added by the driver in the last available entry.
153046 +
153047 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
153048 +
153049 + @Return 0 on success; Error code otherwise.
153050 +
153051 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
153052 + node and for all of the nodes that lead to it.
153053 +*//***************************************************************************/
153054 +#if defined(CONFIG_COMPAT)
153055 +#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)
153056 +#endif
153057 +#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)
153058 +
153059 +/**************************************************************************//**
153060 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
153061 +
153062 + @Description Modify the key and Next Engine Parameters of this key in the index defined by key_index.
153063 +
153064 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
153065 +
153066 + @Return 0 on success; Error code otherwise.
153067 +
153068 + @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also
153069 + the node that points to this node
153070 +*//***************************************************************************/
153071 +#if defined(CONFIG_COMPAT)
153072 +#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)
153073 +#endif
153074 +#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)
153075 +
153076 +/**************************************************************************//**
153077 + @Function FM_PCD_MatchTableModifyKey
153078 +
153079 + @Description Modify the key at the index defined by key_index.
153080 +
153081 + @Param[in] ioc_fm_pcd_cc_node_modify_key_params_t - Pointer to a structure with the relevant parameters
153082 +
153083 + @Return 0 on success; Error code otherwise.
153084 +
153085 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
153086 + node and for all of the nodes that lead to it.
153087 +*//***************************************************************************/
153088 +#if defined(CONFIG_COMPAT)
153089 +#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)
153090 +#endif
153091 +#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)
153092 +
153093 +/**************************************************************************//**
153094 + @Function FM_PCD_HashTableSet
153095 +
153096 + @Description This routine initializes a hash table structure.
153097 + KeyGen hash result determines the hash bucket.
153098 + Next, KeyGen key is compared against all keys of this
153099 + bucket (exact match).
153100 + Number of sets (number of buckets) of the hash equals to the
153101 + number of 1-s in 'hash_res_mask' in the provided parameters.
153102 + Number of hash table ways is then calculated by dividing
153103 + 'max_num_of_keys' equally between the hash sets. This is the maximal
153104 + number of keys that a hash bucket may hold.
153105 + The hash table is initialized empty and keys may be
153106 + added to it following the initialization. Keys masks are not
153107 + supported in current hash table implementation.
153108 + The initialized hash table can be integrated as a node in a
153109 + CC tree.
153110 +
153111 + @Param[in,out] ioc_fm_pcd_hash_table_params_t - Pointer to a structure with the relevant parameters
153112 +
153113 + @Return 0 on success; Error code otherwise.
153114 +*//***************************************************************************/
153115 +#if defined(CONFIG_COMPAT)
153116 +#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)
153117 +#endif
153118 +#define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t)
153119 +
153120 +
153121 +/**************************************************************************//**
153122 + @Function FM_PCD_HashTableDelete
153123 +
153124 + @Description This routine deletes the provided hash table and released all
153125 + its allocated resources.
153126 +
153127 + @Param[in] ioc_fm_obj_t - The ID of a hash table.
153128 +
153129 + @Return 0 on success; Error code otherwise.
153130 +
153131 + @Cautions Allowed only following FM_PCD_HashTableSet().
153132 +*//***************************************************************************/
153133 +#if defined(CONFIG_COMPAT)
153134 +#define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t)
153135 +#endif
153136 +#define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t)
153137 +
153138 +/**************************************************************************//**
153139 + @Function FM_PCD_HashTableAddKey
153140 +
153141 + @Description This routine adds the provided key (including next engine
153142 + parameters of this key) to the hash table.
153143 + The key is added as the last key of the bucket that it is
153144 + mapped to.
153145 +
153146 + @Param[in] ioc_fm_pcd_hash_table_add_key_params_t - Pointer to a structure with the relevant parameters
153147 +
153148 + @Return 0 on success; error code otherwise.
153149 +
153150 + @Cautions Allowed only following FM_PCD_HashTableSet().
153151 +*//***************************************************************************/
153152 +#if defined(CONFIG_COMPAT)
153153 +#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)
153154 +#endif
153155 +#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)
153156 +
153157 +/**************************************************************************//**
153158 + @Function FM_PCD_HashTableRemoveKey
153159 +
153160 + @Description This routine removes the requested key (including next engine
153161 + parameters of this key) from the hash table.
153162 +
153163 + @Param[in] ioc_fm_pcd_hash_table_remove_key_params_t - Pointer to a structure with the relevant parameters
153164 +
153165 + @Return 0 on success; Error code otherwise.
153166 +
153167 + @Cautions Allowed only following FM_PCD_HashTableSet().
153168 +*//***************************************************************************/
153169 +#if defined(CONFIG_COMPAT)
153170 +#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)
153171 +#endif
153172 +#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)
153173 +
153174 +/**************************************************************************//**
153175 + @Function FM_PCD_PlcrProfileSet
153176 +
153177 + @Description Sets a profile entry in the policer profile table.
153178 + The routine overrides any existing value.
153179 +
153180 + @Param[in,out] ioc_fm_pcd_plcr_profile_params_t A structure of parameters for defining a
153181 + policer profile entry.
153182 +
153183 + @Return 0 on success; Error code otherwise.
153184 +*//***************************************************************************/
153185 +#if defined(CONFIG_COMPAT)
153186 +#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)
153187 +#endif
153188 +#define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t)
153189 +
153190 +/**************************************************************************//**
153191 + @Function FM_PCD_PlcrProfileDelete
153192 +
153193 + @Description Delete a profile entry in the policer profile table.
153194 + The routine set entry to invalid.
153195 +
153196 + @Param[in] ioc_fm_obj_t The id of a policer profile.
153197 +
153198 + @Return 0 on success; Error code otherwise.
153199 +*//***************************************************************************/
153200 +#if defined(CONFIG_COMPAT)
153201 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t)
153202 +#endif
153203 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t)
153204 +
153205 +/**************************************************************************//**
153206 + @Function FM_PCD_ManipNodeSet
153207 +
153208 + @Description This routine should be called for defining a manipulation
153209 + node. A manipulation node must be defined before the CC node
153210 + that precedes it.
153211 +
153212 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
153213 +
153214 + @Return A handle to the initialized object on success; NULL code otherwise.
153215 +*//***************************************************************************/
153216 +#if defined(CONFIG_COMPAT)
153217 +#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)
153218 +#endif
153219 +#define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t)
153220 +
153221 +/**************************************************************************//**
153222 + @Function FM_PCD_ManipNodeReplace
153223 +
153224 + @Description Change existing manipulation node to be according to new requirement.
153225 + (Here, it's implemented as a variant of the same IOCTL as for
153226 + FM_PCD_ManipNodeSet(), and one that when called, the 'id' member
153227 + in its 'ioc_fm_pcd_manip_params_t' argument is set to contain
153228 + the manip node's handle)
153229 +
153230 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
153231 +
153232 + @Return 0 on success; error code otherwise.
153233 +
153234 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
153235 +*//***************************************************************************/
153236 +#if defined(CONFIG_COMPAT)
153237 +#define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
153238 +#endif
153239 +#define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET
153240 +
153241 +/**************************************************************************//**
153242 + @Function FM_PCD_ManipNodeDelete
153243 +
153244 + @Description Delete an existing manipulation node.
153245 +
153246 + @Param[in] ioc_fm_obj_t The id of the manipulation node to delete.
153247 +
153248 + @Return 0 on success; error code otherwise.
153249 +
153250 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
153251 +*//***************************************************************************/
153252 +#if defined(CONFIG_COMPAT)
153253 +#define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t)
153254 +#endif
153255 +#define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t)
153256 +
153257 +/**************************************************************************//**
153258 + @Function FM_PCD_ManipGetStatistics
153259 +
153260 + @Description Retrieve the manipulation statistics.
153261 +
153262 + @Param[in] h_ManipNode A handle to a manipulation node.
153263 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
153264 +
153265 + @Return E_OK on success; Error code otherwise.
153266 +
153267 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
153268 +*//***************************************************************************/
153269 +#if defined(CONFIG_COMPAT)
153270 +#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)
153271 +#endif
153272 +#define FM_PCD_IOC_MANIP_GET_STATS _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_fm_pcd_manip_get_stats_t)
153273 +
153274 +/**************************************************************************//**
153275 +@Function FM_PCD_SetAdvancedOffloadSupport
153276 +
153277 +@Description This routine must be called in order to support the following features:
153278 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
153279 +
153280 +@Param[in] h_FmPcd FM PCD module descriptor.
153281 +
153282 +@Return 0 on success; error code otherwise.
153283 +
153284 +@Cautions Allowed only when PCD is disabled.
153285 +*//***************************************************************************/
153286 +#define FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45))
153287 +
153288 +#if (DPAA_VERSION >= 11)
153289 +/**************************************************************************//**
153290 + @Function FM_PCD_FrmReplicSetGroup
153291 +
153292 + @Description Initialize a Frame Replicator group.
153293 +
153294 + @Param[in] h_FmPcd FM PCD module descriptor.
153295 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
153296 + the frame replicator group.
153297 +
153298 + @Return A handle to the initialized object on success; NULL code otherwise.
153299 +
153300 + @Cautions Allowed only following FM_PCD_Init().
153301 +*//***************************************************************************/
153302 +#if defined(CONFIG_COMPAT)
153303 +#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)
153304 +#endif
153305 +#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)
153306 +
153307 +/**************************************************************************//**
153308 + @Function FM_PCD_FrmReplicDeleteGroup
153309 +
153310 + @Description Delete a Frame Replicator group.
153311 +
153312 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
153313 +
153314 + @Return E_OK on success; Error code otherwise.
153315 +
153316 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
153317 +*//***************************************************************************/
153318 +#if defined(CONFIG_COMPAT)
153319 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t)
153320 +#endif
153321 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t)
153322 +
153323 +/**************************************************************************//**
153324 + @Function FM_PCD_FrmReplicAddMember
153325 +
153326 + @Description Add the member in the index defined by the memberIndex.
153327 +
153328 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
153329 + @Param[in] memberIndex member index for adding.
153330 + @Param[in] p_MemberParams A pointer to the new member parameters.
153331 +
153332 + @Return E_OK on success; Error code otherwise.
153333 +
153334 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
153335 +*//***************************************************************************/
153336 +#if defined(CONFIG_COMPAT)
153337 +#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)
153338 +#endif
153339 +#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)
153340 +
153341 +/**************************************************************************//**
153342 + @Function FM_PCD_FrmReplicRemoveMember
153343 +
153344 + @Description Remove the member defined by the index from the relevant group.
153345 +
153346 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
153347 + @Param[in] memberIndex member index for removing.
153348 +
153349 + @Return E_OK on success; Error code otherwise.
153350 +
153351 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
153352 +*//***************************************************************************/
153353 +#if defined(CONFIG_COMPAT)
153354 +#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)
153355 +#endif
153356 +#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)
153357 +
153358 +#endif
153359 +
153360 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
153361 +/**************************************************************************//**
153362 + @Function FM_PCD_StatisticsSetNode
153363 +
153364 + @Description This routine should be called for defining a statistics node.
153365 +
153366 + @Param[in,out] ioc_fm_pcd_stats_params_t A structure of parameters defining the statistics
153367 +
153368 + @Return 0 on success; Error code otherwise.
153369 +*//***************************************************************************/
153370 +#if defined(CONFIG_COMPAT)
153371 +#define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
153372 +#endif
153373 +#define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
153374 +
153375 +#endif /* FM_CAPWAP_SUPPORT */
153376 +
153377 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
153378 +#if defined(CONFIG_COMPAT)
153379 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \
153380 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT
153381 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \
153382 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT
153383 +#define FM_PCD_IOC_KG_SET_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_SET_COMPAT
153384 +#define FM_PCD_IOC_KG_DEL_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT
153385 +#define FM_PCD_IOC_CC_BUILD_TREE_COMPAT FM_PCD_IOC_CC_ROOT_BUILD_COMPAT
153386 +#define FM_PCD_IOC_CC_DELETE_TREE_COMPAT FM_PCD_IOC_CC_ROOT_DELETE_COMPAT
153387 +#define FM_PCD_IOC_CC_DELETE_NODE_COMPAT FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT
153388 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE_COMPAT \
153389 + FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT
153390 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE_COMPAT \
153391 + FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT
153392 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE_COMPAT \
153393 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT
153394 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT
153395 +#define FM_PCD_IOC_CC_NODE_ADD_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT
153396 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT \
153397 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT
153398 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT
153399 +#define FM_PCD_IOC_PLCR_SET_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT
153400 +#define FM_PCD_IOC_PLCR_DEL_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT
153401 +#define FM_PCD_IOC_MANIP_SET_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
153402 +#define FM_PCD_IOC_MANIP_DELETE_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT
153403 +#endif
153404 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET
153405 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS \
153406 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE
153407 +#define FM_PCD_IOC_KG_SET_SCHEME FM_PCD_IOC_KG_SCHEME_SET
153408 +#define FM_PCD_IOC_KG_DEL_SCHEME FM_PCD_IOC_KG_SCHEME_DELETE
153409 +#define FM_PCD_IOC_CC_BUILD_TREE FM_PCD_IOC_CC_ROOT_BUILD
153410 +#define FM_PCD_IOC_CC_DELETE_TREE FM_PCD_IOC_CC_ROOT_DELETE
153411 +#define FM_PCD_IOC_CC_DELETE_NODE FM_PCD_IOC_MATCH_TABLE_DELETE
153412 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE
153413 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE
153414 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE \
153415 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE
153416 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY
153417 +#define FM_PCD_IOC_CC_NODE_ADD_KEY FM_PCD_IOC_MATCH_TABLE_ADD_KEY
153418 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE \
153419 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE
153420 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY
153421 +#define FM_PCD_IOC_PLCR_SET_PROFILE FM_PCD_IOC_PLCR_PROFILE_SET
153422 +#define FM_PCD_IOC_PLCR_DEL_PROFILE FM_PCD_IOC_PLCR_PROFILE_DELETE
153423 +#define FM_PCD_IOC_MANIP_SET_NODE FM_PCD_IOC_MANIP_NODE_SET
153424 +#define FM_PCD_IOC_MANIP_DELETE_NODE FM_PCD_IOC_MANIP_NODE_DELETE
153425 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
153426 +
153427 +#endif /* __FM_PCD_IOCTLS_H */
153428 +/** @} */ /* end of lnx_ioctl_FM_PCD_Runtime_grp group */
153429 +/** @} */ /* end of lnx_ioctl_FM_PCD_grp group */
153430 +/** @} */ /* end of lnx_ioctl_FM_grp group */
153431 diff --git a/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
153432 new file mode 100644
153433 index 00000000..eb9bd9a7
153434 --- /dev/null
153435 +++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
153436 @@ -0,0 +1,973 @@
153437 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153438 + * All rights reserved.
153439 + *
153440 + * Redistribution and use in source and binary forms, with or without
153441 + * modification, are permitted provided that the following conditions are met:
153442 + * * Redistributions of source code must retain the above copyright
153443 + * notice, this list of conditions and the following disclaimer.
153444 + * * Redistributions in binary form must reproduce the above copyright
153445 + * notice, this list of conditions and the following disclaimer in the
153446 + * documentation and/or other materials provided with the distribution.
153447 + * * Neither the name of Freescale Semiconductor nor the
153448 + * names of its contributors may be used to endorse or promote products
153449 + * derived from this software without specific prior written permission.
153450 + *
153451 + *
153452 + * ALTERNATIVELY, this software may be distributed under the terms of the
153453 + * GNU General Public License ("GPL") as published by the Free Software
153454 + * Foundation, either version 2 of that License or (at your option) any
153455 + * later version.
153456 + *
153457 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153458 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153459 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153460 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153461 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153462 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153463 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153464 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153465 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153466 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153467 + */
153468 +
153469 +/******************************************************************************
153470 + @File fm_port_ioctls.h
153471 +
153472 + @Description FM Port routines
153473 +*//***************************************************************************/
153474 +#ifndef __FM_PORT_IOCTLS_H
153475 +#define __FM_PORT_IOCTLS_H
153476 +
153477 +#include "enet_ext.h"
153478 +#include "net_ioctls.h"
153479 +#include "fm_ioctls.h"
153480 +#include "fm_pcd_ioctls.h"
153481 +
153482 +
153483 +/**************************************************************************//**
153484 +
153485 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
153486 +
153487 + @Description FM Linux ioctls definitions and enums
153488 +
153489 + @{
153490 +*//***************************************************************************/
153491 +
153492 +/**************************************************************************//**
153493 + @Group lnx_ioctl_FM_PORT_grp FM Port
153494 +
153495 + @Description FM Port API
153496 +
153497 + The FM uses a general module called "port" to represent a Tx port
153498 + (MAC), an Rx port (MAC), offline parsing flow or host command
153499 + flow. There may be up to 17 (may change) ports in an FM - 5 Tx
153500 + ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7
153501 + Host command/Offline parsing ports. The SW driver manages these
153502 + ports as sub-modules of the FM, i.e. after an FM is initialized,
153503 + its ports may be initialized and operated upon.
153504 +
153505 + The port is initialized aware of its type, but other functions on
153506 + a port may be indifferent to its type. When necessary, the driver
153507 + verifies coherency and returns error if applicable.
153508 +
153509 + On initialization, user specifies the port type and it's index
153510 + (relative to the port's type). Host command and Offline parsing
153511 + ports share the same id range, I.e user may not initialized host
153512 + command port 0 and offline parsing port 0.
153513 +
153514 + @{
153515 +*//***************************************************************************/
153516 +
153517 +/**************************************************************************//**
153518 + @Description An enum for defining port PCD modes.
153519 + (Must match enum e_FmPortPcdSupport defined in fm_port_ext.h)
153520 +
153521 + This enum defines the superset of PCD engines support - i.e. not
153522 + all engines have to be used, but all have to be enabled. The real
153523 + flow of a specific frame depends on the PCD configuration and the
153524 + frame headers and payload.
153525 + Note: the first engine and the first engine after the parser (if
153526 + exists) should be in order, the order is important as it will
153527 + define the flow of the port. However, as for the rest engines
153528 + (the ones that follows), the order is not important anymore as
153529 + it is defined by the PCD graph itself.
153530 +*//***************************************************************************/
153531 +typedef enum ioc_fm_port_pcd_support {
153532 + e_IOC_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
153533 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
153534 + , e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
153535 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
153536 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
153537 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
153538 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
153539 + /**< Use all PCD engines */
153540 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
153541 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
153542 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
153543 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
153544 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
153545 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
153546 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
153547 +#endif /* FM_CAPWAP_SUPPORT */
153548 +} ioc_fm_port_pcd_support;
153549 +
153550 +
153551 +/**************************************************************************//**
153552 + @Collection FM Frame error
153553 +*//***************************************************************************/
153554 +typedef uint32_t ioc_fm_port_frame_err_select_t; /**< typedef for defining Frame Descriptor errors */
153555 +
153556 +/* @} */
153557 +
153558 +
153559 +/**************************************************************************//**
153560 + @Description An enum for defining Dual Tx rate limiting scale.
153561 + (Must match e_FmPortDualRateLimiterScaleDown defined in fm_port_ext.h)
153562 +*//***************************************************************************/
153563 +typedef enum ioc_fm_port_dual_rate_limiter_scale_down {
153564 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
153565 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
153566 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
153567 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
153568 +} ioc_fm_port_dual_rate_limiter_scale_down;
153569 +
153570 +/**************************************************************************//**
153571 + @Description A structure for defining Tx rate limiting
153572 + (Must match struct t_FmPortRateLimit defined in fm_port_ext.h)
153573 +*//***************************************************************************/
153574 +typedef struct ioc_fm_port_rate_limit_t {
153575 + uint16_t max_burst_size; /**< in KBytes for Tx ports, in frames
153576 + for offline parsing ports. (note that
153577 + for early chips burst size is
153578 + rounded up to a multiply of 1000 frames).*/
153579 + uint32_t rate_limit; /**< in Kb/sec for Tx ports, in frame/sec for
153580 + offline parsing ports. Rate limit refers to
153581 + data rate (rather than line rate). */
153582 + ioc_fm_port_dual_rate_limiter_scale_down rate_limit_divider; /**< For offline parsing ports only. Not-valid
153583 + for some earlier chip revisions */
153584 +} ioc_fm_port_rate_limit_t;
153585 +
153586 +
153587 +
153588 +/**************************************************************************//**
153589 + @Group lnx_ioctl_FM_PORT_runtime_control_grp FM Port Runtime Control Unit
153590 +
153591 + @Description FM Port Runtime control unit API functions, definitions and enums.
153592 +
153593 + @{
153594 +*//***************************************************************************/
153595 +
153596 +/**************************************************************************//**
153597 + @Description An enum for defining FM Port counters.
153598 + (Must match enum e_FmPortCounters defined in fm_port_ext.h)
153599 +*//***************************************************************************/
153600 +typedef enum ioc_fm_port_counters {
153601 + e_IOC_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
153602 + e_IOC_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
153603 + e_IOC_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
153604 + e_IOC_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
153605 + e_IOC_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
153606 + e_IOC_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
153607 + e_IOC_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
153608 + e_IOC_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
153609 + e_IOC_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
153610 + e_IOC_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
153611 + e_IOC_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
153612 + e_IOC_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
153613 + e_IOC_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
153614 + e_IOC_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
153615 + e_IOC_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
153616 + e_IOC_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
153617 + e_IOC_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
153618 + e_IOC_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
153619 + e_IOC_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
153620 + e_IOC_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
153621 + e_IOC_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
153622 + e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
153623 +} ioc_fm_port_counters;
153624 +
153625 +typedef struct ioc_fm_port_bmi_stats_t {
153626 + uint32_t cnt_cycle;
153627 + uint32_t cnt_task_util;
153628 + uint32_t cnt_queue_util;
153629 + uint32_t cnt_dma_util;
153630 + uint32_t cnt_fifo_util;
153631 + uint32_t cnt_rx_pause_activation;
153632 + uint32_t cnt_frame;
153633 + uint32_t cnt_discard_frame;
153634 + uint32_t cnt_dealloc_buf;
153635 + uint32_t cnt_rx_bad_frame;
153636 + uint32_t cnt_rx_large_frame;
153637 + uint32_t cnt_rx_filter_frame;
153638 + uint32_t cnt_rx_list_dma_err;
153639 + uint32_t cnt_rx_out_of_buffers_discard;
153640 + uint32_t cnt_wred_discard;
153641 + uint32_t cnt_length_err;
153642 + uint32_t cnt_unsupported_format;
153643 +} ioc_fm_port_bmi_stats_t;
153644 +
153645 +/**************************************************************************//**
153646 + @Description Structure for Port id parameters.
153647 + (Description may be inaccurate;
153648 + must match struct t_FmPortCongestionGrps defined in fm_port_ext.h)
153649 +
153650 + Fields commented 'IN' are passed by the port module to be used
153651 + by the FM module.
153652 + Fields commented 'OUT' will be filled by FM before returning to port.
153653 +*//***************************************************************************/
153654 +typedef struct ioc_fm_port_congestion_groups_t {
153655 + uint16_t num_of_congestion_grps_to_consider; /**< The number of required congestion groups
153656 + to define the size of the following array */
153657 + uint8_t congestion_grps_to_consider [FM_PORT_NUM_OF_CONGESTION_GRPS];
153658 + /**< An array of CG indexes;
153659 + Note that the size of the array should be
153660 + 'num_of_congestion_grps_to_consider'. */
153661 +#if DPAA_VERSION >= 11
153662 + bool pfc_priorities_enable[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
153663 + /**< A matrix that represents the map between the CG ids
153664 + defined in 'congestion_grps_to_consider' to the priorities
153665 + mapping array. */
153666 +#endif /* DPAA_VERSION >= 11 */
153667 +} ioc_fm_port_congestion_groups_t;
153668 +
153669 +
153670 +
153671 +/**************************************************************************//**
153672 + @Function FM_PORT_Disable
153673 +
153674 + @Description Gracefully disable an FM port. The port will not start new tasks after all
153675 + tasks associated with the port are terminated.
153676 +
153677 + @Return 0 on success; error code otherwise.
153678 +
153679 + @Cautions This is a blocking routine, it returns after port is
153680 + gracefully stopped, i.e. the port will not except new frames,
153681 + but it will finish all frames or tasks which were already began
153682 +*//***************************************************************************/
153683 +#define FM_PORT_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(1))
153684 +
153685 +/**************************************************************************//**
153686 + @Function FM_PORT_Enable
153687 +
153688 + @Description A runtime routine provided to allow disable/enable of port.
153689 +
153690 + @Return 0 on success; error code otherwise.
153691 +*//***************************************************************************/
153692 +#define FM_PORT_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(2))
153693 +
153694 +/**************************************************************************//**
153695 + @Function FM_PORT_SetRateLimit
153696 +
153697 + @Description Calling this routine enables rate limit algorithm.
153698 + By default, this functionality is disabled.
153699 + Note that rate-limit mechanism uses the FM time stamp.
153700 + The selected rate limit specified here would be
153701 + rounded DOWN to the nearest 16M.
153702 +
153703 + May be used for Tx and offline parsing ports only
153704 +
153705 + @Param[in] ioc_fm_port_rate_limit A structure of rate limit parameters
153706 +
153707 + @Return 0 on success; error code otherwise.
153708 +*//***************************************************************************/
153709 +#define FM_PORT_IOC_SET_RATE_LIMIT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(3), ioc_fm_port_rate_limit_t)
153710 +
153711 +/**************************************************************************//**
153712 + @Function FM_PORT_DeleteRateLimit
153713 +
153714 + @Description Calling this routine disables the previously enabled rate limit.
153715 +
153716 + May be used for Tx and offline parsing ports only
153717 +
153718 + @Return 0 on success; error code otherwise.
153719 +*//***************************************************************************/
153720 +#define FM_PORT_IOC_DELETE_RATE_LIMIT _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(5))
153721 +#define FM_PORT_IOC_REMOVE_RATE_LIMIT FM_PORT_IOC_DELETE_RATE_LIMIT
153722 +
153723 +
153724 +/**************************************************************************//**
153725 + @Function FM_PORT_AddCongestionGrps
153726 +
153727 + @Description This routine effects the corresponding Tx port.
153728 + It should be called in order to enable pause
153729 + frame transmission in case of congestion in one or more
153730 + of the congestion groups relevant to this port.
153731 + Each call to this routine may add one or more congestion
153732 + groups to be considered relevant to this port.
153733 +
153734 + May be used for Rx, or RX+OP ports only (depending on chip)
153735 +
153736 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
153737 + congestion group ids to consider.
153738 +
153739 + @Return 0 on success; error code otherwise.
153740 +*//***************************************************************************/
153741 +#define FM_PORT_IOC_ADD_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(34), ioc_fm_port_congestion_groups_t)
153742 +
153743 +/**************************************************************************//**
153744 + @Function FM_PORT_RemoveCongestionGrps
153745 +
153746 + @Description This routine effects the corresponding Tx port. It should be
153747 + called when congestion groups were
153748 + defined for this port and are no longer relevant, or pause
153749 + frames transmitting is not required on their behalf.
153750 + Each call to this routine may remove one or more congestion
153751 + groups to be considered relevant to this port.
153752 +
153753 + May be used for Rx, or RX+OP ports only (depending on chip)
153754 +
153755 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
153756 + congestion group ids to consider.
153757 +
153758 + @Return 0 on success; error code otherwise.
153759 +*//***************************************************************************/
153760 +#define FM_PORT_IOC_REMOVE_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(35), ioc_fm_port_congestion_groups_t)
153761 +
153762 +/**************************************************************************//**
153763 + @Function FM_PORT_SetErrorsRoute
153764 +
153765 + @Description Errors selected for this routine will cause a frame with that error
153766 + to be enqueued to error queue.
153767 + Errors not selected for this routine will cause a frame with that error
153768 + to be enqueued to the one of the other port queues.
153769 + By default all errors are defined to be enqueued to error queue.
153770 + Errors that were configured to be discarded (at initialization)
153771 + may not be selected here.
153772 +
153773 + May be used for Rx and offline parsing ports only
153774 +
153775 + @Param[in] ioc_fm_port_frame_err_select_t A list of errors to enqueue to error queue
153776 +
153777 + @Return 0 on success; error code otherwise.
153778 +
153779 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
153780 + (szbs001: How is it possible to have one function that needs to be
153781 + called BEFORE FM_PORT_Init() implemented as an ioctl,
153782 + which will ALWAYS be called AFTER the FM_PORT_Init()
153783 + for that port!?!?!?!???!?!??!?!?)
153784 +*//***************************************************************************/
153785 +#define FM_PORT_IOC_SET_ERRORS_ROUTE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(4), ioc_fm_port_frame_err_select_t)
153786 +
153787 +
153788 +/**************************************************************************//**
153789 + @Group lnx_ioctl_FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
153790 +
153791 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
153792 +
153793 + @{
153794 +*//***************************************************************************/
153795 +
153796 +/**************************************************************************//**
153797 + @Description A structure defining the KG scheme after the parser.
153798 + (Must match struct t_FmPcdKgSchemeSelect defined in fm_port_ext.h)
153799 +
153800 + This is relevant only to change scheme selection mode - from
153801 + direct to indirect and vice versa, or when the scheme is selected directly,
153802 + to select the scheme id.
153803 +
153804 +*//***************************************************************************/
153805 +typedef struct ioc_fm_pcd_kg_scheme_select_t {
153806 + bool direct; /**< TRUE to use 'scheme_id' directly, FALSE to use LCV.*/
153807 + void *scheme_id; /**< Relevant for 'direct'=TRUE only.
153808 + 'scheme_id' selects the scheme after parser. */
153809 +} ioc_fm_pcd_kg_scheme_select_t;
153810 +
153811 +/**************************************************************************//**
153812 + @Description Scheme IDs structure
153813 + (Must match struct t_FmPcdPortSchemesParams defined in fm_port_ext.h)
153814 +*//***************************************************************************/
153815 +typedef struct ioc_fm_pcd_port_schemes_params_t {
153816 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
153817 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'num_of_schemes' schemes for the
153818 + port to be bound to */
153819 +} ioc_fm_pcd_port_schemes_params_t;
153820 +
153821 +/**************************************************************************//**
153822 + @Description A union for defining port protocol parameters for parser
153823 + (Must match union u_FmPcdHdrPrsOpts defined in fm_port_ext.h)
153824 +*//***************************************************************************/
153825 +typedef union ioc_fm_pcd_hdr_prs_opts_u {
153826 + /* MPLS */
153827 + struct {
153828 + bool label_interpretation_enable;/**< When this bit is set, the last MPLS label will be
153829 + interpreted as described in HW spec table. When the bit
153830 + is cleared, the parser will advance to MPLS next parse */
153831 + ioc_net_header_type next_parse; /**< must be equal or higher than IPv4 */
153832 + } mpls_prs_options;
153833 +
153834 + /* VLAN */
153835 + struct {
153836 + uint16_t tag_protocol_id1; /**< User defined Tag Protocol Identifier, to be recognized
153837 + on VLAN TAG on top of 0x8100 and 0x88A8 */
153838 + uint16_t tag_protocol_id2; /**< User defined Tag Protocol Identifier, to be recognized
153839 + on VLAN TAG on top of 0x8100 and 0x88A8 */
153840 + } vlan_prs_options;
153841 +
153842 + /* PPP */
153843 + struct{
153844 + bool enable_mtu_check; /**< Check validity of MTU according to RFC2516 */
153845 + } pppoe_prs_options;
153846 +
153847 + /* IPV6 */
153848 + struct {
153849 + bool routing_hdr_disable; /**< Disable routing header */
153850 + } ipv6_prs_options;
153851 +
153852 + /* UDP */
153853 + struct {
153854 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
153855 + } udp_prs_options;
153856 +
153857 + /* TCP */
153858 + struct {
153859 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
153860 + } tcp_prs_options;
153861 +} ioc_fm_pcd_hdr_prs_opts_u;
153862 +
153863 +/**************************************************************************//**
153864 + @Description A structure for defining each header for the parser
153865 + (must match struct t_FmPcdPrsAdditionalHdrParams defined in fm_port_ext.h)
153866 +*//***************************************************************************/
153867 +typedef struct ioc_fm_pcd_prs_additional_hdr_params_t {
153868 + ioc_net_header_type hdr; /**< Selected header */
153869 + bool err_disable; /**< TRUE to disable error indication */
153870 + bool soft_prs_enable; /**< Enable jump to SW parser when this
153871 + header is recognized by the HW parser. */
153872 + uint8_t index_per_hdr; /**< Normally 0, if more than one sw parser
153873 + attachments exists for the same header,
153874 + (in the main sw parser code) use this
153875 + index to distinguish between them. */
153876 + bool use_prs_opts; /**< TRUE to use parser options. */
153877 + ioc_fm_pcd_hdr_prs_opts_u prs_opts; /**< A unuion according to header type,
153878 + defining the parser options selected.*/
153879 +} ioc_fm_pcd_prs_additional_hdr_params_t;
153880 +
153881 +/**************************************************************************//**
153882 + @Description A structure for defining port PCD parameters
153883 + (Must match t_FmPortPcdPrsParams defined in fm_port_ext.h)
153884 +*//***************************************************************************/
153885 +typedef struct ioc_fm_port_pcd_prs_params_t {
153886 + uint8_t prs_res_priv_info; /**< The private info provides a method of inserting
153887 + port information into the parser result. This information
153888 + may be extracted by KeyGen and be used for frames
153889 + distribution when a per-port distinction is required,
153890 + it may also be used as a port logical id for analyzing
153891 + incoming frames. */
153892 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to start parsing */
153893 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at 'parsing_offset' */
153894 + bool include_in_prs_statistics; /**< TRUE to include this port in the parser statistics */
153895 + uint8_t num_of_hdrs_with_additional_params;
153896 + /**< Normally 0, some headers may get special parameters */
153897 + ioc_fm_pcd_prs_additional_hdr_params_t additional_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
153898 + /**< 'num_of_hdrs_with_additional_params' structures
153899 + additional parameters for each header that requires them */
153900 + bool set_vlan_tpid1; /**< TRUE to configure user selection of Ethertype to
153901 + indicate a VLAN tag (in addition to the TPID values
153902 + 0x8100 and 0x88A8). */
153903 + uint16_t vlan_tpid1; /**< extra tag to use if set_vlan_tpid1=TRUE. */
153904 + bool set_vlan_tpid2; /**< TRUE to configure user selection of Ethertype to
153905 + indicate a VLAN tag (in addition to the TPID values
153906 + 0x8100 and 0x88A8). */
153907 + uint16_t vlan_tpid2; /**< extra tag to use if set_vlan_tpid1=TRUE. */
153908 +} ioc_fm_port_pcd_prs_params_t;
153909 +
153910 +/**************************************************************************//**
153911 + @Description A structure for defining coarse alassification parameters
153912 + (Must match t_FmPortPcdCcParams defined in fm_port_ext.h)
153913 +*//***************************************************************************/
153914 +typedef struct ioc_fm_port_pcd_cc_params_t {
153915 + void *cc_tree_id; /**< CC tree id */
153916 +} ioc_fm_port_pcd_cc_params_t;
153917 +
153918 +/**************************************************************************//**
153919 + @Description A structure for defining keygen parameters
153920 + (Must match t_FmPortPcdKgParams defined in fm_port_ext.h)
153921 +*//***************************************************************************/
153922 +typedef struct ioc_fm_port_pcd_kg_params_t {
153923 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
153924 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
153925 + /**< Array of 'num_of_schemes' schemes for the
153926 + port to be bound to */
153927 + bool direct_scheme; /**< TRUE for going from parser to a specific scheme,
153928 + regardless of parser result */
153929 + void *direct_scheme_id; /**< Scheme id, as returned by FM_PCD_KgSetScheme;
153930 + relevant only if direct=TRUE. */
153931 +} ioc_fm_port_pcd_kg_params_t;
153932 +
153933 +/**************************************************************************//**
153934 + @Description A structure for defining policer parameters
153935 + (Must match t_FmPortPcdPlcrParams defined in fm_port_ext.h)
153936 +*//***************************************************************************/
153937 +typedef struct ioc_fm_port_pcd_plcr_params_t {
153938 + void *plcr_profile_id; /**< Selected profile handle;
153939 + relevant in one of the following cases:
153940 + e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
153941 + e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
153942 + or if any flow uses a KG scheme where policer
153943 + profile is not generated (bypass_plcr_profile_generation selected) */
153944 +} ioc_fm_port_pcd_plcr_params_t;
153945 +
153946 +/**************************************************************************//**
153947 + @Description A structure for defining port PCD parameters
153948 + (Must match struct t_FmPortPcdParams defined in fm_port_ext.h)
153949 +*//***************************************************************************/
153950 +typedef struct ioc_fm_port_pcd_params_t {
153951 + ioc_fm_port_pcd_support pcd_support; /**< Relevant for Rx and offline ports only.
153952 + Describes the active PCD engines for this port. */
153953 + void *net_env_id; /**< HL Unused in PLCR only mode */
153954 + ioc_fm_port_pcd_prs_params_t *p_prs_params; /**< Parser parameters for this port */
153955 + ioc_fm_port_pcd_cc_params_t *p_cc_params; /**< Coarse classification parameters for this port */
153956 + ioc_fm_port_pcd_kg_params_t *p_kg_params; /**< Keygen parameters for this port */
153957 + ioc_fm_port_pcd_plcr_params_t *p_plcr_params; /**< Policer parameters for this port */
153958 + void *p_ip_reassembly_manip;/**< IP Reassembly manipulation */
153959 +#if (DPAA_VERSION >= 11)
153960 + void *p_capwap_reassembly_manip;/**< CAPWAP Reassembly manipulation */
153961 +#endif /* (DPAA_VERSION >= 11) */
153962 +} ioc_fm_port_pcd_params_t;
153963 +
153964 +/**************************************************************************//**
153965 + @Description A structure for defining the Parser starting point
153966 + (Must match struct t_FmPcdPrsStart defined in fm_port_ext.h)
153967 +*//***************************************************************************/
153968 +typedef struct ioc_fm_pcd_prs_start_t {
153969 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to
153970 + start parsing */
153971 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at
153972 + 'parsing_offset' */
153973 +} ioc_fm_pcd_prs_start_t;
153974 +
153975 +
153976 +/**************************************************************************//**
153977 + @Description FQID parameters structure
153978 +*//***************************************************************************/
153979 +typedef struct ioc_fm_port_pcd_fqids_params_t {
153980 + uint32_t num_fqids; /**< Number of fqids to be allocated for the port */
153981 + uint8_t alignment; /**< Alignment required for this port */
153982 + uint32_t base_fqid; /**< output parameter - the base fqid */
153983 +} ioc_fm_port_pcd_fqids_params_t;
153984 +
153985 +
153986 +/**************************************************************************//**
153987 + @Function FM_PORT_IOC_ALLOC_PCD_FQIDS
153988 +
153989 + @Description Allocates FQID's
153990 +
153991 + May be used for Rx and offline parsing ports only
153992 +
153993 + @Param[in,out] ioc_fm_port_pcd_fqids_params_t Parameters for allocating FQID's
153994 +
153995 + @Return 0 on success; error code otherwise.
153996 +*//***************************************************************************/
153997 +#define FM_PORT_IOC_ALLOC_PCD_FQIDS _IOWR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), ioc_fm_port_pcd_fqids_params_t)
153998 +
153999 +/**************************************************************************//**
154000 + @Function FM_PORT_IOC_FREE_PCD_FQIDS
154001 +
154002 + @Description Frees previously-allocated FQIDs
154003 +
154004 + May be used for Rx and offline parsing ports only
154005 +
154006 + @Param[in] uint32_t Base FQID of previously allocated range.
154007 +
154008 + @Return 0 on success; error code otherwise.
154009 +*//***************************************************************************/
154010 +#define FM_PORT_IOC_FREE_PCD_FQIDS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), uint32_t)
154011 +
154012 +
154013 +/**************************************************************************//**
154014 + @Function FM_PORT_SetPCD
154015 +
154016 + @Description Calling this routine defines the port's PCD configuration.
154017 + It changes it from its default configuration which is PCD
154018 + disabled (BMI to BMI) and configures it according to the passed
154019 + parameters.
154020 +
154021 + May be used for Rx and offline parsing ports only
154022 +
154023 + @Param[in] ioc_fm_port_pcd_params_t A Structure of parameters defining the port's PCD
154024 + configuration.
154025 +
154026 + @Return 0 on success; error code otherwise.
154027 +*//***************************************************************************/
154028 +#if defined(CONFIG_COMPAT)
154029 +#define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t)
154030 +#endif
154031 +#define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t)
154032 +
154033 +/**************************************************************************//**
154034 + @Function FM_PORT_DeletePCD
154035 +
154036 + @Description Calling this routine releases the port's PCD configuration.
154037 + The port returns to its default configuration which is PCD
154038 + disabled (BMI to BMI) and all PCD configuration is removed.
154039 +
154040 + May be used for Rx and offline parsing ports which are
154041 + in PCD mode only
154042 +
154043 + @Return 0 on success; error code otherwise.
154044 +*//***************************************************************************/
154045 +#define FM_PORT_IOC_DELETE_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(21))
154046 +
154047 +/**************************************************************************//**
154048 + @Function FM_PORT_AttachPCD
154049 +
154050 + @Description This routine may be called after FM_PORT_DetachPCD was called,
154051 + to return to the originally configured PCD support flow.
154052 + The couple of routines are used to allow PCD configuration changes
154053 + that demand that PCD will not be used while changes take place.
154054 +
154055 + May be used for Rx and offline parsing ports which are
154056 + in PCD mode only
154057 +
154058 + @Return 0 on success; error code otherwise.
154059 +*//***************************************************************************/
154060 +#define FM_PORT_IOC_ATTACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(23))
154061 +
154062 +/**************************************************************************//**
154063 + @Function FM_PORT_DetachPCD
154064 +
154065 + @Description Calling this routine detaches the port from its PCD functionality.
154066 + The port returns to its default flow which is BMI to BMI.
154067 +
154068 + May be used for Rx and offline parsing ports which are
154069 + in PCD mode only
154070 +
154071 + @Return 0 on success; error code otherwise.
154072 +*//***************************************************************************/
154073 +#define FM_PORT_IOC_DETACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(22))
154074 +
154075 +/**************************************************************************//**
154076 + @Function FM_PORT_PcdPlcrAllocProfiles
154077 +
154078 + @Description This routine may be called only for ports that use the Policer in
154079 + order to allocate private policer profiles.
154080 +
154081 + @Param[in] uint16_t The number of required policer profiles
154082 +
154083 + @Return 0 on success; error code otherwise.
154084 +
154085 + @Cautions Allowed before FM_PORT_SetPCD() only.
154086 +*//***************************************************************************/
154087 +#define FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(24), uint16_t)
154088 +
154089 +/**************************************************************************//**
154090 + @Function FM_PORT_PcdPlcrFreeProfiles
154091 +
154092 + @Description This routine should be called for freeing private policer profiles.
154093 +
154094 + @Return 0 on success; error code otherwise.
154095 +
154096 + @Cautions Allowed before FM_PORT_SetPCD() only.
154097 +*//***************************************************************************/
154098 +#define FM_PORT_IOC_PCD_PLCR_FREE_PROFILES _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(25))
154099 +
154100 +/**************************************************************************//**
154101 + @Function FM_PORT_PcdKgModifyInitialScheme
154102 +
154103 + @Description This routine may be called only for ports that use the keygen in
154104 + order to change the initial scheme frame should be routed to.
154105 + The change may be of a scheme id (in case of direct mode),
154106 + from direct to indirect, or from indirect to direct - specifying the scheme id.
154107 +
154108 + @Param[in] ioc_fm_pcd_kg_scheme_select_t A structure of parameters for defining whether
154109 + a scheme is direct/indirect, and if direct - scheme id.
154110 +
154111 + @Return 0 on success; error code otherwise.
154112 +*//***************************************************************************/
154113 +#if defined(CONFIG_COMPAT)
154114 +#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)
154115 +#endif
154116 +#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)
154117 +
154118 +/**************************************************************************//**
154119 + @Function FM_PORT_PcdPlcrModifyInitialProfile
154120 +
154121 + @Description This routine may be called for ports with flows
154122 + e_IOC_FM_PCD_SUPPORT_PLCR_ONLY or e_IOC_FM_PCD_SUPPORT_PRS_AND_PLCR only,
154123 + to change the initial Policer profile frame should be routed to.
154124 + The change may be of a profile and/or absolute/direct mode selection.
154125 +
154126 + @Param[in] ioc_fm_obj_t Policer profile Id as returned from FM_PCD_PlcrSetProfile.
154127 +
154128 + @Return 0 on success; error code otherwise.
154129 +*//***************************************************************************/
154130 +#if defined(CONFIG_COMPAT)
154131 +#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)
154132 +#endif
154133 +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t)
154134 +
154135 +/**************************************************************************//**
154136 + @Function FM_PORT_PcdCcModifyTree
154137 +
154138 + @Description This routine may be called to change this port connection to
154139 + a pre-initializes coarse classification Tree.
154140 +
154141 + @Param[in] ioc_fm_obj_t Id of new coarse classification tree selected for this port.
154142 +
154143 + @Return 0 on success; error code otherwise.
154144 +
154145 + @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD()
154146 +*//***************************************************************************/
154147 +#if defined(CONFIG_COMPAT)
154148 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t)
154149 +#endif
154150 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t)
154151 +
154152 +/**************************************************************************//**
154153 + @Function FM_PORT_PcdKgBindSchemes
154154 +
154155 + @Description These routines may be called for modifying the binding of ports
154156 + to schemes. The scheme itself is not added,
154157 + just this specific port starts using it.
154158 +
154159 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
154160 +
154161 + @Return 0 on success; error code otherwise.
154162 +
154163 + @Cautions Allowed only following FM_PORT_SetPCD().
154164 +*//***************************************************************************/
154165 +#if defined(CONFIG_COMPAT)
154166 +#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)
154167 +#endif
154168 +#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)
154169 +
154170 +/**************************************************************************//**
154171 + @Function FM_PORT_PcdKgUnbindSchemes
154172 +
154173 + @Description These routines may be called for modifying the binding of ports
154174 + to schemes. The scheme itself is not removed or invalidated,
154175 + just this specific port stops using it.
154176 +
154177 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
154178 +
154179 + @Return 0 on success; error code otherwise.
154180 +
154181 + @Cautions Allowed only following FM_PORT_SetPCD().
154182 +*//***************************************************************************/
154183 +#if defined(CONFIG_COMPAT)
154184 +#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)
154185 +#endif
154186 +#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)
154187 +
154188 +typedef struct ioc_fm_port_mac_addr_params_t {
154189 + uint8_t addr[ENET_NUM_OCTETS_PER_ADDRESS];
154190 +} ioc_fm_port_mac_addr_params_t;
154191 +
154192 +/**************************************************************************//**
154193 + @Function FM_MAC_AddHashMacAddr
154194 +
154195 + @Description Add an Address to the hash table. This is for filter purpose only.
154196 +
154197 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
154198 +
154199 + @Return E_OK on success; Error code otherwise.
154200 +
154201 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
154202 + @Cautions Some address need to be filtered out in upper FM blocks.
154203 +*//***************************************************************************/
154204 +#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)
154205 +
154206 +/**************************************************************************//**
154207 + @Function FM_MAC_RemoveHashMacAddr
154208 +
154209 + @Description Delete an Address to the hash table. This is for filter purpose only.
154210 +
154211 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
154212 +
154213 + @Return E_OK on success; Error code otherwise.
154214 +
154215 + @Cautions Allowed only following FM_MAC_Init().
154216 +*//***************************************************************************/
154217 +#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)
154218 +
154219 +typedef struct ioc_fm_port_tx_pause_frames_params_t {
154220 + uint8_t priority;
154221 + uint16_t pause_time;
154222 + uint16_t thresh_time;
154223 +} ioc_fm_port_tx_pause_frames_params_t;
154224 +
154225 +/**************************************************************************//**
154226 + @Function FM_MAC_SetTxPauseFrames
154227 +
154228 + @Description Enable/Disable transmission of Pause-Frames.
154229 + The routine changes the default configuration:
154230 + pause-time - [0xf000]
154231 + threshold-time - [0]
154232 +
154233 + @Param[in] ioc_fm_port_tx_pause_frames_params_t A structure holding the required parameters.
154234 +
154235 + @Return E_OK on success; Error code otherwise.
154236 +
154237 + @Cautions Allowed only following FM_MAC_Init().
154238 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
154239 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
154240 + in the 'priority' field.
154241 +*//***************************************************************************/
154242 +#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)
154243 +
154244 +typedef struct ioc_fm_port_mac_statistics_t {
154245 + /* RMON */
154246 + uint64_t e_stat_pkts_64; /**< r-10G tr-DT 64 byte frame counter */
154247 + uint64_t e_stat_pkts_65_to_127; /**< r-10G 65 to 127 byte frame counter */
154248 + uint64_t e_stat_pkts_128_to_255; /**< r-10G 128 to 255 byte frame counter */
154249 + uint64_t e_stat_pkts_256_to_511; /**< r-10G 256 to 511 byte frame counter */
154250 + uint64_t e_stat_pkts_512_to_1023; /**< r-10G 512 to 1023 byte frame counter */
154251 + uint64_t e_stat_pkts_1024_to_1518; /**< r-10G 1024 to 1518 byte frame counter */
154252 + uint64_t e_stat_pkts_1519_to_1522; /**< r-10G 1519 to 1522 byte good frame count */
154253 + /* */
154254 + uint64_t e_stat_fragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
154255 + uint64_t e_stat_jabbers; /**< Total number of packets longer than valid maximum length octets */
154256 + uint64_t e_stat_drop_events; /**< number of dropped packets due to internal errors of the MAC Client (during recieve). */
154257 + uint64_t e_stat_CRC_align_errors; /**< Incremented when frames of correct length but with CRC error are received.*/
154258 + uint64_t e_stat_undersize_pkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
154259 + This count does not include range length errors */
154260 + uint64_t e_stat_oversize_pkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
154261 + a valid FCS and otherwise well formed */
154262 + /* Pause */
154263 + uint64_t te_stat_pause; /**< Pause MAC Control received */
154264 + uint64_t re_stat_pause; /**< Pause MAC Control sent */
154265 + /* MIB II */
154266 + uint64_t if_in_octets; /**< Total number of byte received. */
154267 + uint64_t if_in_pkts; /**< Total number of packets received.*/
154268 + uint64_t if_in_ucast_pkts; /**< Total number of unicast frame received;
154269 + NOTE: this counter is not supported on dTSEC MAC */
154270 + uint64_t if_in_mcast_pkts; /**< Total number of multicast frame received*/
154271 + uint64_t if_in_bcast_pkts; /**< Total number of broadcast frame received */
154272 + uint64_t if_in_discards; /**< Frames received, but discarded due to problems within the MAC RX. */
154273 + uint64_t if_in_errors; /**< Number of frames received with error:
154274 + - FIFO Overflow Error
154275 + - CRC Error
154276 + - Frame Too Long Error
154277 + - Alignment Error
154278 + - The dedicated Error Code (0xfe, not a code error) was received */
154279 + uint64_t if_out_octets; /**< Total number of byte sent. */
154280 + uint64_t if_out_pkts; /**< Total number of packets sent .*/
154281 + uint64_t if_out_ucast_pkts; /**< Total number of unicast frame sent;
154282 + NOTE: this counter is not supported on dTSEC MAC */
154283 + uint64_t if_out_mcast_pkts; /**< Total number of multicast frame sent */
154284 + uint64_t if_out_bcast_pkts; /**< Total number of multicast frame sent */
154285 + uint64_t if_out_discards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
154286 + uint64_t if_out_errors; /**< Number of frames transmitted with error:
154287 + - FIFO Overflow Error
154288 + - FIFO Underflow Error
154289 + - Other */
154290 +} ioc_fm_port_mac_statistics_t;
154291 +
154292 +/**************************************************************************//**
154293 + @Function FM_MAC_GetStatistics
154294 +
154295 + @Description get all MAC statistics counters
154296 +
154297 + @Param[out] ioc_fm_port_mac_statistics_t A structure holding the statistics
154298 +
154299 + @Return E_OK on success; Error code otherwise.
154300 +
154301 + @Cautions Allowed only following FM_Init().
154302 +*//***************************************************************************/
154303 +#define FM_PORT_IOC_GET_MAC_STATISTICS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(41), ioc_fm_port_mac_statistics_t)
154304 +
154305 +/**************************************************************************//**
154306 + @Function FM_PORT_ConfigBufferPrefixContent
154307 +
154308 + @Description Defines the structure, size and content of the application buffer.
154309 + The prefix will
154310 + In Tx ports, if 'passPrsResult', the application
154311 + should set a value to their offsets in the prefix of
154312 + the FM will save the first 'privDataSize', than,
154313 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
154314 + and timeStamp, and the packet itself (in this order), to the
154315 + application buffer, and to offset.
154316 + Calling this routine changes the buffer margins definitions
154317 + in the internal driver data base from its default
154318 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
154319 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
154320 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
154321 +
154322 + May be used for all ports
154323 +
154324 + @Param[in] ioc_fm_buffer_prefix_content_t A structure holding the required parameters.
154325 +
154326 + @Return E_OK on success; Error code otherwise.
154327 +
154328 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
154329 +*//***************************************************************************/
154330 +#define FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(39), ioc_fm_buffer_prefix_content_t)
154331 +
154332 +#if (DPAA_VERSION >= 11)
154333 +typedef struct ioc_fm_port_vsp_alloc_params_t {
154334 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
154335 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
154336 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
154337 + if relevant function called for Rx port */
154338 + void *p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
154339 +}ioc_fm_port_vsp_alloc_params_t;
154340 +
154341 +/**************************************************************************//**
154342 + @Function FM_PORT_VSPAlloc
154343 +
154344 + @Description This routine allocated VSPs per port and forces the port to work
154345 + in VSP mode. Note that the port is initialized by default with the
154346 + physical-storage-profile only.
154347 +
154348 + @Param[in] h_FmPort A handle to a FM Port module.
154349 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
154350 +
154351 + @Return E_OK on success; Error code otherwise.
154352 +
154353 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
154354 + and also before FM_PORT_Enable() (i.e. the port should be disabled).
154355 +*//***************************************************************************/
154356 +#if defined(CONFIG_COMPAT)
154357 +#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)
154358 +#endif
154359 +#define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t)
154360 +#endif /* (DPAA_VERSION >= 11) */
154361 +
154362 +/**************************************************************************//**
154363 + @Function FM_PORT_GetBmiCounters
154364 +
154365 + @Description Read port's BMI stat counters and place them into
154366 + a designated structure of counters.
154367 +
154368 + @Param[in] h_FmPort A handle to a FM Port module.
154369 + @Param[out] p_BmiStats counters structure
154370 +
154371 + @Return E_OK on success; Error code otherwise.
154372 +
154373 + @Cautions Allowed only following FM_PORT_Init().
154374 +*//***************************************************************************/
154375 +
154376 +#define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t)
154377 +
154378 +typedef struct ioc_fm_port_mac_frame_size_counters_t {
154379 +
154380 + e_CommMode type;
154381 + uint64_t count_pkts_64; /**< 64 byte frame counter */
154382 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
154383 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
154384 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
154385 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
154386 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
154387 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
154388 +} ioc_fm_port_mac_frame_size_counters_t;
154389 +
154390 +/**************************************************************************//**
154391 + @Function FM_MAC_GetFrameSizeCounters
154392 +
154393 + @Description get MAC statistics counters for different frame size
154394 +
154395 + @Param[out] ioc_fm_port_mac_frame_size_counters_t A structure holding the counters
154396 +
154397 + @Return E_OK on success; Error code otherwise.
154398 +
154399 + @Cautions Allowed only following FM_Init().
154400 +*//***************************************************************************/
154401 +#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)
154402 +
154403 +
154404 +/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */
154405 +/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */
154406 +
154407 +/** @} */ /* end of lnx_ioctl_FM_PORT_grp group */
154408 +/** @} */ /* end of lnx_ioctl_FM_grp group */
154409 +#endif /* __FM_PORT_IOCTLS_H */
154410 diff --git a/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
154411 new file mode 100644
154412 index 00000000..207ed1eb
154413 --- /dev/null
154414 +++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
154415 @@ -0,0 +1,208 @@
154416 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154417 + * All rights reserved.
154418 + *
154419 + * Redistribution and use in source and binary forms, with or without
154420 + * modification, are permitted provided that the following conditions are met:
154421 + * * Redistributions of source code must retain the above copyright
154422 + * notice, this list of conditions and the following disclaimer.
154423 + * * Redistributions in binary form must reproduce the above copyright
154424 + * notice, this list of conditions and the following disclaimer in the
154425 + * documentation and/or other materials provided with the distribution.
154426 + * * Neither the name of Freescale Semiconductor nor the
154427 + * names of its contributors may be used to endorse or promote products
154428 + * derived from this software without specific prior written permission.
154429 + *
154430 + *
154431 + * ALTERNATIVELY, this software may be distributed under the terms of the
154432 + * GNU General Public License ("GPL") as published by the Free Software
154433 + * Foundation, either version 2 of that License or (at your option) any
154434 + * later version.
154435 + *
154436 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154437 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154438 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154439 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154440 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154441 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154442 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154443 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154444 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154445 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154446 + */
154447 +
154448 +/**************************************************************************//**
154449 + @File fm_test_ioctls.h
154450 +
154451 + @Description FM Char device ioctls
154452 +*//***************************************************************************/
154453 +#ifndef __FM_TEST_IOCTLS_H
154454 +#define __FM_TEST_IOCTLS_H
154455 +
154456 +#include "ioctls.h"
154457 +
154458 +
154459 +/**************************************************************************//**
154460 + @Group lnx_ioctl_FMT_grp Frame Manager Test Linux IOCTL API
154461 +
154462 + @Description FM-Test Linux ioctls definitions and enums
154463 +
154464 + @{
154465 +*//***************************************************************************/
154466 +
154467 +#define IOC_FMT_MAX_NUM_OF_PORTS 26
154468 +
154469 +/**************************************************************************//**
154470 + @Collection TEST Parameters
154471 +*//***************************************************************************/
154472 +/**************************************************************************//**
154473 + @Description: Name of the FM-Test chardev
154474 +*//***************************************************************************/
154475 +#define DEV_FM_TEST_NAME "fm-test-port"
154476 +
154477 +#define DEV_FM_TEST_PORTS_MINOR_BASE 0
154478 +#define DEV_FM_TEST_MAX_MINORS (DEV_FM_TEST_PORTS_MINOR_BASE + IOC_FMT_MAX_NUM_OF_PORTS)
154479 +
154480 +#define FMT_PORT_IOC_NUM(n) n
154481 +/* @} */
154482 +
154483 +/**************************************************************************//**
154484 + @Group lnx_ioctl_FMT_lib_grp FM-Test library
154485 +
154486 + @Description TODO
154487 +
154488 + @{
154489 +*//***************************************************************************/
154490 +
154491 +/**************************************************************************//**
154492 + @Description TODO
154493 +*//***************************************************************************/
154494 +typedef uint8_t ioc_fmt_xxx_t;
154495 +
154496 +#define FM_PRS_MAX 32
154497 +#define FM_TIME_STAMP_MAX 8
154498 +
154499 +/**************************************************************************//**
154500 + @Description FM Port buffer content description
154501 +*//***************************************************************************/
154502 +typedef struct ioc_fmt_buff_context_t {
154503 + void *p_user_priv;
154504 + uint8_t fm_prs_res[FM_PRS_MAX];
154505 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
154506 +} ioc_fmt_buff_context_t;
154507 +
154508 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
154509 +typedef struct ioc_fmt_compat_buff_context_t {
154510 + compat_uptr_t p_user_priv;
154511 + uint8_t fm_prs_res[FM_PRS_MAX];
154512 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
154513 +} ioc_fmt_compat_buff_context_t;
154514 +#endif
154515 +
154516 +/**************************************************************************//**
154517 + @Description Buffer descriptor
154518 +*//***************************************************************************/
154519 +typedef struct ioc_fmt_buff_desc_t {
154520 + uint32_t qid;
154521 + void *p_data;
154522 + uint32_t size;
154523 + uint32_t status;
154524 + ioc_fmt_buff_context_t buff_context;
154525 +} ioc_fmt_buff_desc_t;
154526 +
154527 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
154528 +typedef struct ioc_fmt_compat_buff_desc_t {
154529 + uint32_t qid;
154530 + compat_uptr_t p_data;
154531 + uint32_t size;
154532 + uint32_t status;
154533 + ioc_fmt_compat_buff_context_t buff_context;
154534 +} ioc_fmt_compat_buff_desc_t;
154535 +#endif
154536 +
154537 +/**************************************************************************//**
154538 + @Group lnx_ioctl_FMT_runtime_control_grp FM-Test Runtime Control Unit
154539 +
154540 + @Description TODO
154541 + @{
154542 +*//***************************************************************************/
154543 +
154544 +/** @} */ /* end of lnx_ioctl_FMT_runtime_control_grp group */
154545 +
154546 +
154547 +/**************************************************************************//**
154548 + @Group lnx_ioctl_FMTP_lib_grp FM-Port-Test library
154549 +
154550 + @Description TODO
154551 +
154552 + @{
154553 +*//***************************************************************************/
154554 +
154555 +/**************************************************************************//**
154556 + @Description FM-Test FM port type
154557 +*//***************************************************************************/
154558 +typedef enum ioc_fmt_port_type {
154559 + e_IOC_FMT_PORT_T_RXTX, /**< Standard port */
154560 + e_IOC_FMT_PORT_T_OP, /**< Offline-parsing port */
154561 +} ioc_fmt_port_type;
154562 +
154563 +/**************************************************************************//**
154564 + @Description TODO
154565 +*//***************************************************************************/
154566 +typedef struct ioc_fmt_port_param_t {
154567 + uint8_t fm_id;
154568 + ioc_fmt_port_type fm_port_type;
154569 + uint8_t fm_port_id;
154570 + uint32_t num_tx_queues;
154571 +} ioc_fmt_port_param_t;
154572 +
154573 +
154574 +/**************************************************************************//**
154575 + @Function FMT_PORT_IOC_INIT
154576 +
154577 + @Description TODO
154578 +
154579 + @Param[in] ioc_fmt_port_param_t TODO
154580 +
154581 + @Cautions Allowed only after the FM equivalent port is already initialized.
154582 +*//***************************************************************************/
154583 +#define FMT_PORT_IOC_INIT _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(0), ioc_fmt_port_param_t)
154584 +
154585 +/**************************************************************************//**
154586 + @Function FMT_PORT_IOC_SET_DIAG_MODE
154587 +
154588 + @Description TODO
154589 +
154590 + @Param[in] ioc_diag_mode TODO
154591 +
154592 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
154593 +*//***************************************************************************/
154594 +#define FMT_PORT_IOC_SET_DIAG_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(1), ioc_diag_mode)
154595 +
154596 +/**************************************************************************//**
154597 + @Function FMT_PORT_IOC_SET_IP_HEADER_MANIP
154598 +
154599 + @Description Set IP header manipulations for this port.
154600 +
154601 + @Param[in] int 1 to enable; 0 to disable
154602 +
154603 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
154604 +*//***************************************************************************/
154605 +#define FMT_PORT_IOC_SET_IP_HEADER_MANIP _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(2), int)
154606 +
154607 +/**************************************************************************//**
154608 + @Function FMT_PORT_IOC_SET_DPAECHO_MODE
154609 +
154610 + @Description Set DPA in echo mode - all frame are sent back.
154611 +
154612 + @Param[in] int 1 to enable; 0 to disable
154613 +
154614 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
154615 +*//***************************************************************************/
154616 +#define FMT_PORT_IOC_SET_DPAECHO_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(3), int)
154617 +
154618 +/** @} */ /* end of lnx_ioctl_FMTP_lib_grp group */
154619 +/** @} */ /* end of lnx_ioctl_FMT_lib_grp group */
154620 +/** @} */ /* end of lnx_ioctl_FMT_grp */
154621 +
154622 +
154623 +#endif /* __FM_TEST_IOCTLS_H */
154624 diff --git a/include/uapi/linux/fmd/integrations/Kbuild b/include/uapi/linux/fmd/integrations/Kbuild
154625 new file mode 100644
154626 index 00000000..e548d676
154627 --- /dev/null
154628 +++ b/include/uapi/linux/fmd/integrations/Kbuild
154629 @@ -0,0 +1 @@
154630 +header-y += integration_ioctls.h
154631 diff --git a/include/uapi/linux/fmd/integrations/integration_ioctls.h b/include/uapi/linux/fmd/integrations/integration_ioctls.h
154632 new file mode 100644
154633 index 00000000..61d696e2
154634 --- /dev/null
154635 +++ b/include/uapi/linux/fmd/integrations/integration_ioctls.h
154636 @@ -0,0 +1,56 @@
154637 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154638 + * All rights reserved.
154639 + *
154640 + * Redistribution and use in source and binary forms, with or without
154641 + * modification, are permitted provided that the following conditions are met:
154642 + * * Redistributions of source code must retain the above copyright
154643 + * notice, this list of conditions and the following disclaimer.
154644 + * * Redistributions in binary form must reproduce the above copyright
154645 + * notice, this list of conditions and the following disclaimer in the
154646 + * documentation and/or other materials provided with the distribution.
154647 + * * Neither the name of Freescale Semiconductor nor the
154648 + * names of its contributors may be used to endorse or promote products
154649 + * derived from this software without specific prior written permission.
154650 + *
154651 + *
154652 + * ALTERNATIVELY, this software may be distributed under the terms of the
154653 + * GNU General Public License ("GPL") as published by the Free Software
154654 + * Foundation, either version 2 of that License or (at your option) any
154655 + * later version.
154656 + *
154657 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154658 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154659 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154660 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154661 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154662 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154663 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154664 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154665 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154666 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154667 + */
154668 +
154669 +/**************************************************************************//**
154670 + @File integration_ioctls.h
154671 +
154672 + @Description External header file for Integration unit routines.
154673 +*//***************************************************************************/
154674 +
154675 +#ifndef __INTG_IOCTLS_H
154676 +#define __INTG_IOCTLS_H
154677 +
154678 +
154679 +#define FM_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+1)
154680 +#define FMT_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+3)
154681 +
154682 +/*#define FM_IOCTL_DBG*/
154683 +
154684 +#if defined(FM_IOCTL_DBG)
154685 + #define _fm_ioctl_dbg(format, arg...) \
154686 + printk("fm ioctl [%s:%u](cpu:%u) - " format, \
154687 + __func__, __LINE__, smp_processor_id(), ##arg)
154688 +#else
154689 +# define _fm_ioctl_dbg(arg...)
154690 +#endif
154691 +
154692 +#endif /* __INTG_IOCTLS_H */
154693 diff --git a/include/uapi/linux/fmd/ioctls.h b/include/uapi/linux/fmd/ioctls.h
154694 new file mode 100644
154695 index 00000000..4f36cb05
154696 --- /dev/null
154697 +++ b/include/uapi/linux/fmd/ioctls.h
154698 @@ -0,0 +1,96 @@
154699 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154700 + * All rights reserved.
154701 + *
154702 + * Redistribution and use in source and binary forms, with or without
154703 + * modification, are permitted provided that the following conditions are met:
154704 + * * Redistributions of source code must retain the above copyright
154705 + * notice, this list of conditions and the following disclaimer.
154706 + * * Redistributions in binary form must reproduce the above copyright
154707 + * notice, this list of conditions and the following disclaimer in the
154708 + * documentation and/or other materials provided with the distribution.
154709 + * * Neither the name of Freescale Semiconductor nor the
154710 + * names of its contributors may be used to endorse or promote products
154711 + * derived from this software without specific prior written permission.
154712 + *
154713 + *
154714 + * ALTERNATIVELY, this software may be distributed under the terms of the
154715 + * GNU General Public License ("GPL") as published by the Free Software
154716 + * Foundation, either version 2 of that License or (at your option) any
154717 + * later version.
154718 + *
154719 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154720 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154721 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154722 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154723 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154724 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154725 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154726 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154727 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154728 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154729 + */
154730 +
154731 +/**************************************************************************//**
154732 + @File ioctls.h
154733 +
154734 + @Description Structures and definitions for Command Relay Ioctls
154735 +*//***************************************************************************/
154736 +
154737 +#ifndef __IOCTLS_H__
154738 +#define __IOCTLS_H__
154739 +
154740 +#include <asm/ioctl.h>
154741 +
154742 +#include "integration_ioctls.h"
154743 +
154744 +
154745 +/**************************************************************************//**
154746 + @Group lnx_ioctl_ncsw_grp NetCommSw Linux User-Space (IOCTL) API
154747 + @{
154748 +*//***************************************************************************/
154749 +
154750 +#define NCSW_IOC_TYPE_BASE 0xe0 /**< defines the IOCTL type for all
154751 + the NCSW Linux module commands */
154752 +
154753 +
154754 +/**************************************************************************//**
154755 + @Description IOCTL Memory allocation types.
154756 +*//***************************************************************************/
154757 +typedef enum ioc_mem_type {
154758 + e_IOC_MEM_INVALID = 0x00000000, /**< Invalid memory type (error) */
154759 + e_IOC_MEM_CACHABLE_SYS = 0x00000001, /**< Primary DDR, cacheable segment */
154760 + e_IOC_MEM_NOCACHE_SYS = 0x00000004, /**< Primary DDR, non-cacheable segment */
154761 + e_IOC_MEM_SECONDARY = 0x00000002, /**< Either secondary DDR or SDRAM */
154762 + e_IOC_MEM_PRAM = 0x00000008 /**< Multi-user RAM identifier */
154763 +} ioc_mem_type;
154764 +
154765 +/**************************************************************************//**
154766 + @Description Enumeration (bit flags) of communication modes (Transmit,
154767 + receive or both).
154768 +*//***************************************************************************/
154769 +typedef enum ioc_comm_mode {
154770 + e_IOC_COMM_MODE_NONE = 0 /**< No transmit/receive communication */
154771 + , e_IOC_COMM_MODE_RX = 1 /**< Only receive communication */
154772 + , e_IOC_COMM_MODE_TX = 2 /**< Only transmit communication */
154773 + , e_IOC_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
154774 +} ioc_comm_mode;
154775 +
154776 +/**************************************************************************//**
154777 + @Description General Diagnostic Mode
154778 +*//***************************************************************************/
154779 +typedef enum ioc_diag_mode
154780 +{
154781 + e_IOC_DIAG_MODE_NONE = 0,
154782 + e_IOC_DIAG_MODE_CTRL_LOOPBACK, /**< loopback in the controller; E.g. MAC, TDM, etc. */
154783 + e_IOC_DIAG_MODE_CHIP_LOOPBACK, /**< loopback in the chip but not in controller;
154784 + E.g. IO-pins, SerDes, etc. */
154785 + e_IOC_DIAG_MODE_PHY_LOOPBACK, /**< loopback in the external PHY */
154786 + e_IOC_DIAG_MODE_LINE_LOOPBACK, /**< loopback in the external line */
154787 + e_IOC_DIAG_MODE_CTRL_ECHO, /**< */
154788 + e_IOC_DIAG_MODE_PHY_ECHO /**< */
154789 +} ioc_diag_mode;
154790 +
154791 +/** @} */ /* end of lnx_ioctl_ncsw_grp */
154792 +
154793 +
154794 +#endif /* __IOCTLS_H__ */
154795 diff --git a/include/uapi/linux/fmd/net_ioctls.h b/include/uapi/linux/fmd/net_ioctls.h
154796 new file mode 100644
154797 index 00000000..c99d64cf
154798 --- /dev/null
154799 +++ b/include/uapi/linux/fmd/net_ioctls.h
154800 @@ -0,0 +1,430 @@
154801 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154802 + * All rights reserved.
154803 + *
154804 + * Redistribution and use in source and binary forms, with or without
154805 + * modification, are permitted provided that the following conditions are met:
154806 + * * Redistributions of source code must retain the above copyright
154807 + * notice, this list of conditions and the following disclaimer.
154808 + * * Redistributions in binary form must reproduce the above copyright
154809 + * notice, this list of conditions and the following disclaimer in the
154810 + * documentation and/or other materials provided with the distribution.
154811 + * * Neither the name of Freescale Semiconductor nor the
154812 + * names of its contributors may be used to endorse or promote products
154813 + * derived from this software without specific prior written permission.
154814 + *
154815 + *
154816 + * ALTERNATIVELY, this software may be distributed under the terms of the
154817 + * GNU General Public License ("GPL") as published by the Free Software
154818 + * Foundation, either version 2 of that License or (at your option) any
154819 + * later version.
154820 + *
154821 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154822 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154823 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154824 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154825 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154826 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154827 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154828 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154829 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154830 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154831 + */
154832 +
154833 +
154834 +/**************************************************************************//**
154835 + @File net_ioctls.h
154836 +
154837 + @Description This file contains common and general netcomm headers definitions.
154838 +*//***************************************************************************/
154839 +#ifndef __NET_IOCTLS_H
154840 +#define __NET_IOCTLS_H
154841 +
154842 +#include "ioctls.h"
154843 +
154844 +
154845 +typedef uint8_t ioc_header_field_ppp_t;
154846 +
154847 +#define IOC_NET_HEADER_FIELD_PPP_PID (1)
154848 +#define IOC_NET_HEADER_FIELD_PPP_COMPRESSED (IOC_NET_HEADER_FIELD_PPP_PID << 1)
154849 +#define IOC_NET_HEADER_FIELD_PPP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPP_PID << 2) - 1)
154850 +
154851 +
154852 +typedef uint8_t ioc_header_field_pppoe_t;
154853 +
154854 +#define IOC_NET_HEADER_FIELD_PPPoE_VER (1)
154855 +#define IOC_NET_HEADER_FIELD_PPPoE_TYPE (IOC_NET_HEADER_FIELD_PPPoE_VER << 1)
154856 +#define IOC_NET_HEADER_FIELD_PPPoE_CODE (IOC_NET_HEADER_FIELD_PPPoE_VER << 2)
154857 +#define IOC_NET_HEADER_FIELD_PPPoE_SID (IOC_NET_HEADER_FIELD_PPPoE_VER << 3)
154858 +#define IOC_NET_HEADER_FIELD_PPPoE_LEN (IOC_NET_HEADER_FIELD_PPPoE_VER << 4)
154859 +#define IOC_NET_HEADER_FIELD_PPPoE_SESSION (IOC_NET_HEADER_FIELD_PPPoE_VER << 5)
154860 +#define IOC_NET_HEADER_FIELD_PPPoE_PID (IOC_NET_HEADER_FIELD_PPPoE_VER << 6)
154861 +#define IOC_NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
154862 +
154863 +#define IOC_NET_HEADER_FIELD_PPPMUX_PID (1)
154864 +#define IOC_NET_HEADER_FIELD_PPPMUX_CKSUM (IOC_NET_HEADER_FIELD_PPPMUX_PID << 1)
154865 +#define IOC_NET_HEADER_FIELD_PPPMUX_COMPRESSED (IOC_NET_HEADER_FIELD_PPPMUX_PID << 2)
154866 +#define IOC_NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
154867 +
154868 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
154869 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
154870 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
154871 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
154872 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
154873 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
154874 +
154875 +
154876 +typedef uint8_t ioc_header_field_eth_t;
154877 +
154878 +#define IOC_NET_HEADER_FIELD_ETH_DA (1)
154879 +#define IOC_NET_HEADER_FIELD_ETH_SA (IOC_NET_HEADER_FIELD_ETH_DA << 1)
154880 +#define IOC_NET_HEADER_FIELD_ETH_LENGTH (IOC_NET_HEADER_FIELD_ETH_DA << 2)
154881 +#define IOC_NET_HEADER_FIELD_ETH_TYPE (IOC_NET_HEADER_FIELD_ETH_DA << 3)
154882 +#define IOC_NET_HEADER_FIELD_ETH_FINAL_CKSUM (IOC_NET_HEADER_FIELD_ETH_DA << 4)
154883 +#define IOC_NET_HEADER_FIELD_ETH_PADDING (IOC_NET_HEADER_FIELD_ETH_DA << 5)
154884 +#define IOC_NET_HEADER_FIELD_ETH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ETH_DA << 6) - 1)
154885 +
154886 +#define IOC_NET_HEADER_FIELD_ETH_ADDR_SIZE 6
154887 +
154888 +typedef uint16_t ioc_header_field_ip_t;
154889 +
154890 +#define IOC_NET_HEADER_FIELD_IP_VER (1)
154891 +#define IOC_NET_HEADER_FIELD_IP_DSCP (IOC_NET_HEADER_FIELD_IP_VER << 2)
154892 +#define IOC_NET_HEADER_FIELD_IP_ECN (IOC_NET_HEADER_FIELD_IP_VER << 3)
154893 +#define IOC_NET_HEADER_FIELD_IP_PROTO (IOC_NET_HEADER_FIELD_IP_VER << 4)
154894 +
154895 +#define IOC_NET_HEADER_FIELD_IP_PROTO_SIZE 1
154896 +
154897 +typedef uint16_t ioc_header_field_ipv4_t;
154898 +
154899 +#define IOC_NET_HEADER_FIELD_IPv4_VER (1)
154900 +#define IOC_NET_HEADER_FIELD_IPv4_HDR_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 1)
154901 +#define IOC_NET_HEADER_FIELD_IPv4_TOS (IOC_NET_HEADER_FIELD_IPv4_VER << 2)
154902 +#define IOC_NET_HEADER_FIELD_IPv4_TOTAL_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 3)
154903 +#define IOC_NET_HEADER_FIELD_IPv4_ID (IOC_NET_HEADER_FIELD_IPv4_VER << 4)
154904 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_D (IOC_NET_HEADER_FIELD_IPv4_VER << 5)
154905 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_M (IOC_NET_HEADER_FIELD_IPv4_VER << 6)
154906 +#define IOC_NET_HEADER_FIELD_IPv4_OFFSET (IOC_NET_HEADER_FIELD_IPv4_VER << 7)
154907 +#define IOC_NET_HEADER_FIELD_IPv4_TTL (IOC_NET_HEADER_FIELD_IPv4_VER << 8)
154908 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO (IOC_NET_HEADER_FIELD_IPv4_VER << 9)
154909 +#define IOC_NET_HEADER_FIELD_IPv4_CKSUM (IOC_NET_HEADER_FIELD_IPv4_VER << 10)
154910 +#define IOC_NET_HEADER_FIELD_IPv4_SRC_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 11)
154911 +#define IOC_NET_HEADER_FIELD_IPv4_DST_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 12)
154912 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS (IOC_NET_HEADER_FIELD_IPv4_VER << 13)
154913 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS_COUNT (IOC_NET_HEADER_FIELD_IPv4_VER << 14)
154914 +#define IOC_NET_HEADER_FIELD_IPv4_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv4_VER << 15) - 1)
154915 +
154916 +#define IOC_NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
154917 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
154918 +
154919 +
154920 +typedef uint8_t ioc_header_field_ipv6_t;
154921 +
154922 +#define IOC_NET_HEADER_FIELD_IPv6_VER (1)
154923 +#define IOC_NET_HEADER_FIELD_IPv6_TC (IOC_NET_HEADER_FIELD_IPv6_VER << 1)
154924 +#define IOC_NET_HEADER_FIELD_IPv6_SRC_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 2)
154925 +#define IOC_NET_HEADER_FIELD_IPv6_DST_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 3)
154926 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR (IOC_NET_HEADER_FIELD_IPv6_VER << 4)
154927 +#define IOC_NET_HEADER_FIELD_IPv6_FL (IOC_NET_HEADER_FIELD_IPv6_VER << 5)
154928 +#define IOC_NET_HEADER_FIELD_IPv6_HOP_LIMIT (IOC_NET_HEADER_FIELD_IPv6_VER << 6)
154929 +#define IOC_NET_HEADER_FIELD_IPv6_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv6_VER << 7) - 1)
154930 +
154931 +#define IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
154932 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
154933 +
154934 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE (1)
154935 +#define IOC_NET_HEADER_FIELD_ICMP_CODE (IOC_NET_HEADER_FIELD_ICMP_TYPE << 1)
154936 +#define IOC_NET_HEADER_FIELD_ICMP_CKSUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 2)
154937 +#define IOC_NET_HEADER_FIELD_ICMP_ID (IOC_NET_HEADER_FIELD_ICMP_TYPE << 3)
154938 +#define IOC_NET_HEADER_FIELD_ICMP_SQ_NUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 4)
154939 +#define IOC_NET_HEADER_FIELD_ICMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
154940 +
154941 +#define IOC_NET_HEADER_FIELD_ICMP_CODE_SIZE 1
154942 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
154943 +
154944 +#define IOC_NET_HEADER_FIELD_IGMP_VERSION (1)
154945 +#define IOC_NET_HEADER_FIELD_IGMP_TYPE (IOC_NET_HEADER_FIELD_IGMP_VERSION << 1)
154946 +#define IOC_NET_HEADER_FIELD_IGMP_CKSUM (IOC_NET_HEADER_FIELD_IGMP_VERSION << 2)
154947 +#define IOC_NET_HEADER_FIELD_IGMP_DATA (IOC_NET_HEADER_FIELD_IGMP_VERSION << 3)
154948 +#define IOC_NET_HEADER_FIELD_IGMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
154949 +
154950 +
154951 +typedef uint16_t ioc_header_field_tcp_t;
154952 +
154953 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SRC (1)
154954 +#define IOC_NET_HEADER_FIELD_TCP_PORT_DST (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 1)
154955 +#define IOC_NET_HEADER_FIELD_TCP_SEQ (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 2)
154956 +#define IOC_NET_HEADER_FIELD_TCP_ACK (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 3)
154957 +#define IOC_NET_HEADER_FIELD_TCP_OFFSET (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 4)
154958 +#define IOC_NET_HEADER_FIELD_TCP_FLAGS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 5)
154959 +#define IOC_NET_HEADER_FIELD_TCP_WINDOW (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 6)
154960 +#define IOC_NET_HEADER_FIELD_TCP_CKSUM (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 7)
154961 +#define IOC_NET_HEADER_FIELD_TCP_URGPTR (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 8)
154962 +#define IOC_NET_HEADER_FIELD_TCP_OPTS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 9)
154963 +#define IOC_NET_HEADER_FIELD_TCP_OPTS_COUNT (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 10)
154964 +#define IOC_NET_HEADER_FIELD_TCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
154965 +
154966 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SIZE 2
154967 +
154968 +
154969 +typedef uint8_t ioc_header_field_sctp_t;
154970 +
154971 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SRC (1)
154972 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_DST (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
154973 +#define IOC_NET_HEADER_FIELD_SCTP_VER_TAG (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
154974 +#define IOC_NET_HEADER_FIELD_SCTP_CKSUM (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
154975 +#define IOC_NET_HEADER_FIELD_SCTP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
154976 +
154977 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SIZE 2
154978 +
154979 +typedef uint8_t ioc_header_field_dccp_t;
154980 +
154981 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SRC (1)
154982 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_DST (IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
154983 +#define IOC_NET_HEADER_FIELD_DCCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
154984 +
154985 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SIZE 2
154986 +
154987 +
154988 +typedef uint8_t ioc_header_field_udp_t;
154989 +
154990 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SRC (1)
154991 +#define IOC_NET_HEADER_FIELD_UDP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 1)
154992 +#define IOC_NET_HEADER_FIELD_UDP_LEN (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 2)
154993 +#define IOC_NET_HEADER_FIELD_UDP_CKSUM (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 3)
154994 +#define IOC_NET_HEADER_FIELD_UDP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
154995 +
154996 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SIZE 2
154997 +
154998 +typedef uint8_t ioc_header_field_udp_lite_t;
154999 +
155000 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
155001 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_DST (IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
155002 +#define IOC_NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
155003 +
155004 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
155005 +
155006 +typedef uint8_t ioc_header_field_udp_encap_esp_t;
155007 +
155008 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
155009 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
155010 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
155011 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
155012 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
155013 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
155014 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
155015 +
155016 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
155017 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
155018 +
155019 +#define IOC_NET_HEADER_FIELD_IPHC_CID (1)
155020 +#define IOC_NET_HEADER_FIELD_IPHC_CID_TYPE (IOC_NET_HEADER_FIELD_IPHC_CID << 1)
155021 +#define IOC_NET_HEADER_FIELD_IPHC_HCINDEX (IOC_NET_HEADER_FIELD_IPHC_CID << 2)
155022 +#define IOC_NET_HEADER_FIELD_IPHC_GEN (IOC_NET_HEADER_FIELD_IPHC_CID << 3)
155023 +#define IOC_NET_HEADER_FIELD_IPHC_D_BIT (IOC_NET_HEADER_FIELD_IPHC_CID << 4)
155024 +#define IOC_NET_HEADER_FIELD_IPHC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPHC_CID << 5) - 1)
155025 +
155026 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
155027 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
155028 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
155029 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
155030 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
155031 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
155032 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
155033 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
155034 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
155035 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
155036 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
155037 +
155038 +#define IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
155039 +#define IOC_NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
155040 +#define IOC_NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
155041 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
155042 +#define IOC_NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
155043 +#define IOC_NET_HEADER_FIELD_L2TPv2_VERSION (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
155044 +#define IOC_NET_HEADER_FIELD_L2TPv2_LEN (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
155045 +#define IOC_NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
155046 +#define IOC_NET_HEADER_FIELD_L2TPv2_SESSION_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
155047 +#define IOC_NET_HEADER_FIELD_L2TPv2_NS (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
155048 +#define IOC_NET_HEADER_FIELD_L2TPv2_NR (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
155049 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
155050 +#define IOC_NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
155051 +#define IOC_NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
155052 +
155053 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
155054 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
155055 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
155056 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
155057 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
155058 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
155059 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SENT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
155060 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_RECV (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
155061 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
155062 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
155063 +
155064 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
155065 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
155066 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ID (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
155067 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
155068 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
155069 +
155070 +
155071 +typedef uint8_t ioc_header_field_vlan_t;
155072 +
155073 +#define IOC_NET_HEADER_FIELD_VLAN_VPRI (1)
155074 +#define IOC_NET_HEADER_FIELD_VLAN_CFI (IOC_NET_HEADER_FIELD_VLAN_VPRI << 1)
155075 +#define IOC_NET_HEADER_FIELD_VLAN_VID (IOC_NET_HEADER_FIELD_VLAN_VPRI << 2)
155076 +#define IOC_NET_HEADER_FIELD_VLAN_LENGTH (IOC_NET_HEADER_FIELD_VLAN_VPRI << 3)
155077 +#define IOC_NET_HEADER_FIELD_VLAN_TYPE (IOC_NET_HEADER_FIELD_VLAN_VPRI << 4)
155078 +#define IOC_NET_HEADER_FIELD_VLAN_ALL_FIELDS ((IOC_NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
155079 +
155080 +#define IOC_NET_HEADER_FIELD_VLAN_TCI (IOC_NET_HEADER_FIELD_VLAN_VPRI | \
155081 + IOC_NET_HEADER_FIELD_VLAN_CFI | \
155082 + IOC_NET_HEADER_FIELD_VLAN_VID)
155083 +
155084 +
155085 +typedef uint8_t ioc_header_field_llc_t;
155086 +
155087 +#define IOC_NET_HEADER_FIELD_LLC_DSAP (1)
155088 +#define IOC_NET_HEADER_FIELD_LLC_SSAP (IOC_NET_HEADER_FIELD_LLC_DSAP << 1)
155089 +#define IOC_NET_HEADER_FIELD_LLC_CTRL (IOC_NET_HEADER_FIELD_LLC_DSAP << 2)
155090 +#define IOC_NET_HEADER_FIELD_LLC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
155091 +
155092 +#define IOC_NET_HEADER_FIELD_NLPID_NLPID (1)
155093 +#define IOC_NET_HEADER_FIELD_NLPID_ALL_FIELDS ((IOC_NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
155094 +
155095 +
155096 +typedef uint8_t ioc_header_field_snap_t;
155097 +
155098 +#define IOC_NET_HEADER_FIELD_SNAP_OUI (1)
155099 +#define IOC_NET_HEADER_FIELD_SNAP_PID (IOC_NET_HEADER_FIELD_SNAP_OUI << 1)
155100 +#define IOC_NET_HEADER_FIELD_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
155101 +
155102 +
155103 +typedef uint8_t ioc_header_field_llc_snap_t;
155104 +
155105 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
155106 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
155107 +
155108 +#define IOC_NET_HEADER_FIELD_ARP_HTYPE (1)
155109 +#define IOC_NET_HEADER_FIELD_ARP_PTYPE (IOC_NET_HEADER_FIELD_ARP_HTYPE << 1)
155110 +#define IOC_NET_HEADER_FIELD_ARP_HLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 2)
155111 +#define IOC_NET_HEADER_FIELD_ARP_PLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 3)
155112 +#define IOC_NET_HEADER_FIELD_ARP_OPER (IOC_NET_HEADER_FIELD_ARP_HTYPE << 4)
155113 +#define IOC_NET_HEADER_FIELD_ARP_SHA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 5)
155114 +#define IOC_NET_HEADER_FIELD_ARP_SPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 6)
155115 +#define IOC_NET_HEADER_FIELD_ARP_THA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 7)
155116 +#define IOC_NET_HEADER_FIELD_ARP_TPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 8)
155117 +#define IOC_NET_HEADER_FIELD_ARP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
155118 +
155119 +#define IOC_NET_HEADER_FIELD_RFC2684_LLC (1)
155120 +#define IOC_NET_HEADER_FIELD_RFC2684_NLPID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 1)
155121 +#define IOC_NET_HEADER_FIELD_RFC2684_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 2)
155122 +#define IOC_NET_HEADER_FIELD_RFC2684_PID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 3)
155123 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 4)
155124 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_IDX (IOC_NET_HEADER_FIELD_RFC2684_LLC << 5)
155125 +#define IOC_NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((IOC_NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
155126 +
155127 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
155128 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_PCDID (IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
155129 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
155130 +
155131 +#define IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
155132 +#define IOC_NET_HEADER_FIELD_PAYLOAD_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
155133 +#define IOC_NET_HEADER_FIELD_MAX_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
155134 +#define IOC_NET_HEADER_FIELD_MIN_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
155135 +#define IOC_NET_HEADER_FIELD_PAYLOAD_TYPE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
155136 +#define IOC_NET_HEADER_FIELD_FRAME_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
155137 +#define IOC_NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
155138 +
155139 +
155140 +typedef uint8_t ioc_header_field_gre_t;
155141 +
155142 +#define IOC_NET_HEADER_FIELD_GRE_TYPE (1)
155143 +#define IOC_NET_HEADER_FIELD_GRE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
155144 +
155145 +
155146 +typedef uint8_t ioc_header_field_minencap_t;
155147 +
155148 +#define IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
155149 +#define IOC_NET_HEADER_FIELD_MINENCAP_DST_IP (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
155150 +#define IOC_NET_HEADER_FIELD_MINENCAP_TYPE (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
155151 +#define IOC_NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
155152 +
155153 +
155154 +typedef uint8_t ioc_header_field_ipsec_ah_t;
155155 +
155156 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_SPI (1)
155157 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_NH (IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
155158 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
155159 +
155160 +
155161 +typedef uint8_t ioc_header_field_ipsec_esp_t;
155162 +
155163 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
155164 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
155165 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
155166 +
155167 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
155168 +
155169 +
155170 +typedef uint8_t ioc_header_field_mpls_t;
155171 +
155172 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
155173 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
155174 +
155175 +
155176 +typedef uint8_t ioc_header_field_macsec_t;
155177 +
155178 +#define IOC_NET_HEADER_FIELD_MACSEC_SECTAG (1)
155179 +#define IOC_NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
155180 +
155181 +
155182 +typedef enum {
155183 + e_IOC_NET_HEADER_TYPE_NONE = 0,
155184 + e_IOC_NET_HEADER_TYPE_PAYLOAD,
155185 + e_IOC_NET_HEADER_TYPE_ETH,
155186 + e_IOC_NET_HEADER_TYPE_VLAN,
155187 + e_IOC_NET_HEADER_TYPE_IPv4,
155188 + e_IOC_NET_HEADER_TYPE_IPv6,
155189 + e_IOC_NET_HEADER_TYPE_IP,
155190 + e_IOC_NET_HEADER_TYPE_TCP,
155191 + e_IOC_NET_HEADER_TYPE_UDP,
155192 + e_IOC_NET_HEADER_TYPE_UDP_LITE,
155193 + e_IOC_NET_HEADER_TYPE_IPHC,
155194 + e_IOC_NET_HEADER_TYPE_SCTP,
155195 + e_IOC_NET_HEADER_TYPE_SCTP_CHUNK_DATA,
155196 + e_IOC_NET_HEADER_TYPE_PPPoE,
155197 + e_IOC_NET_HEADER_TYPE_PPP,
155198 + e_IOC_NET_HEADER_TYPE_PPPMUX,
155199 + e_IOC_NET_HEADER_TYPE_PPPMUX_SUBFRAME,
155200 + e_IOC_NET_HEADER_TYPE_L2TPv2,
155201 + e_IOC_NET_HEADER_TYPE_L2TPv3_CTRL,
155202 + e_IOC_NET_HEADER_TYPE_L2TPv3_SESS,
155203 + e_IOC_NET_HEADER_TYPE_LLC,
155204 + e_IOC_NET_HEADER_TYPE_LLC_SNAP,
155205 + e_IOC_NET_HEADER_TYPE_NLPID,
155206 + e_IOC_NET_HEADER_TYPE_SNAP,
155207 + e_IOC_NET_HEADER_TYPE_MPLS,
155208 + e_IOC_NET_HEADER_TYPE_IPSEC_AH,
155209 + e_IOC_NET_HEADER_TYPE_IPSEC_ESP,
155210 + e_IOC_NET_HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
155211 + e_IOC_NET_HEADER_TYPE_MACSEC,
155212 + e_IOC_NET_HEADER_TYPE_GRE,
155213 + e_IOC_NET_HEADER_TYPE_MINENCAP,
155214 + e_IOC_NET_HEADER_TYPE_DCCP,
155215 + e_IOC_NET_HEADER_TYPE_ICMP,
155216 + e_IOC_NET_HEADER_TYPE_IGMP,
155217 + e_IOC_NET_HEADER_TYPE_ARP,
155218 + e_IOC_NET_HEADER_TYPE_CAPWAP,
155219 + e_IOC_NET_HEADER_TYPE_CAPWAP_DTLS,
155220 + e_IOC_NET_HEADER_TYPE_RFC2684,
155221 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L2,
155222 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L3,
155223 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L4,
155224 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM1,
155225 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM2,
155226 + e_IOC_NET_MAX_HEADER_TYPE_COUNT
155227 +} ioc_net_header_type;
155228 +
155229 +
155230 +#endif /* __NET_IOCTLS_H */
155231 --
155232 2.14.1
155233